update i686
This commit is contained in:
parent
c8252cce16
commit
9f9bbd8429
261 changed files with 3813 additions and 49662 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,12 +0,0 @@
|
|||
# Copyright (C) AB Strakt
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
pyOpenSSL - A simple wrapper around the OpenSSL library
|
||||
"""
|
||||
|
||||
from OpenSSL import rand, crypto, SSL
|
||||
from OpenSSL.version import __version__
|
||||
|
||||
__all__ = [
|
||||
'rand', 'crypto', 'SSL', 'tsafe', '__version__']
|
|
@ -1,53 +0,0 @@
|
|||
from six import PY3, binary_type, text_type
|
||||
|
||||
from cryptography.hazmat.bindings.openssl.binding import Binding
|
||||
binding = Binding()
|
||||
ffi = binding.ffi
|
||||
lib = binding.lib
|
||||
|
||||
def exception_from_error_queue(exceptionType):
|
||||
def text(charp):
|
||||
return native(ffi.string(charp))
|
||||
|
||||
errors = []
|
||||
while True:
|
||||
error = lib.ERR_get_error()
|
||||
if error == 0:
|
||||
break
|
||||
errors.append((
|
||||
text(lib.ERR_lib_error_string(error)),
|
||||
text(lib.ERR_func_error_string(error)),
|
||||
text(lib.ERR_reason_error_string(error))))
|
||||
|
||||
raise exceptionType(errors)
|
||||
|
||||
|
||||
|
||||
def native(s):
|
||||
"""
|
||||
Convert :py:class:`bytes` or :py:class:`unicode` to the native
|
||||
:py:class:`str` type, using UTF-8 encoding if conversion is necessary.
|
||||
|
||||
:raise UnicodeError: The input string is not UTF-8 decodeable.
|
||||
|
||||
:raise TypeError: The input is neither :py:class:`bytes` nor
|
||||
:py:class:`unicode`.
|
||||
"""
|
||||
if not isinstance(s, (binary_type, text_type)):
|
||||
raise TypeError("%r is neither bytes nor unicode" % s)
|
||||
if PY3:
|
||||
if isinstance(s, binary_type):
|
||||
return s.decode("utf-8")
|
||||
else:
|
||||
if isinstance(s, text_type):
|
||||
return s.encode("utf-8")
|
||||
return s
|
||||
|
||||
|
||||
|
||||
if PY3:
|
||||
def byte_string(s):
|
||||
return s.encode("charmap")
|
||||
else:
|
||||
def byte_string(s):
|
||||
return s
|
File diff suppressed because it is too large
Load diff
|
@ -1,180 +0,0 @@
|
|||
"""
|
||||
PRNG management routines, thin wrappers.
|
||||
|
||||
See the file RATIONALE for a short explanation of why this module was written.
|
||||
"""
|
||||
|
||||
from functools import partial
|
||||
|
||||
from six import integer_types as _integer_types
|
||||
|
||||
from OpenSSL._util import (
|
||||
ffi as _ffi,
|
||||
lib as _lib,
|
||||
exception_from_error_queue as _exception_from_error_queue)
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
"""
|
||||
An error occurred in an `OpenSSL.rand` API.
|
||||
"""
|
||||
|
||||
_raise_current_error = partial(_exception_from_error_queue, Error)
|
||||
|
||||
_unspecified = object()
|
||||
|
||||
_builtin_bytes = bytes
|
||||
|
||||
def bytes(num_bytes):
|
||||
"""
|
||||
Get some random bytes as a string.
|
||||
|
||||
:param num_bytes: The number of bytes to fetch
|
||||
:return: A string of random bytes
|
||||
"""
|
||||
if not isinstance(num_bytes, _integer_types):
|
||||
raise TypeError("num_bytes must be an integer")
|
||||
|
||||
if num_bytes < 0:
|
||||
raise ValueError("num_bytes must not be negative")
|
||||
|
||||
result_buffer = _ffi.new("char[]", num_bytes)
|
||||
result_code = _lib.RAND_bytes(result_buffer, num_bytes)
|
||||
if result_code == -1:
|
||||
# TODO: No tests for this code path. Triggering a RAND_bytes failure
|
||||
# might involve supplying a custom ENGINE? That's hard.
|
||||
_raise_current_error()
|
||||
|
||||
return _ffi.buffer(result_buffer)[:]
|
||||
|
||||
|
||||
|
||||
def add(buffer, entropy):
|
||||
"""
|
||||
Add data with a given entropy to the PRNG
|
||||
|
||||
:param buffer: Buffer with random data
|
||||
:param entropy: The entropy (in bytes) measurement of the buffer
|
||||
:return: None
|
||||
"""
|
||||
if not isinstance(buffer, _builtin_bytes):
|
||||
raise TypeError("buffer must be a byte string")
|
||||
|
||||
if not isinstance(entropy, int):
|
||||
raise TypeError("entropy must be an integer")
|
||||
|
||||
# TODO Nothing tests this call actually being made, or made properly.
|
||||
_lib.RAND_add(buffer, len(buffer), entropy)
|
||||
|
||||
|
||||
|
||||
def seed(buffer):
|
||||
"""
|
||||
Alias for rand_add, with entropy equal to length
|
||||
|
||||
:param buffer: Buffer with random data
|
||||
:return: None
|
||||
"""
|
||||
if not isinstance(buffer, _builtin_bytes):
|
||||
raise TypeError("buffer must be a byte string")
|
||||
|
||||
# TODO Nothing tests this call actually being made, or made properly.
|
||||
_lib.RAND_seed(buffer, len(buffer))
|
||||
|
||||
|
||||
|
||||
def status():
|
||||
"""
|
||||
Retrieve the status of the PRNG
|
||||
|
||||
:return: True if the PRNG is seeded enough, false otherwise
|
||||
"""
|
||||
return _lib.RAND_status()
|
||||
|
||||
|
||||
|
||||
def egd(path, bytes=_unspecified):
|
||||
"""
|
||||
Query an entropy gathering daemon (EGD) for random data and add it to the
|
||||
PRNG. I haven't found any problems when the socket is missing, the function
|
||||
just returns 0.
|
||||
|
||||
:param path: The path to the EGD socket
|
||||
:param bytes: (optional) The number of bytes to read, default is 255
|
||||
:returns: The number of bytes read (NB: a value of 0 isn't necessarily an
|
||||
error, check rand.status())
|
||||
"""
|
||||
if not isinstance(path, _builtin_bytes):
|
||||
raise TypeError("path must be a byte string")
|
||||
|
||||
if bytes is _unspecified:
|
||||
bytes = 255
|
||||
elif not isinstance(bytes, int):
|
||||
raise TypeError("bytes must be an integer")
|
||||
|
||||
return _lib.RAND_egd_bytes(path, bytes)
|
||||
|
||||
|
||||
|
||||
def cleanup():
|
||||
"""
|
||||
Erase the memory used by the PRNG.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# TODO Nothing tests this call actually being made, or made properly.
|
||||
_lib.RAND_cleanup()
|
||||
|
||||
|
||||
|
||||
def load_file(filename, maxbytes=_unspecified):
|
||||
"""
|
||||
Seed the PRNG with data from a file
|
||||
|
||||
:param filename: The file to read data from
|
||||
:param maxbytes: (optional) The number of bytes to read, default is
|
||||
to read the entire file
|
||||
:return: The number of bytes read
|
||||
"""
|
||||
if not isinstance(filename, _builtin_bytes):
|
||||
raise TypeError("filename must be a string")
|
||||
|
||||
if maxbytes is _unspecified:
|
||||
maxbytes = -1
|
||||
elif not isinstance(maxbytes, int):
|
||||
raise TypeError("maxbytes must be an integer")
|
||||
|
||||
return _lib.RAND_load_file(filename, maxbytes)
|
||||
|
||||
|
||||
|
||||
def write_file(filename):
|
||||
"""
|
||||
Save PRNG state to a file
|
||||
|
||||
:param filename: The file to write data to
|
||||
:return: The number of bytes written
|
||||
"""
|
||||
if not isinstance(filename, _builtin_bytes):
|
||||
raise TypeError("filename must be a string")
|
||||
|
||||
return _lib.RAND_write_file(filename)
|
||||
|
||||
|
||||
# TODO There are no tests for screen at all
|
||||
def screen():
|
||||
"""
|
||||
Add the current contents of the screen to the PRNG state. Availability:
|
||||
Windows.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
_lib.RAND_screen()
|
||||
|
||||
if getattr(_lib, 'RAND_screen', None) is None:
|
||||
del screen
|
||||
|
||||
|
||||
# TODO There are no tests for the RAND strings being loaded, whatever that
|
||||
# means.
|
||||
_lib.ERR_load_RAND_strings()
|
|
@ -1,6 +0,0 @@
|
|||
# Copyright (C) Jean-Paul Calderone
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Package containing unit tests for :py:mod:`OpenSSL`.
|
||||
"""
|
File diff suppressed because it is too large
Load diff
|
@ -1,203 +0,0 @@
|
|||
# Copyright (c) Frederick Dean
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Unit tests for :py:obj:`OpenSSL.rand`.
|
||||
"""
|
||||
|
||||
from unittest import main
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
|
||||
from OpenSSL.test.util import TestCase, b
|
||||
from OpenSSL import rand
|
||||
|
||||
|
||||
class RandTests(TestCase):
|
||||
def test_bytes_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.bytes` raises :py:obj:`TypeError` if called with the wrong
|
||||
number of arguments or with a non-:py:obj:`int` argument.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.bytes)
|
||||
self.assertRaises(TypeError, rand.bytes, None)
|
||||
self.assertRaises(TypeError, rand.bytes, 3, None)
|
||||
|
||||
|
||||
def test_insufficientMemory(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.bytes` raises :py:obj:`MemoryError` if more bytes
|
||||
are requested than will fit in memory.
|
||||
"""
|
||||
self.assertRaises(MemoryError, rand.bytes, sys.maxsize)
|
||||
|
||||
|
||||
def test_bytes(self):
|
||||
"""
|
||||
Verify that we can obtain bytes from rand_bytes() and
|
||||
that they are different each time. Test the parameter
|
||||
of rand_bytes() for bad values.
|
||||
"""
|
||||
b1 = rand.bytes(50)
|
||||
self.assertEqual(len(b1), 50)
|
||||
b2 = rand.bytes(num_bytes=50) # parameter by name
|
||||
self.assertNotEqual(b1, b2) # Hip, Hip, Horay! FIPS complaince
|
||||
b3 = rand.bytes(num_bytes=0)
|
||||
self.assertEqual(len(b3), 0)
|
||||
exc = self.assertRaises(ValueError, rand.bytes, -1)
|
||||
self.assertEqual(str(exc), "num_bytes must not be negative")
|
||||
|
||||
|
||||
def test_add_wrong_args(self):
|
||||
"""
|
||||
When called with the wrong number of arguments, or with arguments not of
|
||||
type :py:obj:`str` and :py:obj:`int`, :py:obj:`OpenSSL.rand.add` raises :py:obj:`TypeError`.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.add)
|
||||
self.assertRaises(TypeError, rand.add, b("foo"), None)
|
||||
self.assertRaises(TypeError, rand.add, None, 3)
|
||||
self.assertRaises(TypeError, rand.add, b("foo"), 3, None)
|
||||
|
||||
|
||||
def test_add(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.add` adds entropy to the PRNG.
|
||||
"""
|
||||
rand.add(b('hamburger'), 3)
|
||||
|
||||
|
||||
def test_seed_wrong_args(self):
|
||||
"""
|
||||
When called with the wrong number of arguments, or with a non-:py:obj:`str`
|
||||
argument, :py:obj:`OpenSSL.rand.seed` raises :py:obj:`TypeError`.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.seed)
|
||||
self.assertRaises(TypeError, rand.seed, None)
|
||||
self.assertRaises(TypeError, rand.seed, b("foo"), None)
|
||||
|
||||
|
||||
def test_seed(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.seed` adds entropy to the PRNG.
|
||||
"""
|
||||
rand.seed(b('milk shake'))
|
||||
|
||||
|
||||
def test_status_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.status` raises :py:obj:`TypeError` when called with any
|
||||
arguments.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.status, None)
|
||||
|
||||
|
||||
def test_status(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.status` returns :py:obj:`True` if the PRNG has sufficient
|
||||
entropy, :py:obj:`False` otherwise.
|
||||
"""
|
||||
# It's hard to know what it is actually going to return. Different
|
||||
# OpenSSL random engines decide differently whether they have enough
|
||||
# entropy or not.
|
||||
self.assertTrue(rand.status() in (1, 2))
|
||||
|
||||
|
||||
def test_egd_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.egd` raises :py:obj:`TypeError` when called with the wrong
|
||||
number of arguments or with arguments not of type :py:obj:`str` and :py:obj:`int`.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.egd)
|
||||
self.assertRaises(TypeError, rand.egd, None)
|
||||
self.assertRaises(TypeError, rand.egd, "foo", None)
|
||||
self.assertRaises(TypeError, rand.egd, None, 3)
|
||||
self.assertRaises(TypeError, rand.egd, "foo", 3, None)
|
||||
|
||||
|
||||
def test_egd_missing(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.egd` returns :py:obj:`0` or :py:obj:`-1` if the
|
||||
EGD socket passed to it does not exist.
|
||||
"""
|
||||
result = rand.egd(self.mktemp())
|
||||
expected = (-1, 0)
|
||||
self.assertTrue(
|
||||
result in expected,
|
||||
"%r not in %r" % (result, expected))
|
||||
|
||||
|
||||
def test_egd_missing_and_bytes(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.egd` returns :py:obj:`0` or :py:obj:`-1` if the
|
||||
EGD socket passed to it does not exist even if a size argument is
|
||||
explicitly passed.
|
||||
"""
|
||||
result = rand.egd(self.mktemp(), 1024)
|
||||
expected = (-1, 0)
|
||||
self.assertTrue(
|
||||
result in expected,
|
||||
"%r not in %r" % (result, expected))
|
||||
|
||||
|
||||
def test_cleanup_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.cleanup` raises :py:obj:`TypeError` when called with any
|
||||
arguments.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.cleanup, None)
|
||||
|
||||
|
||||
def test_cleanup(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.cleanup` releases the memory used by the PRNG and returns
|
||||
:py:obj:`None`.
|
||||
"""
|
||||
self.assertIdentical(rand.cleanup(), None)
|
||||
|
||||
|
||||
def test_load_file_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.load_file` raises :py:obj:`TypeError` when called the wrong
|
||||
number of arguments or arguments not of type :py:obj:`str` and :py:obj:`int`.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.load_file)
|
||||
self.assertRaises(TypeError, rand.load_file, "foo", None)
|
||||
self.assertRaises(TypeError, rand.load_file, None, 1)
|
||||
self.assertRaises(TypeError, rand.load_file, "foo", 1, None)
|
||||
|
||||
|
||||
def test_write_file_wrong_args(self):
|
||||
"""
|
||||
:py:obj:`OpenSSL.rand.write_file` raises :py:obj:`TypeError` when called with the
|
||||
wrong number of arguments or a non-:py:obj:`str` argument.
|
||||
"""
|
||||
self.assertRaises(TypeError, rand.write_file)
|
||||
self.assertRaises(TypeError, rand.write_file, None)
|
||||
self.assertRaises(TypeError, rand.write_file, "foo", None)
|
||||
|
||||
|
||||
def test_files(self):
|
||||
"""
|
||||
Test reading and writing of files via rand functions.
|
||||
"""
|
||||
# Write random bytes to a file
|
||||
tmpfile = self.mktemp()
|
||||
# Make sure it exists (so cleanup definitely succeeds)
|
||||
fObj = open(tmpfile, 'w')
|
||||
fObj.close()
|
||||
try:
|
||||
rand.write_file(tmpfile)
|
||||
# Verify length of written file
|
||||
size = os.stat(tmpfile)[stat.ST_SIZE]
|
||||
self.assertEqual(1024, size)
|
||||
# Read random bytes from file
|
||||
rand.load_file(tmpfile)
|
||||
rand.load_file(tmpfile, 4) # specify a length
|
||||
finally:
|
||||
# Cleanup
|
||||
os.unlink(tmpfile)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
File diff suppressed because it is too large
Load diff
|
@ -1,302 +0,0 @@
|
|||
# Copyright (C) Jean-Paul Calderone
|
||||
# Copyright (C) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Helpers for the OpenSSL test suite, largely copied from
|
||||
U{Twisted<http://twistedmatrix.com/>}.
|
||||
"""
|
||||
|
||||
import shutil
|
||||
import traceback
|
||||
import os, os.path
|
||||
from tempfile import mktemp
|
||||
from unittest import TestCase
|
||||
import sys
|
||||
|
||||
from OpenSSL._util import exception_from_error_queue
|
||||
from OpenSSL.crypto import Error
|
||||
|
||||
try:
|
||||
import memdbg
|
||||
except Exception:
|
||||
class _memdbg(object): heap = None
|
||||
memdbg = _memdbg()
|
||||
|
||||
from OpenSSL._util import ffi, lib, byte_string as b
|
||||
|
||||
class TestCase(TestCase):
|
||||
"""
|
||||
:py:class:`TestCase` adds useful testing functionality beyond what is available
|
||||
from the standard library :py:class:`unittest.TestCase`.
|
||||
"""
|
||||
def run(self, result):
|
||||
run = super(TestCase, self).run
|
||||
if memdbg.heap is None:
|
||||
return run(result)
|
||||
|
||||
# Run the test as usual
|
||||
before = set(memdbg.heap)
|
||||
run(result)
|
||||
|
||||
# Clean up some long-lived allocations so they won't be reported as
|
||||
# memory leaks.
|
||||
lib.CRYPTO_cleanup_all_ex_data()
|
||||
lib.ERR_remove_thread_state(ffi.NULL)
|
||||
after = set(memdbg.heap)
|
||||
|
||||
if not after - before:
|
||||
# No leaks, fast succeed
|
||||
return
|
||||
|
||||
if result.wasSuccessful():
|
||||
# If it passed, run it again with memory debugging
|
||||
before = set(memdbg.heap)
|
||||
run(result)
|
||||
|
||||
# Clean up some long-lived allocations so they won't be reported as
|
||||
# memory leaks.
|
||||
lib.CRYPTO_cleanup_all_ex_data()
|
||||
lib.ERR_remove_thread_state(ffi.NULL)
|
||||
|
||||
after = set(memdbg.heap)
|
||||
|
||||
self._reportLeaks(after - before, result)
|
||||
|
||||
|
||||
def _reportLeaks(self, leaks, result):
|
||||
def format_leak(p):
|
||||
stacks = memdbg.heap[p]
|
||||
# Eventually look at multiple stacks for the realloc() case. For
|
||||
# now just look at the original allocation location.
|
||||
(size, python_stack, c_stack) = stacks[0]
|
||||
|
||||
stack = traceback.format_list(python_stack)[:-1]
|
||||
|
||||
# c_stack looks something like this (interesting parts indicated
|
||||
# with inserted arrows not part of the data):
|
||||
#
|
||||
# /home/exarkun/Projects/pyOpenSSL/branches/use-opentls/__pycache__/_cffi__x89095113xb9185b9b.so(+0x12cf) [0x7fe2e20582cf]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyCFunction_Call+0x8b) [0x56265a]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x4d5f52]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyEval_EvalFrameEx+0x753b) [0x4d0e1e]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x4d6419]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x4d6129]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyEval_EvalFrameEx+0x753b) [0x4d0e1e]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyEval_EvalCodeEx+0x1043) [0x4d3726]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x55fd51]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyObject_Call+0x7e) [0x420ee6]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyEval_CallObjectWithKeywords+0x158) [0x4d56ec]
|
||||
# /home/exarkun/.local/lib/python2.7/site-packages/cffi-0.5-py2.7-linux-x86_64.egg/_cffi_backend.so(+0xe96e) [0x7fe2e38be96e]
|
||||
# /usr/lib/x86_64-linux-gnu/libffi.so.6(ffi_closure_unix64_inner+0x1b9) [0x7fe2e36ad819]
|
||||
# /usr/lib/x86_64-linux-gnu/libffi.so.6(ffi_closure_unix64+0x46) [0x7fe2e36adb7c]
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(CRYPTO_malloc+0x64) [0x7fe2e1cef784] <------ end interesting
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(lh_insert+0x16b) [0x7fe2e1d6a24b] .
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(+0x61c18) [0x7fe2e1cf0c18] .
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(+0x625ec) [0x7fe2e1cf15ec] .
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(DSA_new_method+0xe6) [0x7fe2e1d524d6] .
|
||||
# /lib/x86_64-linux-gnu/libcrypto.so.1.0.0(DSA_generate_parameters+0x3a) [0x7fe2e1d5364a] <------ begin interesting
|
||||
# /home/exarkun/Projects/opentls/trunk/tls/c/__pycache__/_cffi__x305d4698xb539baaa.so(+0x1f397) [0x7fe2df84d397]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyCFunction_Call+0x8b) [0x56265a]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x4d5f52]
|
||||
# /home/exarkun/Projects/cpython/2.7/python(PyEval_EvalFrameEx+0x753b) [0x4d0e1e]
|
||||
# /home/exarkun/Projects/cpython/2.7/python() [0x4d6419]
|
||||
# ...
|
||||
#
|
||||
# Notice the stack is upside down compared to a Python traceback.
|
||||
# Identify the start and end of interesting bits and stuff it into the stack we report.
|
||||
|
||||
saved = list(c_stack)
|
||||
|
||||
# Figure the first interesting frame will be after a the cffi-compiled module
|
||||
while c_stack and '/__pycache__/_cffi__' not in c_stack[-1]:
|
||||
c_stack.pop()
|
||||
|
||||
# Figure the last interesting frame will always be CRYPTO_malloc,
|
||||
# since that's where we hooked in to things.
|
||||
while c_stack and 'CRYPTO_malloc' not in c_stack[0] and 'CRYPTO_realloc' not in c_stack[0]:
|
||||
c_stack.pop(0)
|
||||
|
||||
if c_stack:
|
||||
c_stack.reverse()
|
||||
else:
|
||||
c_stack = saved[::-1]
|
||||
stack.extend([frame + "\n" for frame in c_stack])
|
||||
|
||||
stack.insert(0, "Leaked (%s) at:\n")
|
||||
return "".join(stack)
|
||||
|
||||
if leaks:
|
||||
unique_leaks = {}
|
||||
for p in leaks:
|
||||
size = memdbg.heap[p][-1][0]
|
||||
new_leak = format_leak(p)
|
||||
if new_leak not in unique_leaks:
|
||||
unique_leaks[new_leak] = [(size, p)]
|
||||
else:
|
||||
unique_leaks[new_leak].append((size, p))
|
||||
memdbg.free(p)
|
||||
|
||||
for (stack, allocs) in unique_leaks.iteritems():
|
||||
allocs_accum = []
|
||||
for (size, pointer) in allocs:
|
||||
|
||||
addr = int(ffi.cast('uintptr_t', pointer))
|
||||
allocs_accum.append("%d@0x%x" % (size, addr))
|
||||
allocs_report = ", ".join(sorted(allocs_accum))
|
||||
|
||||
result.addError(
|
||||
self,
|
||||
(None, Exception(stack % (allocs_report,)), None))
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Clean up any files or directories created using :py:meth:`TestCase.mktemp`.
|
||||
Subclasses must invoke this method if they override it or the
|
||||
cleanup will not occur.
|
||||
"""
|
||||
if False and self._temporaryFiles is not None:
|
||||
for temp in self._temporaryFiles:
|
||||
if os.path.isdir(temp):
|
||||
shutil.rmtree(temp)
|
||||
elif os.path.exists(temp):
|
||||
os.unlink(temp)
|
||||
try:
|
||||
exception_from_error_queue(Error)
|
||||
except Error:
|
||||
e = sys.exc_info()[1]
|
||||
if e.args != ([],):
|
||||
self.fail("Left over errors in OpenSSL error queue: " + repr(e))
|
||||
|
||||
|
||||
def assertIsInstance(self, instance, classOrTuple, message=None):
|
||||
"""
|
||||
Fail if C{instance} is not an instance of the given class or of
|
||||
one of the given classes.
|
||||
|
||||
@param instance: the object to test the type (first argument of the
|
||||
C{isinstance} call).
|
||||
@type instance: any.
|
||||
@param classOrTuple: the class or classes to test against (second
|
||||
argument of the C{isinstance} call).
|
||||
@type classOrTuple: class, type, or tuple.
|
||||
|
||||
@param message: Custom text to include in the exception text if the
|
||||
assertion fails.
|
||||
"""
|
||||
if not isinstance(instance, classOrTuple):
|
||||
if message is None:
|
||||
suffix = ""
|
||||
else:
|
||||
suffix = ": " + message
|
||||
self.fail("%r is not an instance of %s%s" % (
|
||||
instance, classOrTuple, suffix))
|
||||
|
||||
|
||||
def failUnlessIn(self, containee, container, msg=None):
|
||||
"""
|
||||
Fail the test if :py:data:`containee` is not found in :py:data:`container`.
|
||||
|
||||
:param containee: the value that should be in :py:class:`container`
|
||||
:param container: a sequence type, or in the case of a mapping type,
|
||||
will follow semantics of 'if key in dict.keys()'
|
||||
:param msg: if msg is None, then the failure message will be
|
||||
'%r not in %r' % (first, second)
|
||||
"""
|
||||
if containee not in container:
|
||||
raise self.failureException(msg or "%r not in %r"
|
||||
% (containee, container))
|
||||
return containee
|
||||
assertIn = failUnlessIn
|
||||
|
||||
def failUnlessIdentical(self, first, second, msg=None):
|
||||
"""
|
||||
Fail the test if :py:data:`first` is not :py:data:`second`. This is an
|
||||
obect-identity-equality test, not an object equality
|
||||
(i.e. :py:func:`__eq__`) test.
|
||||
|
||||
:param msg: if msg is None, then the failure message will be
|
||||
'%r is not %r' % (first, second)
|
||||
"""
|
||||
if first is not second:
|
||||
raise self.failureException(msg or '%r is not %r' % (first, second))
|
||||
return first
|
||||
assertIdentical = failUnlessIdentical
|
||||
|
||||
|
||||
def failIfIdentical(self, first, second, msg=None):
|
||||
"""
|
||||
Fail the test if :py:data:`first` is :py:data:`second`. This is an
|
||||
obect-identity-equality test, not an object equality
|
||||
(i.e. :py:func:`__eq__`) test.
|
||||
|
||||
:param msg: if msg is None, then the failure message will be
|
||||
'%r is %r' % (first, second)
|
||||
"""
|
||||
if first is second:
|
||||
raise self.failureException(msg or '%r is %r' % (first, second))
|
||||
return first
|
||||
assertNotIdentical = failIfIdentical
|
||||
|
||||
|
||||
def failUnlessRaises(self, exception, f, *args, **kwargs):
|
||||
"""
|
||||
Fail the test unless calling the function :py:data:`f` with the given
|
||||
:py:data:`args` and :py:data:`kwargs` raises :py:data:`exception`. The
|
||||
failure will report the traceback and call stack of the unexpected
|
||||
exception.
|
||||
|
||||
:param exception: exception type that is to be expected
|
||||
:param f: the function to call
|
||||
|
||||
:return: The raised exception instance, if it is of the given type.
|
||||
:raise self.failureException: Raised if the function call does
|
||||
not raise an exception or if it raises an exception of a
|
||||
different type.
|
||||
"""
|
||||
try:
|
||||
result = f(*args, **kwargs)
|
||||
except exception:
|
||||
inst = sys.exc_info()[1]
|
||||
return inst
|
||||
except:
|
||||
raise self.failureException('%s raised instead of %s'
|
||||
% (sys.exc_info()[0],
|
||||
exception.__name__,
|
||||
))
|
||||
else:
|
||||
raise self.failureException('%s not raised (%r returned)'
|
||||
% (exception.__name__, result))
|
||||
assertRaises = failUnlessRaises
|
||||
|
||||
|
||||
_temporaryFiles = None
|
||||
def mktemp(self):
|
||||
"""
|
||||
Pathetic substitute for twisted.trial.unittest.TestCase.mktemp.
|
||||
"""
|
||||
if self._temporaryFiles is None:
|
||||
self._temporaryFiles = []
|
||||
temp = b(mktemp(dir="."))
|
||||
self._temporaryFiles.append(temp)
|
||||
return temp
|
||||
|
||||
|
||||
# Other stuff
|
||||
def assertConsistentType(self, theType, name, *constructionArgs):
|
||||
"""
|
||||
Perform various assertions about :py:data:`theType` to ensure that it is a
|
||||
well-defined type. This is useful for extension types, where it's
|
||||
pretty easy to do something wacky. If something about the type is
|
||||
unusual, an exception will be raised.
|
||||
|
||||
:param theType: The type object about which to make assertions.
|
||||
:param name: A string giving the name of the type.
|
||||
:param constructionArgs: Positional arguments to use with :py:data:`theType` to
|
||||
create an instance of it.
|
||||
"""
|
||||
self.assertEqual(theType.__name__, name)
|
||||
self.assertTrue(isinstance(theType, type))
|
||||
instance = theType(*constructionArgs)
|
||||
self.assertIdentical(type(instance), theType)
|
|
@ -1,28 +0,0 @@
|
|||
from OpenSSL import SSL
|
||||
_ssl = SSL
|
||||
del SSL
|
||||
|
||||
import threading
|
||||
_RLock = threading.RLock
|
||||
del threading
|
||||
|
||||
class Connection:
|
||||
def __init__(self, *args):
|
||||
self._ssl_conn = apply(_ssl.Connection, args)
|
||||
self._lock = _RLock()
|
||||
|
||||
for f in ('get_context', 'pending', 'send', 'write', 'recv', 'read',
|
||||
'renegotiate', 'bind', 'listen', 'connect', 'accept',
|
||||
'setblocking', 'fileno', 'shutdown', 'close', 'get_cipher_list',
|
||||
'getpeername', 'getsockname', 'getsockopt', 'setsockopt',
|
||||
'makefile', 'get_app_data', 'set_app_data', 'state_string',
|
||||
'sock_shutdown', 'get_peer_certificate', 'get_peer_cert_chain', 'want_read',
|
||||
'want_write', 'set_connect_state', 'set_accept_state',
|
||||
'connect_ex', 'sendall'):
|
||||
exec("""def %s(self, *args):
|
||||
self._lock.acquire()
|
||||
try:
|
||||
return self._ssl_conn.%s(*args)
|
||||
finally:
|
||||
self._lock.release()\n""" % (f, f))
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
# Copyright (C) AB Strakt
|
||||
# Copyright (C) Jean-Paul Calderone
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
pyOpenSSL - A simple wrapper around the OpenSSL library
|
||||
"""
|
||||
|
||||
__version__ = '0.14'
|
|
@ -1,366 +1,366 @@
|
|||
../sqlalchemy/interfaces.py
|
||||
../sqlalchemy/events.py
|
||||
../sqlalchemy/types.py
|
||||
../sqlalchemy/exc.py
|
||||
../sqlalchemy/schema.py
|
||||
../sqlalchemy/inspection.py
|
||||
../sqlalchemy/__init__.py
|
||||
../sqlalchemy/pool.py
|
||||
../sqlalchemy/processors.py
|
||||
../sqlalchemy/log.py
|
||||
../sqlalchemy/databases/__init__.py
|
||||
../sqlalchemy/testing/engines.py
|
||||
../sqlalchemy/testing/schema.py
|
||||
../sqlalchemy/testing/pickleable.py
|
||||
../sqlalchemy/testing/fixtures.py
|
||||
../sqlalchemy/testing/__init__.py
|
||||
../sqlalchemy/testing/assertsql.py
|
||||
../sqlalchemy/testing/config.py
|
||||
../sqlalchemy/testing/warnings.py
|
||||
../sqlalchemy/testing/distutils_run.py
|
||||
../sqlalchemy/testing/requirements.py
|
||||
../sqlalchemy/testing/runner.py
|
||||
../sqlalchemy/testing/assertions.py
|
||||
../sqlalchemy/testing/profiling.py
|
||||
../sqlalchemy/testing/mock.py
|
||||
../sqlalchemy/testing/exclusions.py
|
||||
../sqlalchemy/testing/util.py
|
||||
../sqlalchemy/testing/entities.py
|
||||
../sqlalchemy/testing/plugin/noseplugin.py
|
||||
../sqlalchemy/testing/plugin/__init__.py
|
||||
../sqlalchemy/testing/plugin/pytestplugin.py
|
||||
../sqlalchemy/testing/plugin/plugin_base.py
|
||||
../sqlalchemy/testing/suite/test_insert.py
|
||||
../sqlalchemy/testing/suite/test_results.py
|
||||
../sqlalchemy/testing/suite/__init__.py
|
||||
../sqlalchemy/testing/suite/test_select.py
|
||||
../sqlalchemy/testing/suite/test_sequence.py
|
||||
../sqlalchemy/testing/suite/test_types.py
|
||||
../sqlalchemy/testing/suite/test_update_delete.py
|
||||
../sqlalchemy/testing/suite/test_reflection.py
|
||||
../sqlalchemy/testing/suite/test_ddl.py
|
||||
../sqlalchemy/orm/persistence.py
|
||||
../sqlalchemy/orm/interfaces.py
|
||||
../sqlalchemy/orm/events.py
|
||||
../sqlalchemy/orm/path_registry.py
|
||||
../sqlalchemy/orm/descriptor_props.py
|
||||
../sqlalchemy/orm/identity.py
|
||||
../sqlalchemy/orm/evaluator.py
|
||||
../sqlalchemy/orm/exc.py
|
||||
../sqlalchemy/orm/base.py
|
||||
../sqlalchemy/orm/__init__.py
|
||||
../sqlalchemy/orm/properties.py
|
||||
../sqlalchemy/orm/relationships.py
|
||||
../sqlalchemy/orm/collections.py
|
||||
../sqlalchemy/orm/strategy_options.py
|
||||
../sqlalchemy/orm/dynamic.py
|
||||
../sqlalchemy/orm/attributes.py
|
||||
../sqlalchemy/orm/mapper.py
|
||||
../sqlalchemy/orm/state.py
|
||||
../sqlalchemy/orm/sync.py
|
||||
../sqlalchemy/orm/loading.py
|
||||
../sqlalchemy/orm/strategies.py
|
||||
../sqlalchemy/orm/unitofwork.py
|
||||
../sqlalchemy/orm/query.py
|
||||
../sqlalchemy/orm/instrumentation.py
|
||||
../sqlalchemy/orm/session.py
|
||||
../sqlalchemy/orm/deprecated_interfaces.py
|
||||
../sqlalchemy/orm/scoping.py
|
||||
../sqlalchemy/orm/dependency.py
|
||||
../sqlalchemy/orm/util.py
|
||||
../sqlalchemy/sql/default_comparator.py
|
||||
../sqlalchemy/sql/sqltypes.py
|
||||
../sqlalchemy/sql/functions.py
|
||||
../sqlalchemy/sql/base.py
|
||||
../sqlalchemy/sql/schema.py
|
||||
../sqlalchemy/sql/__init__.py
|
||||
../sqlalchemy/sql/ddl.py
|
||||
../sqlalchemy/sql/elements.py
|
||||
../sqlalchemy/sql/compiler.py
|
||||
../sqlalchemy/sql/annotation.py
|
||||
../sqlalchemy/sql/dml.py
|
||||
../sqlalchemy/sql/expression.py
|
||||
../sqlalchemy/sql/operators.py
|
||||
../sqlalchemy/sql/selectable.py
|
||||
../sqlalchemy/sql/visitors.py
|
||||
../sqlalchemy/sql/type_api.py
|
||||
../sqlalchemy/sql/naming.py
|
||||
../sqlalchemy/sql/util.py
|
||||
../sqlalchemy/ext/serializer.py
|
||||
../sqlalchemy/ext/associationproxy.py
|
||||
../sqlalchemy/ext/automap.py
|
||||
../sqlalchemy/ext/__init__.py
|
||||
../sqlalchemy/ext/hybrid.py
|
||||
../sqlalchemy/ext/compiler.py
|
||||
../sqlalchemy/ext/horizontal_shard.py
|
||||
../sqlalchemy/ext/orderinglist.py
|
||||
../sqlalchemy/ext/instrumentation.py
|
||||
../sqlalchemy/ext/mutable.py
|
||||
../sqlalchemy/ext/declarative/base.py
|
||||
../sqlalchemy/ext/declarative/__init__.py
|
||||
../sqlalchemy/ext/declarative/clsregistry.py
|
||||
../sqlalchemy/ext/declarative/api.py
|
||||
../sqlalchemy/util/langhelpers.py
|
||||
../sqlalchemy/util/queue.py
|
||||
../sqlalchemy/inspection.py
|
||||
../sqlalchemy/interfaces.py
|
||||
../sqlalchemy/types.py
|
||||
../sqlalchemy/pool.py
|
||||
../sqlalchemy/__init__.py
|
||||
../sqlalchemy/schema.py
|
||||
../sqlalchemy/exc.py
|
||||
../sqlalchemy/events.py
|
||||
../sqlalchemy/processors.py
|
||||
../sqlalchemy/util/compat.py
|
||||
../sqlalchemy/util/__init__.py
|
||||
../sqlalchemy/util/deprecations.py
|
||||
../sqlalchemy/util/_collections.py
|
||||
../sqlalchemy/util/topological.py
|
||||
../sqlalchemy/connectors/mxodbc.py
|
||||
../sqlalchemy/connectors/__init__.py
|
||||
../sqlalchemy/connectors/pyodbc.py
|
||||
../sqlalchemy/connectors/mysqldb.py
|
||||
../sqlalchemy/connectors/zxJDBC.py
|
||||
../sqlalchemy/dialects/postgres.py
|
||||
../sqlalchemy/dialects/__init__.py
|
||||
../sqlalchemy/dialects/mssql/adodbapi.py
|
||||
../sqlalchemy/dialects/mssql/mxodbc.py
|
||||
../sqlalchemy/dialects/mssql/base.py
|
||||
../sqlalchemy/dialects/mssql/information_schema.py
|
||||
../sqlalchemy/dialects/mssql/__init__.py
|
||||
../sqlalchemy/dialects/mssql/pyodbc.py
|
||||
../sqlalchemy/dialects/mssql/zxjdbc.py
|
||||
../sqlalchemy/dialects/mssql/pymssql.py
|
||||
../sqlalchemy/dialects/postgresql/pg8000.py
|
||||
../sqlalchemy/dialects/postgresql/ranges.py
|
||||
../sqlalchemy/dialects/postgresql/base.py
|
||||
../sqlalchemy/dialects/postgresql/__init__.py
|
||||
../sqlalchemy/dialects/postgresql/zxjdbc.py
|
||||
../sqlalchemy/dialects/postgresql/json.py
|
||||
../sqlalchemy/dialects/postgresql/pypostgresql.py
|
||||
../sqlalchemy/dialects/postgresql/constraints.py
|
||||
../sqlalchemy/dialects/postgresql/hstore.py
|
||||
../sqlalchemy/dialects/postgresql/psycopg2.py
|
||||
../sqlalchemy/dialects/sybase/mxodbc.py
|
||||
../sqlalchemy/dialects/sybase/base.py
|
||||
../sqlalchemy/dialects/sybase/__init__.py
|
||||
../sqlalchemy/dialects/sybase/pyodbc.py
|
||||
../sqlalchemy/dialects/sybase/pysybase.py
|
||||
../sqlalchemy/dialects/drizzle/base.py
|
||||
../sqlalchemy/dialects/drizzle/__init__.py
|
||||
../sqlalchemy/dialects/drizzle/mysqldb.py
|
||||
../sqlalchemy/dialects/mysql/mysqlconnector.py
|
||||
../sqlalchemy/dialects/mysql/base.py
|
||||
../sqlalchemy/dialects/mysql/__init__.py
|
||||
../sqlalchemy/dialects/mysql/pyodbc.py
|
||||
../sqlalchemy/dialects/mysql/zxjdbc.py
|
||||
../sqlalchemy/dialects/mysql/oursql.py
|
||||
../sqlalchemy/dialects/mysql/pymysql.py
|
||||
../sqlalchemy/dialects/mysql/cymysql.py
|
||||
../sqlalchemy/dialects/mysql/gaerdbms.py
|
||||
../sqlalchemy/dialects/mysql/mysqldb.py
|
||||
../sqlalchemy/dialects/sqlite/base.py
|
||||
../sqlalchemy/dialects/sqlite/__init__.py
|
||||
../sqlalchemy/dialects/sqlite/pysqlite.py
|
||||
../sqlalchemy/dialects/firebird/base.py
|
||||
../sqlalchemy/dialects/firebird/__init__.py
|
||||
../sqlalchemy/dialects/firebird/fdb.py
|
||||
../sqlalchemy/dialects/firebird/kinterbasdb.py
|
||||
../sqlalchemy/dialects/oracle/base.py
|
||||
../sqlalchemy/dialects/oracle/__init__.py
|
||||
../sqlalchemy/dialects/oracle/zxjdbc.py
|
||||
../sqlalchemy/dialects/oracle/cx_oracle.py
|
||||
../sqlalchemy/util/queue.py
|
||||
../sqlalchemy/util/__init__.py
|
||||
../sqlalchemy/util/langhelpers.py
|
||||
../sqlalchemy/ext/horizontal_shard.py
|
||||
../sqlalchemy/ext/serializer.py
|
||||
../sqlalchemy/ext/automap.py
|
||||
../sqlalchemy/ext/associationproxy.py
|
||||
../sqlalchemy/ext/__init__.py
|
||||
../sqlalchemy/ext/hybrid.py
|
||||
../sqlalchemy/ext/mutable.py
|
||||
../sqlalchemy/ext/orderinglist.py
|
||||
../sqlalchemy/ext/compiler.py
|
||||
../sqlalchemy/ext/instrumentation.py
|
||||
../sqlalchemy/ext/declarative/api.py
|
||||
../sqlalchemy/ext/declarative/__init__.py
|
||||
../sqlalchemy/ext/declarative/base.py
|
||||
../sqlalchemy/ext/declarative/clsregistry.py
|
||||
../sqlalchemy/event/api.py
|
||||
../sqlalchemy/event/registry.py
|
||||
../sqlalchemy/event/__init__.py
|
||||
../sqlalchemy/event/legacy.py
|
||||
../sqlalchemy/event/base.py
|
||||
../sqlalchemy/event/attr.py
|
||||
../sqlalchemy/sql/type_api.py
|
||||
../sqlalchemy/sql/ddl.py
|
||||
../sqlalchemy/sql/selectable.py
|
||||
../sqlalchemy/sql/util.py
|
||||
../sqlalchemy/sql/sqltypes.py
|
||||
../sqlalchemy/sql/functions.py
|
||||
../sqlalchemy/sql/operators.py
|
||||
../sqlalchemy/sql/dml.py
|
||||
../sqlalchemy/sql/naming.py
|
||||
../sqlalchemy/sql/expression.py
|
||||
../sqlalchemy/sql/__init__.py
|
||||
../sqlalchemy/sql/schema.py
|
||||
../sqlalchemy/sql/base.py
|
||||
../sqlalchemy/sql/default_comparator.py
|
||||
../sqlalchemy/sql/visitors.py
|
||||
../sqlalchemy/sql/compiler.py
|
||||
../sqlalchemy/sql/elements.py
|
||||
../sqlalchemy/sql/annotation.py
|
||||
../sqlalchemy/engine/default.py
|
||||
../sqlalchemy/engine/url.py
|
||||
../sqlalchemy/engine/util.py
|
||||
../sqlalchemy/engine/interfaces.py
|
||||
../sqlalchemy/engine/result.py
|
||||
../sqlalchemy/engine/base.py
|
||||
../sqlalchemy/engine/url.py
|
||||
../sqlalchemy/engine/threadlocal.py
|
||||
../sqlalchemy/engine/__init__.py
|
||||
../sqlalchemy/engine/default.py
|
||||
../sqlalchemy/engine/strategies.py
|
||||
../sqlalchemy/engine/base.py
|
||||
../sqlalchemy/engine/threadlocal.py
|
||||
../sqlalchemy/engine/reflection.py
|
||||
../sqlalchemy/engine/util.py
|
||||
../sqlalchemy/event/base.py
|
||||
../sqlalchemy/event/__init__.py
|
||||
../sqlalchemy/event/attr.py
|
||||
../sqlalchemy/event/registry.py
|
||||
../sqlalchemy/event/legacy.py
|
||||
../sqlalchemy/event/api.py
|
||||
../sqlalchemy/__pycache__/interfaces.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/events.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/types.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/exc.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/schema.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/inspection.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/pool.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/processors.cpython-34.pyc
|
||||
../sqlalchemy/engine/strategies.py
|
||||
../sqlalchemy/dialects/postgres.py
|
||||
../sqlalchemy/dialects/__init__.py
|
||||
../sqlalchemy/dialects/mysql/mysqlconnector.py
|
||||
../sqlalchemy/dialects/mysql/pymysql.py
|
||||
../sqlalchemy/dialects/mysql/cymysql.py
|
||||
../sqlalchemy/dialects/mysql/oursql.py
|
||||
../sqlalchemy/dialects/mysql/pyodbc.py
|
||||
../sqlalchemy/dialects/mysql/__init__.py
|
||||
../sqlalchemy/dialects/mysql/zxjdbc.py
|
||||
../sqlalchemy/dialects/mysql/base.py
|
||||
../sqlalchemy/dialects/mysql/gaerdbms.py
|
||||
../sqlalchemy/dialects/mysql/mysqldb.py
|
||||
../sqlalchemy/dialects/postgresql/pg8000.py
|
||||
../sqlalchemy/dialects/postgresql/hstore.py
|
||||
../sqlalchemy/dialects/postgresql/pypostgresql.py
|
||||
../sqlalchemy/dialects/postgresql/psycopg2.py
|
||||
../sqlalchemy/dialects/postgresql/ranges.py
|
||||
../sqlalchemy/dialects/postgresql/json.py
|
||||
../sqlalchemy/dialects/postgresql/__init__.py
|
||||
../sqlalchemy/dialects/postgresql/zxjdbc.py
|
||||
../sqlalchemy/dialects/postgresql/base.py
|
||||
../sqlalchemy/dialects/postgresql/constraints.py
|
||||
../sqlalchemy/dialects/sybase/pyodbc.py
|
||||
../sqlalchemy/dialects/sybase/__init__.py
|
||||
../sqlalchemy/dialects/sybase/base.py
|
||||
../sqlalchemy/dialects/sybase/mxodbc.py
|
||||
../sqlalchemy/dialects/sybase/pysybase.py
|
||||
../sqlalchemy/dialects/firebird/fdb.py
|
||||
../sqlalchemy/dialects/firebird/__init__.py
|
||||
../sqlalchemy/dialects/firebird/kinterbasdb.py
|
||||
../sqlalchemy/dialects/firebird/base.py
|
||||
../sqlalchemy/dialects/sqlite/pysqlite.py
|
||||
../sqlalchemy/dialects/sqlite/__init__.py
|
||||
../sqlalchemy/dialects/sqlite/base.py
|
||||
../sqlalchemy/dialects/mssql/information_schema.py
|
||||
../sqlalchemy/dialects/mssql/pymssql.py
|
||||
../sqlalchemy/dialects/mssql/adodbapi.py
|
||||
../sqlalchemy/dialects/mssql/pyodbc.py
|
||||
../sqlalchemy/dialects/mssql/__init__.py
|
||||
../sqlalchemy/dialects/mssql/zxjdbc.py
|
||||
../sqlalchemy/dialects/mssql/base.py
|
||||
../sqlalchemy/dialects/mssql/mxodbc.py
|
||||
../sqlalchemy/dialects/drizzle/__init__.py
|
||||
../sqlalchemy/dialects/drizzle/base.py
|
||||
../sqlalchemy/dialects/drizzle/mysqldb.py
|
||||
../sqlalchemy/dialects/oracle/cx_oracle.py
|
||||
../sqlalchemy/dialects/oracle/__init__.py
|
||||
../sqlalchemy/dialects/oracle/zxjdbc.py
|
||||
../sqlalchemy/dialects/oracle/base.py
|
||||
../sqlalchemy/testing/profiling.py
|
||||
../sqlalchemy/testing/warnings.py
|
||||
../sqlalchemy/testing/engines.py
|
||||
../sqlalchemy/testing/util.py
|
||||
../sqlalchemy/testing/entities.py
|
||||
../sqlalchemy/testing/mock.py
|
||||
../sqlalchemy/testing/exclusions.py
|
||||
../sqlalchemy/testing/assertions.py
|
||||
../sqlalchemy/testing/distutils_run.py
|
||||
../sqlalchemy/testing/fixtures.py
|
||||
../sqlalchemy/testing/pickleable.py
|
||||
../sqlalchemy/testing/__init__.py
|
||||
../sqlalchemy/testing/schema.py
|
||||
../sqlalchemy/testing/runner.py
|
||||
../sqlalchemy/testing/config.py
|
||||
../sqlalchemy/testing/requirements.py
|
||||
../sqlalchemy/testing/assertsql.py
|
||||
../sqlalchemy/testing/plugin/pytestplugin.py
|
||||
../sqlalchemy/testing/plugin/plugin_base.py
|
||||
../sqlalchemy/testing/plugin/noseplugin.py
|
||||
../sqlalchemy/testing/plugin/__init__.py
|
||||
../sqlalchemy/testing/suite/test_types.py
|
||||
../sqlalchemy/testing/suite/test_select.py
|
||||
../sqlalchemy/testing/suite/test_ddl.py
|
||||
../sqlalchemy/testing/suite/test_reflection.py
|
||||
../sqlalchemy/testing/suite/test_sequence.py
|
||||
../sqlalchemy/testing/suite/__init__.py
|
||||
../sqlalchemy/testing/suite/test_results.py
|
||||
../sqlalchemy/testing/suite/test_insert.py
|
||||
../sqlalchemy/testing/suite/test_update_delete.py
|
||||
../sqlalchemy/orm/state.py
|
||||
../sqlalchemy/orm/session.py
|
||||
../sqlalchemy/orm/unitofwork.py
|
||||
../sqlalchemy/orm/properties.py
|
||||
../sqlalchemy/orm/collections.py
|
||||
../sqlalchemy/orm/identity.py
|
||||
../sqlalchemy/orm/util.py
|
||||
../sqlalchemy/orm/sync.py
|
||||
../sqlalchemy/orm/interfaces.py
|
||||
../sqlalchemy/orm/path_registry.py
|
||||
../sqlalchemy/orm/evaluator.py
|
||||
../sqlalchemy/orm/deprecated_interfaces.py
|
||||
../sqlalchemy/orm/mapper.py
|
||||
../sqlalchemy/orm/persistence.py
|
||||
../sqlalchemy/orm/dynamic.py
|
||||
../sqlalchemy/orm/__init__.py
|
||||
../sqlalchemy/orm/scoping.py
|
||||
../sqlalchemy/orm/descriptor_props.py
|
||||
../sqlalchemy/orm/loading.py
|
||||
../sqlalchemy/orm/base.py
|
||||
../sqlalchemy/orm/exc.py
|
||||
../sqlalchemy/orm/events.py
|
||||
../sqlalchemy/orm/strategies.py
|
||||
../sqlalchemy/orm/query.py
|
||||
../sqlalchemy/orm/dependency.py
|
||||
../sqlalchemy/orm/attributes.py
|
||||
../sqlalchemy/orm/relationships.py
|
||||
../sqlalchemy/orm/strategy_options.py
|
||||
../sqlalchemy/orm/instrumentation.py
|
||||
../sqlalchemy/connectors/pyodbc.py
|
||||
../sqlalchemy/connectors/__init__.py
|
||||
../sqlalchemy/connectors/zxJDBC.py
|
||||
../sqlalchemy/connectors/mysqldb.py
|
||||
../sqlalchemy/connectors/mxodbc.py
|
||||
../sqlalchemy/databases/__init__.py
|
||||
../sqlalchemy/__pycache__/log.cpython-34.pyc
|
||||
../sqlalchemy/databases/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/engines.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/schema.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/pickleable.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/fixtures.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/assertsql.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/config.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/warnings.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/distutils_run.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/requirements.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/runner.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/assertions.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/profiling.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/mock.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/exclusions.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/util.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/entities.cpython-34.pyc
|
||||
../sqlalchemy/testing/plugin/__pycache__/noseplugin.cpython-34.pyc
|
||||
../sqlalchemy/testing/plugin/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/testing/plugin/__pycache__/pytestplugin.cpython-34.pyc
|
||||
../sqlalchemy/testing/plugin/__pycache__/plugin_base.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_insert.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_results.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_select.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_sequence.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_types.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_update_delete.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_reflection.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_ddl.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/persistence.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/interfaces.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/events.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/path_registry.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/descriptor_props.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/identity.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/evaluator.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/exc.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/properties.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/relationships.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/collections.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/strategy_options.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/dynamic.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/attributes.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/mapper.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/state.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/sync.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/loading.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/strategies.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/unitofwork.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/query.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/instrumentation.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/session.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/deprecated_interfaces.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/scoping.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/dependency.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/util.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/default_comparator.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/sqltypes.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/functions.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/schema.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/ddl.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/elements.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/compiler.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/annotation.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/dml.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/expression.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/operators.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/selectable.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/visitors.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/type_api.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/naming.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/util.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/serializer.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/associationproxy.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/automap.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/hybrid.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/compiler.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/horizontal_shard.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/orderinglist.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/instrumentation.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/mutable.cpython-34.pyc
|
||||
../sqlalchemy/ext/declarative/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/ext/declarative/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/ext/declarative/__pycache__/clsregistry.cpython-34.pyc
|
||||
../sqlalchemy/ext/declarative/__pycache__/api.cpython-34.pyc
|
||||
../sqlalchemy/util/__pycache__/langhelpers.cpython-34.pyc
|
||||
../sqlalchemy/util/__pycache__/queue.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/inspection.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/interfaces.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/types.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/pool.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/schema.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/exc.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/events.cpython-34.pyc
|
||||
../sqlalchemy/__pycache__/processors.cpython-34.pyc
|
||||
../sqlalchemy/util/__pycache__/compat.cpython-34.pyc
|
||||
../sqlalchemy/util/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/util/__pycache__/deprecations.cpython-34.pyc
|
||||
../sqlalchemy/util/__pycache__/_collections.cpython-34.pyc
|
||||
../sqlalchemy/util/__pycache__/topological.cpython-34.pyc
|
||||
../sqlalchemy/connectors/__pycache__/mxodbc.cpython-34.pyc
|
||||
../sqlalchemy/connectors/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/connectors/__pycache__/pyodbc.cpython-34.pyc
|
||||
../sqlalchemy/connectors/__pycache__/mysqldb.cpython-34.pyc
|
||||
../sqlalchemy/connectors/__pycache__/zxJDBC.cpython-34.pyc
|
||||
../sqlalchemy/dialects/__pycache__/postgres.cpython-34.pyc
|
||||
../sqlalchemy/dialects/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/adodbapi.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/mxodbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/information_schema.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/pyodbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/zxjdbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/pymssql.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/pg8000.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/ranges.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/zxjdbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/json.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/pypostgresql.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/constraints.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/hstore.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/psycopg2.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sybase/__pycache__/mxodbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sybase/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sybase/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sybase/__pycache__/pyodbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sybase/__pycache__/pysybase.cpython-34.pyc
|
||||
../sqlalchemy/dialects/drizzle/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/drizzle/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/drizzle/__pycache__/mysqldb.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/mysqlconnector.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/pyodbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/zxjdbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/oursql.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/pymysql.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/cymysql.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/gaerdbms.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/mysqldb.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sqlite/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sqlite/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sqlite/__pycache__/pysqlite.cpython-34.pyc
|
||||
../sqlalchemy/dialects/firebird/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/firebird/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/firebird/__pycache__/fdb.cpython-34.pyc
|
||||
../sqlalchemy/dialects/firebird/__pycache__/kinterbasdb.cpython-34.pyc
|
||||
../sqlalchemy/dialects/oracle/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/oracle/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/oracle/__pycache__/zxjdbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/oracle/__pycache__/cx_oracle.cpython-34.pyc
|
||||
../sqlalchemy/util/__pycache__/queue.cpython-34.pyc
|
||||
../sqlalchemy/util/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/util/__pycache__/langhelpers.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/horizontal_shard.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/serializer.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/automap.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/associationproxy.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/hybrid.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/mutable.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/orderinglist.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/compiler.cpython-34.pyc
|
||||
../sqlalchemy/ext/__pycache__/instrumentation.cpython-34.pyc
|
||||
../sqlalchemy/ext/declarative/__pycache__/api.cpython-34.pyc
|
||||
../sqlalchemy/ext/declarative/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/ext/declarative/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/ext/declarative/__pycache__/clsregistry.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/api.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/registry.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/legacy.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/attr.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/type_api.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/ddl.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/selectable.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/util.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/sqltypes.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/functions.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/operators.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/dml.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/naming.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/expression.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/schema.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/default_comparator.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/visitors.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/compiler.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/elements.cpython-34.pyc
|
||||
../sqlalchemy/sql/__pycache__/annotation.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/default.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/url.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/util.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/interfaces.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/result.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/url.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/threadlocal.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/default.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/strategies.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/threadlocal.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/reflection.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/util.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/attr.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/registry.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/legacy.cpython-34.pyc
|
||||
../sqlalchemy/event/__pycache__/api.cpython-34.pyc
|
||||
../sqlalchemy/engine/__pycache__/strategies.cpython-34.pyc
|
||||
../sqlalchemy/dialects/__pycache__/postgres.cpython-34.pyc
|
||||
../sqlalchemy/dialects/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/mysqlconnector.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/pymysql.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/cymysql.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/oursql.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/pyodbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/zxjdbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/gaerdbms.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mysql/__pycache__/mysqldb.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/pg8000.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/hstore.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/pypostgresql.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/psycopg2.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/ranges.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/json.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/zxjdbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/postgresql/__pycache__/constraints.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sybase/__pycache__/pyodbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sybase/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sybase/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sybase/__pycache__/mxodbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sybase/__pycache__/pysybase.cpython-34.pyc
|
||||
../sqlalchemy/dialects/firebird/__pycache__/fdb.cpython-34.pyc
|
||||
../sqlalchemy/dialects/firebird/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/firebird/__pycache__/kinterbasdb.cpython-34.pyc
|
||||
../sqlalchemy/dialects/firebird/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sqlite/__pycache__/pysqlite.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sqlite/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/sqlite/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/information_schema.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/pymssql.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/adodbapi.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/pyodbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/zxjdbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/mssql/__pycache__/mxodbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/drizzle/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/drizzle/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/dialects/drizzle/__pycache__/mysqldb.cpython-34.pyc
|
||||
../sqlalchemy/dialects/oracle/__pycache__/cx_oracle.cpython-34.pyc
|
||||
../sqlalchemy/dialects/oracle/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/dialects/oracle/__pycache__/zxjdbc.cpython-34.pyc
|
||||
../sqlalchemy/dialects/oracle/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/profiling.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/warnings.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/engines.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/util.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/entities.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/mock.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/exclusions.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/assertions.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/distutils_run.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/fixtures.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/pickleable.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/schema.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/runner.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/config.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/requirements.cpython-34.pyc
|
||||
../sqlalchemy/testing/__pycache__/assertsql.cpython-34.pyc
|
||||
../sqlalchemy/testing/plugin/__pycache__/pytestplugin.cpython-34.pyc
|
||||
../sqlalchemy/testing/plugin/__pycache__/plugin_base.cpython-34.pyc
|
||||
../sqlalchemy/testing/plugin/__pycache__/noseplugin.cpython-34.pyc
|
||||
../sqlalchemy/testing/plugin/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_types.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_select.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_ddl.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_reflection.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_sequence.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_results.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_insert.cpython-34.pyc
|
||||
../sqlalchemy/testing/suite/__pycache__/test_update_delete.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/state.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/session.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/unitofwork.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/properties.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/collections.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/identity.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/util.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/sync.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/interfaces.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/path_registry.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/evaluator.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/deprecated_interfaces.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/mapper.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/persistence.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/dynamic.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/scoping.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/descriptor_props.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/loading.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/base.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/exc.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/events.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/strategies.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/query.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/dependency.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/attributes.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/relationships.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/strategy_options.cpython-34.pyc
|
||||
../sqlalchemy/orm/__pycache__/instrumentation.cpython-34.pyc
|
||||
../sqlalchemy/connectors/__pycache__/pyodbc.cpython-34.pyc
|
||||
../sqlalchemy/connectors/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/connectors/__pycache__/zxJDBC.cpython-34.pyc
|
||||
../sqlalchemy/connectors/__pycache__/mysqldb.cpython-34.pyc
|
||||
../sqlalchemy/connectors/__pycache__/mxodbc.cpython-34.pyc
|
||||
../sqlalchemy/databases/__pycache__/__init__.cpython-34.pyc
|
||||
../sqlalchemy/cprocessors.cpython-34m.so
|
||||
../sqlalchemy/cresultproxy.cpython-34m.so
|
||||
../sqlalchemy/cutils.cpython-34m.so
|
||||
./
|
||||
SOURCES.txt
|
||||
dependency_links.txt
|
||||
PKG-INFO
|
||||
SOURCES.txt
|
||||
top_level.txt
|
||||
|
|
Binary file not shown.
|
@ -1,28 +0,0 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: cffi
|
||||
Version: 0.8.6
|
||||
Summary: Foreign Function Interface for Python calling C code.
|
||||
Home-page: http://cffi.readthedocs.org
|
||||
Author: Armin Rigo, Maciej Fijalkowski
|
||||
Author-email: python-cffi@googlegroups.com
|
||||
License: MIT
|
||||
Description:
|
||||
CFFI
|
||||
====
|
||||
|
||||
Foreign Function Interface for Python calling C code.
|
||||
Please see the `Documentation <http://cffi.readthedocs.org/>`_.
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
`Mailing list <https://groups.google.com/forum/#!forum/python-cffi>`_
|
||||
|
||||
Platform: UNKNOWN
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.2
|
||||
Classifier: Programming Language :: Python :: 3.3
|
|
@ -1,104 +0,0 @@
|
|||
LICENSE
|
||||
MANIFEST.in
|
||||
setup.cfg
|
||||
setup.py
|
||||
setup_base.py
|
||||
c/_cffi_backend.c
|
||||
c/file_emulator.h
|
||||
c/malloc_closure.h
|
||||
c/minibuffer.h
|
||||
c/misc_thread.h
|
||||
c/misc_win32.h
|
||||
c/test_c.py
|
||||
c/wchar_helper.h
|
||||
c/libffi_msvc/ffi.c
|
||||
c/libffi_msvc/ffi.h
|
||||
c/libffi_msvc/ffi_common.h
|
||||
c/libffi_msvc/fficonfig.h
|
||||
c/libffi_msvc/ffitarget.h
|
||||
c/libffi_msvc/prep_cif.c
|
||||
c/libffi_msvc/types.c
|
||||
c/libffi_msvc/win32.c
|
||||
c/libffi_msvc/win64.asm
|
||||
c/libffi_msvc/win64.obj
|
||||
cffi/__init__.py
|
||||
cffi/api.py
|
||||
cffi/backend_ctypes.py
|
||||
cffi/commontypes.py
|
||||
cffi/cparser.py
|
||||
cffi/ffiplatform.py
|
||||
cffi/gc_weakref.py
|
||||
cffi/lock.py
|
||||
cffi/model.py
|
||||
cffi/vengine_cpy.py
|
||||
cffi/vengine_gen.py
|
||||
cffi/verifier.py
|
||||
cffi.egg-info/PKG-INFO
|
||||
cffi.egg-info/SOURCES.txt
|
||||
cffi.egg-info/dependency_links.txt
|
||||
cffi.egg-info/not-zip-safe
|
||||
cffi.egg-info/requires.txt
|
||||
cffi.egg-info/top_level.txt
|
||||
demo/_curses.py
|
||||
demo/api.py
|
||||
demo/bsdopendirtype.py
|
||||
demo/btrfs-snap.py
|
||||
demo/cffi-cocoa.py
|
||||
demo/fastcsv.py
|
||||
demo/gmp.py
|
||||
demo/pwuid.py
|
||||
demo/py.cleanup
|
||||
demo/pyobj.py
|
||||
demo/readdir.py
|
||||
demo/readdir2.py
|
||||
demo/readdir_ctypes.py
|
||||
demo/setup.py
|
||||
demo/winclipboard.py
|
||||
demo/xclient.py
|
||||
doc/Makefile
|
||||
doc/design.rst
|
||||
doc/make.bat
|
||||
doc/source/conf.py
|
||||
doc/source/index.rst
|
||||
testing/__init__.py
|
||||
testing/backend_tests.py
|
||||
testing/callback_in_thread.py
|
||||
testing/support.py
|
||||
testing/test_cdata.py
|
||||
testing/test_ctypes.py
|
||||
testing/test_ffi_backend.py
|
||||
testing/test_function.py
|
||||
testing/test_model.py
|
||||
testing/test_ownlib.py
|
||||
testing/test_parsing.py
|
||||
testing/test_platform.py
|
||||
testing/test_unicode_literals.py
|
||||
testing/test_verify.py
|
||||
testing/test_verify2.py
|
||||
testing/test_version.py
|
||||
testing/test_vgen.py
|
||||
testing/test_vgen2.py
|
||||
testing/test_zdistutils.py
|
||||
testing/test_zintegration.py
|
||||
testing/udir.py
|
||||
testing/snippets/distutils_module/setup.py
|
||||
testing/snippets/distutils_module/snip_basic_verify.py
|
||||
testing/snippets/distutils_module/build/lib.linux-x86_64-2.7/snip_basic_verify.py
|
||||
testing/snippets/distutils_package_1/setup.py
|
||||
testing/snippets/distutils_package_1/build/lib.linux-x86_64-2.7/snip_basic_verify1/__init__.py
|
||||
testing/snippets/distutils_package_1/snip_basic_verify1/__init__.py
|
||||
testing/snippets/distutils_package_2/setup.py
|
||||
testing/snippets/distutils_package_2/build/lib.linux-x86_64-2.7/snip_basic_verify2/__init__.py
|
||||
testing/snippets/distutils_package_2/snip_basic_verify2/__init__.py
|
||||
testing/snippets/infrastructure/setup.py
|
||||
testing/snippets/infrastructure/build/lib.linux-x86_64-2.7/snip_infrastructure/__init__.py
|
||||
testing/snippets/infrastructure/snip_infrastructure/__init__.py
|
||||
testing/snippets/setuptools_module/setup.py
|
||||
testing/snippets/setuptools_module/snip_setuptools_verify.py
|
||||
testing/snippets/setuptools_module/build/lib.linux-x86_64-2.7/snip_setuptools_verify.py
|
||||
testing/snippets/setuptools_package_1/setup.py
|
||||
testing/snippets/setuptools_package_1/build/lib.linux-x86_64-2.7/snip_setuptools_verify1/__init__.py
|
||||
testing/snippets/setuptools_package_1/snip_setuptools_verify1/__init__.py
|
||||
testing/snippets/setuptools_package_2/setup.py
|
||||
testing/snippets/setuptools_package_2/build/lib.linux-x86_64-2.7/snip_setuptools_verify2/__init__.py
|
||||
testing/snippets/setuptools_package_2/snip_setuptools_verify2/__init__.py
|
|
@ -1,32 +0,0 @@
|
|||
../cffi/lock.py
|
||||
../cffi/backend_ctypes.py
|
||||
../cffi/__init__.py
|
||||
../cffi/ffiplatform.py
|
||||
../cffi/vengine_gen.py
|
||||
../cffi/commontypes.py
|
||||
../cffi/vengine_cpy.py
|
||||
../cffi/api.py
|
||||
../cffi/gc_weakref.py
|
||||
../cffi/verifier.py
|
||||
../cffi/cparser.py
|
||||
../cffi/model.py
|
||||
../cffi/__pycache__/lock.cpython-34.pyc
|
||||
../cffi/__pycache__/backend_ctypes.cpython-34.pyc
|
||||
../cffi/__pycache__/__init__.cpython-34.pyc
|
||||
../cffi/__pycache__/ffiplatform.cpython-34.pyc
|
||||
../cffi/__pycache__/vengine_gen.cpython-34.pyc
|
||||
../cffi/__pycache__/commontypes.cpython-34.pyc
|
||||
../cffi/__pycache__/vengine_cpy.cpython-34.pyc
|
||||
../cffi/__pycache__/api.cpython-34.pyc
|
||||
../cffi/__pycache__/gc_weakref.cpython-34.pyc
|
||||
../cffi/__pycache__/verifier.cpython-34.pyc
|
||||
../cffi/__pycache__/cparser.cpython-34.pyc
|
||||
../cffi/__pycache__/model.cpython-34.pyc
|
||||
../_cffi_backend.cpython-34m.so
|
||||
./
|
||||
dependency_links.txt
|
||||
PKG-INFO
|
||||
SOURCES.txt
|
||||
not-zip-safe
|
||||
top_level.txt
|
||||
requires.txt
|
|
@ -1 +0,0 @@
|
|||
pycparser
|
|
@ -1,2 +0,0 @@
|
|||
_cffi_backend
|
||||
cffi
|
|
@ -1,8 +0,0 @@
|
|||
__all__ = ['FFI', 'VerificationError', 'VerificationMissing', 'CDefError',
|
||||
'FFIError']
|
||||
|
||||
from .api import FFI, CDefError, FFIError
|
||||
from .ffiplatform import VerificationError, VerificationMissing
|
||||
|
||||
__version__ = "0.8.6"
|
||||
__version_info__ = (0, 8, 6)
|
|
@ -1,497 +0,0 @@
|
|||
import sys, types
|
||||
from .lock import allocate_lock
|
||||
|
||||
try:
|
||||
callable
|
||||
except NameError:
|
||||
# Python 3.1
|
||||
from collections import Callable
|
||||
callable = lambda x: isinstance(x, Callable)
|
||||
|
||||
try:
|
||||
basestring
|
||||
except NameError:
|
||||
# Python 3.x
|
||||
basestring = str
|
||||
|
||||
|
||||
class FFIError(Exception):
|
||||
pass
|
||||
|
||||
class CDefError(Exception):
|
||||
def __str__(self):
|
||||
try:
|
||||
line = 'line %d: ' % (self.args[1].coord.line,)
|
||||
except (AttributeError, TypeError, IndexError):
|
||||
line = ''
|
||||
return '%s%s' % (line, self.args[0])
|
||||
|
||||
|
||||
class FFI(object):
|
||||
r'''
|
||||
The main top-level class that you instantiate once, or once per module.
|
||||
|
||||
Example usage:
|
||||
|
||||
ffi = FFI()
|
||||
ffi.cdef("""
|
||||
int printf(const char *, ...);
|
||||
""")
|
||||
|
||||
C = ffi.dlopen(None) # standard library
|
||||
-or-
|
||||
C = ffi.verify() # use a C compiler: verify the decl above is right
|
||||
|
||||
C.printf("hello, %s!\n", ffi.new("char[]", "world"))
|
||||
'''
|
||||
|
||||
def __init__(self, backend=None):
|
||||
"""Create an FFI instance. The 'backend' argument is used to
|
||||
select a non-default backend, mostly for tests.
|
||||
"""
|
||||
from . import cparser, model
|
||||
if backend is None:
|
||||
# You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with
|
||||
# _cffi_backend.so compiled.
|
||||
import _cffi_backend as backend
|
||||
from . import __version__
|
||||
assert backend.__version__ == __version__
|
||||
# (If you insist you can also try to pass the option
|
||||
# 'backend=backend_ctypes.CTypesBackend()', but don't
|
||||
# rely on it! It's probably not going to work well.)
|
||||
|
||||
self._backend = backend
|
||||
self._lock = allocate_lock()
|
||||
self._parser = cparser.Parser()
|
||||
self._cached_btypes = {}
|
||||
self._parsed_types = types.ModuleType('parsed_types').__dict__
|
||||
self._new_types = types.ModuleType('new_types').__dict__
|
||||
self._function_caches = []
|
||||
self._libraries = []
|
||||
self._cdefsources = []
|
||||
if hasattr(backend, 'set_ffi'):
|
||||
backend.set_ffi(self)
|
||||
for name in backend.__dict__:
|
||||
if name.startswith('RTLD_'):
|
||||
setattr(self, name, getattr(backend, name))
|
||||
#
|
||||
with self._lock:
|
||||
self.BVoidP = self._get_cached_btype(model.voidp_type)
|
||||
if isinstance(backend, types.ModuleType):
|
||||
# _cffi_backend: attach these constants to the class
|
||||
if not hasattr(FFI, 'NULL'):
|
||||
FFI.NULL = self.cast(self.BVoidP, 0)
|
||||
FFI.CData, FFI.CType = backend._get_types()
|
||||
else:
|
||||
# ctypes backend: attach these constants to the instance
|
||||
self.NULL = self.cast(self.BVoidP, 0)
|
||||
self.CData, self.CType = backend._get_types()
|
||||
|
||||
def cdef(self, csource, override=False, packed=False):
|
||||
"""Parse the given C source. This registers all declared functions,
|
||||
types, and global variables. The functions and global variables can
|
||||
then be accessed via either 'ffi.dlopen()' or 'ffi.verify()'.
|
||||
The types can be used in 'ffi.new()' and other functions.
|
||||
If 'packed' is specified as True, all structs declared inside this
|
||||
cdef are packed, i.e. laid out without any field alignment at all.
|
||||
"""
|
||||
if not isinstance(csource, str): # unicode, on Python 2
|
||||
if not isinstance(csource, basestring):
|
||||
raise TypeError("cdef() argument must be a string")
|
||||
csource = csource.encode('ascii')
|
||||
with self._lock:
|
||||
self._parser.parse(csource, override=override, packed=packed)
|
||||
self._cdefsources.append(csource)
|
||||
if override:
|
||||
for cache in self._function_caches:
|
||||
cache.clear()
|
||||
|
||||
def dlopen(self, name, flags=0):
|
||||
"""Load and return a dynamic library identified by 'name'.
|
||||
The standard C library can be loaded by passing None.
|
||||
Note that functions and types declared by 'ffi.cdef()' are not
|
||||
linked to a particular library, just like C headers; in the
|
||||
library we only look for the actual (untyped) symbols.
|
||||
"""
|
||||
assert isinstance(name, basestring) or name is None
|
||||
with self._lock:
|
||||
lib, function_cache = _make_ffi_library(self, name, flags)
|
||||
self._function_caches.append(function_cache)
|
||||
self._libraries.append(lib)
|
||||
return lib
|
||||
|
||||
def _typeof_locked(self, cdecl):
|
||||
# call me with the lock!
|
||||
key = cdecl
|
||||
if key in self._parsed_types:
|
||||
return self._parsed_types[key]
|
||||
#
|
||||
if not isinstance(cdecl, str): # unicode, on Python 2
|
||||
cdecl = cdecl.encode('ascii')
|
||||
#
|
||||
type = self._parser.parse_type(cdecl)
|
||||
really_a_function_type = type.is_raw_function
|
||||
if really_a_function_type:
|
||||
type = type.as_function_pointer()
|
||||
btype = self._get_cached_btype(type)
|
||||
result = btype, really_a_function_type
|
||||
self._parsed_types[key] = result
|
||||
return result
|
||||
|
||||
def _typeof(self, cdecl, consider_function_as_funcptr=False):
|
||||
# string -> ctype object
|
||||
try:
|
||||
result = self._parsed_types[cdecl]
|
||||
except KeyError:
|
||||
with self._lock:
|
||||
result = self._typeof_locked(cdecl)
|
||||
#
|
||||
btype, really_a_function_type = result
|
||||
if really_a_function_type and not consider_function_as_funcptr:
|
||||
raise CDefError("the type %r is a function type, not a "
|
||||
"pointer-to-function type" % (cdecl,))
|
||||
return btype
|
||||
|
||||
def typeof(self, cdecl):
|
||||
"""Parse the C type given as a string and return the
|
||||
corresponding <ctype> object.
|
||||
It can also be used on 'cdata' instance to get its C type.
|
||||
"""
|
||||
if isinstance(cdecl, basestring):
|
||||
return self._typeof(cdecl)
|
||||
if isinstance(cdecl, self.CData):
|
||||
return self._backend.typeof(cdecl)
|
||||
if isinstance(cdecl, types.BuiltinFunctionType):
|
||||
res = _builtin_function_type(cdecl)
|
||||
if res is not None:
|
||||
return res
|
||||
if (isinstance(cdecl, types.FunctionType)
|
||||
and hasattr(cdecl, '_cffi_base_type')):
|
||||
with self._lock:
|
||||
return self._get_cached_btype(cdecl._cffi_base_type)
|
||||
raise TypeError(type(cdecl))
|
||||
|
||||
def sizeof(self, cdecl):
|
||||
"""Return the size in bytes of the argument. It can be a
|
||||
string naming a C type, or a 'cdata' instance.
|
||||
"""
|
||||
if isinstance(cdecl, basestring):
|
||||
BType = self._typeof(cdecl)
|
||||
return self._backend.sizeof(BType)
|
||||
else:
|
||||
return self._backend.sizeof(cdecl)
|
||||
|
||||
def alignof(self, cdecl):
|
||||
"""Return the natural alignment size in bytes of the C type
|
||||
given as a string.
|
||||
"""
|
||||
if isinstance(cdecl, basestring):
|
||||
cdecl = self._typeof(cdecl)
|
||||
return self._backend.alignof(cdecl)
|
||||
|
||||
def offsetof(self, cdecl, fieldname):
|
||||
"""Return the offset of the named field inside the given
|
||||
structure, which must be given as a C type name.
|
||||
"""
|
||||
if isinstance(cdecl, basestring):
|
||||
cdecl = self._typeof(cdecl)
|
||||
return self._backend.typeoffsetof(cdecl, fieldname)[1]
|
||||
|
||||
def new(self, cdecl, init=None):
|
||||
"""Allocate an instance according to the specified C type and
|
||||
return a pointer to it. The specified C type must be either a
|
||||
pointer or an array: ``new('X *')`` allocates an X and returns
|
||||
a pointer to it, whereas ``new('X[n]')`` allocates an array of
|
||||
n X'es and returns an array referencing it (which works
|
||||
mostly like a pointer, like in C). You can also use
|
||||
``new('X[]', n)`` to allocate an array of a non-constant
|
||||
length n.
|
||||
|
||||
The memory is initialized following the rules of declaring a
|
||||
global variable in C: by default it is zero-initialized, but
|
||||
an explicit initializer can be given which can be used to
|
||||
fill all or part of the memory.
|
||||
|
||||
When the returned <cdata> object goes out of scope, the memory
|
||||
is freed. In other words the returned <cdata> object has
|
||||
ownership of the value of type 'cdecl' that it points to. This
|
||||
means that the raw data can be used as long as this object is
|
||||
kept alive, but must not be used for a longer time. Be careful
|
||||
about that when copying the pointer to the memory somewhere
|
||||
else, e.g. into another structure.
|
||||
"""
|
||||
if isinstance(cdecl, basestring):
|
||||
cdecl = self._typeof(cdecl)
|
||||
return self._backend.newp(cdecl, init)
|
||||
|
||||
def cast(self, cdecl, source):
|
||||
"""Similar to a C cast: returns an instance of the named C
|
||||
type initialized with the given 'source'. The source is
|
||||
casted between integers or pointers of any type.
|
||||
"""
|
||||
if isinstance(cdecl, basestring):
|
||||
cdecl = self._typeof(cdecl)
|
||||
return self._backend.cast(cdecl, source)
|
||||
|
||||
def string(self, cdata, maxlen=-1):
|
||||
"""Return a Python string (or unicode string) from the 'cdata'.
|
||||
If 'cdata' is a pointer or array of characters or bytes, returns
|
||||
the null-terminated string. The returned string extends until
|
||||
the first null character, or at most 'maxlen' characters. If
|
||||
'cdata' is an array then 'maxlen' defaults to its length.
|
||||
|
||||
If 'cdata' is a pointer or array of wchar_t, returns a unicode
|
||||
string following the same rules.
|
||||
|
||||
If 'cdata' is a single character or byte or a wchar_t, returns
|
||||
it as a string or unicode string.
|
||||
|
||||
If 'cdata' is an enum, returns the value of the enumerator as a
|
||||
string, or 'NUMBER' if the value is out of range.
|
||||
"""
|
||||
return self._backend.string(cdata, maxlen)
|
||||
|
||||
def buffer(self, cdata, size=-1):
|
||||
"""Return a read-write buffer object that references the raw C data
|
||||
pointed to by the given 'cdata'. The 'cdata' must be a pointer or
|
||||
an array. Can be passed to functions expecting a buffer, or directly
|
||||
manipulated with:
|
||||
|
||||
buf[:] get a copy of it in a regular string, or
|
||||
buf[idx] as a single character
|
||||
buf[:] = ...
|
||||
buf[idx] = ... change the content
|
||||
"""
|
||||
return self._backend.buffer(cdata, size)
|
||||
|
||||
def callback(self, cdecl, python_callable=None, error=None):
|
||||
"""Return a callback object or a decorator making such a
|
||||
callback object. 'cdecl' must name a C function pointer type.
|
||||
The callback invokes the specified 'python_callable' (which may
|
||||
be provided either directly or via a decorator). Important: the
|
||||
callback object must be manually kept alive for as long as the
|
||||
callback may be invoked from the C level.
|
||||
"""
|
||||
def callback_decorator_wrap(python_callable):
|
||||
if not callable(python_callable):
|
||||
raise TypeError("the 'python_callable' argument "
|
||||
"is not callable")
|
||||
return self._backend.callback(cdecl, python_callable, error)
|
||||
if isinstance(cdecl, basestring):
|
||||
cdecl = self._typeof(cdecl, consider_function_as_funcptr=True)
|
||||
if python_callable is None:
|
||||
return callback_decorator_wrap # decorator mode
|
||||
else:
|
||||
return callback_decorator_wrap(python_callable) # direct mode
|
||||
|
||||
def getctype(self, cdecl, replace_with=''):
|
||||
"""Return a string giving the C type 'cdecl', which may be itself
|
||||
a string or a <ctype> object. If 'replace_with' is given, it gives
|
||||
extra text to append (or insert for more complicated C types), like
|
||||
a variable name, or '*' to get actually the C type 'pointer-to-cdecl'.
|
||||
"""
|
||||
if isinstance(cdecl, basestring):
|
||||
cdecl = self._typeof(cdecl)
|
||||
replace_with = replace_with.strip()
|
||||
if (replace_with.startswith('*')
|
||||
and '&[' in self._backend.getcname(cdecl, '&')):
|
||||
replace_with = '(%s)' % replace_with
|
||||
elif replace_with and not replace_with[0] in '[(':
|
||||
replace_with = ' ' + replace_with
|
||||
return self._backend.getcname(cdecl, replace_with)
|
||||
|
||||
def gc(self, cdata, destructor):
|
||||
"""Return a new cdata object that points to the same
|
||||
data. Later, when this new cdata object is garbage-collected,
|
||||
'destructor(old_cdata_object)' will be called.
|
||||
"""
|
||||
with self._lock:
|
||||
try:
|
||||
gc_weakrefs = self.gc_weakrefs
|
||||
except AttributeError:
|
||||
from .gc_weakref import GcWeakrefs
|
||||
gc_weakrefs = self.gc_weakrefs = GcWeakrefs(self)
|
||||
return gc_weakrefs.build(cdata, destructor)
|
||||
|
||||
def _get_cached_btype(self, type):
|
||||
assert self._lock.acquire(False) is False
|
||||
# call me with the lock!
|
||||
try:
|
||||
BType = self._cached_btypes[type]
|
||||
except KeyError:
|
||||
finishlist = []
|
||||
BType = type.get_cached_btype(self, finishlist)
|
||||
for type in finishlist:
|
||||
type.finish_backend_type(self, finishlist)
|
||||
return BType
|
||||
|
||||
def verify(self, source='', tmpdir=None, **kwargs):
|
||||
"""Verify that the current ffi signatures compile on this
|
||||
machine, and return a dynamic library object. The dynamic
|
||||
library can be used to call functions and access global
|
||||
variables declared in this 'ffi'. The library is compiled
|
||||
by the C compiler: it gives you C-level API compatibility
|
||||
(including calling macros). This is unlike 'ffi.dlopen()',
|
||||
which requires binary compatibility in the signatures.
|
||||
"""
|
||||
from .verifier import Verifier, _caller_dir_pycache
|
||||
tmpdir = tmpdir or _caller_dir_pycache()
|
||||
self.verifier = Verifier(self, source, tmpdir, **kwargs)
|
||||
lib = self.verifier.load_library()
|
||||
self._libraries.append(lib)
|
||||
return lib
|
||||
|
||||
def _get_errno(self):
|
||||
return self._backend.get_errno()
|
||||
def _set_errno(self, errno):
|
||||
self._backend.set_errno(errno)
|
||||
errno = property(_get_errno, _set_errno, None,
|
||||
"the value of 'errno' from/to the C calls")
|
||||
|
||||
def getwinerror(self, code=-1):
|
||||
return self._backend.getwinerror(code)
|
||||
|
||||
def _pointer_to(self, ctype):
|
||||
from . import model
|
||||
with self._lock:
|
||||
return model.pointer_cache(self, ctype)
|
||||
|
||||
def addressof(self, cdata, field=None):
|
||||
"""Return the address of a <cdata 'struct-or-union'>.
|
||||
If 'field' is specified, return the address of this field.
|
||||
"""
|
||||
ctype = self._backend.typeof(cdata)
|
||||
ctype, offset = self._backend.typeoffsetof(ctype, field)
|
||||
ctypeptr = self._pointer_to(ctype)
|
||||
return self._backend.rawaddressof(ctypeptr, cdata, offset)
|
||||
|
||||
def include(self, ffi_to_include):
|
||||
"""Includes the typedefs, structs, unions and enums defined
|
||||
in another FFI instance. Usage is similar to a #include in C,
|
||||
where a part of the program might include types defined in
|
||||
another part for its own usage. Note that the include()
|
||||
method has no effect on functions, constants and global
|
||||
variables, which must anyway be accessed directly from the
|
||||
lib object returned by the original FFI instance.
|
||||
"""
|
||||
with ffi_to_include._lock:
|
||||
with self._lock:
|
||||
self._parser.include(ffi_to_include._parser)
|
||||
self._cdefsources.append('[')
|
||||
self._cdefsources.extend(ffi_to_include._cdefsources)
|
||||
self._cdefsources.append(']')
|
||||
|
||||
def new_handle(self, x):
|
||||
return self._backend.newp_handle(self.BVoidP, x)
|
||||
|
||||
def from_handle(self, x):
|
||||
return self._backend.from_handle(x)
|
||||
|
||||
|
||||
def _load_backend_lib(backend, name, flags):
|
||||
if name is None:
|
||||
if sys.platform != "win32":
|
||||
return backend.load_library(None, flags)
|
||||
name = "c" # Windows: load_library(None) fails, but this works
|
||||
# (backward compatibility hack only)
|
||||
try:
|
||||
if '.' not in name and '/' not in name:
|
||||
raise OSError("library not found: %r" % (name,))
|
||||
return backend.load_library(name, flags)
|
||||
except OSError:
|
||||
import ctypes.util
|
||||
path = ctypes.util.find_library(name)
|
||||
if path is None:
|
||||
raise # propagate the original OSError
|
||||
return backend.load_library(path, flags)
|
||||
|
||||
def _make_ffi_library(ffi, libname, flags):
|
||||
import os
|
||||
backend = ffi._backend
|
||||
backendlib = _load_backend_lib(backend, libname, flags)
|
||||
copied_enums = []
|
||||
#
|
||||
def make_accessor_locked(name):
|
||||
key = 'function ' + name
|
||||
if key in ffi._parser._declarations:
|
||||
tp = ffi._parser._declarations[key]
|
||||
BType = ffi._get_cached_btype(tp)
|
||||
try:
|
||||
value = backendlib.load_function(BType, name)
|
||||
except KeyError as e:
|
||||
raise AttributeError('%s: %s' % (name, e))
|
||||
library.__dict__[name] = value
|
||||
return
|
||||
#
|
||||
key = 'variable ' + name
|
||||
if key in ffi._parser._declarations:
|
||||
tp = ffi._parser._declarations[key]
|
||||
BType = ffi._get_cached_btype(tp)
|
||||
read_variable = backendlib.read_variable
|
||||
write_variable = backendlib.write_variable
|
||||
setattr(FFILibrary, name, property(
|
||||
lambda self: read_variable(BType, name),
|
||||
lambda self, value: write_variable(BType, name, value)))
|
||||
return
|
||||
#
|
||||
if not copied_enums:
|
||||
from . import model
|
||||
for key, tp in ffi._parser._declarations.items():
|
||||
if not isinstance(tp, model.EnumType):
|
||||
continue
|
||||
for enumname, enumval in zip(tp.enumerators, tp.enumvalues):
|
||||
if enumname not in library.__dict__:
|
||||
library.__dict__[enumname] = enumval
|
||||
for key, val in ffi._parser._int_constants.items():
|
||||
if key not in library.__dict__:
|
||||
library.__dict__[key] = val
|
||||
|
||||
copied_enums.append(True)
|
||||
if name in library.__dict__:
|
||||
return
|
||||
#
|
||||
raise AttributeError(name)
|
||||
#
|
||||
def make_accessor(name):
|
||||
with ffi._lock:
|
||||
if name in library.__dict__ or name in FFILibrary.__dict__:
|
||||
return # added by another thread while waiting for the lock
|
||||
make_accessor_locked(name)
|
||||
#
|
||||
class FFILibrary(object):
|
||||
def __getattr__(self, name):
|
||||
make_accessor(name)
|
||||
return getattr(self, name)
|
||||
def __setattr__(self, name, value):
|
||||
try:
|
||||
property = getattr(self.__class__, name)
|
||||
except AttributeError:
|
||||
make_accessor(name)
|
||||
setattr(self, name, value)
|
||||
else:
|
||||
property.__set__(self, value)
|
||||
#
|
||||
if libname is not None:
|
||||
try:
|
||||
if not isinstance(libname, str): # unicode, on Python 2
|
||||
libname = libname.encode('utf-8')
|
||||
FFILibrary.__name__ = 'FFILibrary_%s' % libname
|
||||
except UnicodeError:
|
||||
pass
|
||||
library = FFILibrary()
|
||||
return library, library.__dict__
|
||||
|
||||
def _builtin_function_type(func):
|
||||
# a hack to make at least ffi.typeof(builtin_function) work,
|
||||
# if the builtin function was obtained by 'vengine_cpy'.
|
||||
import sys
|
||||
try:
|
||||
module = sys.modules[func.__module__]
|
||||
ffi = module._cffi_original_ffi
|
||||
types_of_builtin_funcs = module._cffi_types_of_builtin_funcs
|
||||
tp = types_of_builtin_funcs[func]
|
||||
except (KeyError, AttributeError, TypeError):
|
||||
return None
|
||||
else:
|
||||
with ffi._lock:
|
||||
return ffi._get_cached_btype(tp)
|
File diff suppressed because it is too large
Load diff
|
@ -1,248 +0,0 @@
|
|||
import sys
|
||||
from . import api, model
|
||||
|
||||
|
||||
COMMON_TYPES = {
|
||||
'FILE': model.unknown_type('FILE', '_IO_FILE'),
|
||||
'bool': '_Bool',
|
||||
}
|
||||
|
||||
for _type in model.PrimitiveType.ALL_PRIMITIVE_TYPES:
|
||||
if _type.endswith('_t'):
|
||||
COMMON_TYPES[_type] = _type
|
||||
del _type
|
||||
|
||||
_CACHE = {}
|
||||
|
||||
def resolve_common_type(commontype):
|
||||
try:
|
||||
return _CACHE[commontype]
|
||||
except KeyError:
|
||||
result = COMMON_TYPES.get(commontype, commontype)
|
||||
if not isinstance(result, str):
|
||||
pass # result is already a BaseType
|
||||
elif result.endswith(' *'):
|
||||
if result.startswith('const '):
|
||||
result = model.ConstPointerType(
|
||||
resolve_common_type(result[6:-2]))
|
||||
else:
|
||||
result = model.PointerType(resolve_common_type(result[:-2]))
|
||||
elif result in model.PrimitiveType.ALL_PRIMITIVE_TYPES:
|
||||
result = model.PrimitiveType(result)
|
||||
else:
|
||||
if commontype == result:
|
||||
raise api.FFIError("Unsupported type: %r. Please file a bug "
|
||||
"if you think it should be." % (commontype,))
|
||||
result = resolve_common_type(result) # recursively
|
||||
assert isinstance(result, model.BaseTypeByIdentity)
|
||||
_CACHE[commontype] = result
|
||||
return result
|
||||
|
||||
|
||||
# ____________________________________________________________
|
||||
# Windows common types
|
||||
|
||||
|
||||
def win_common_types(maxsize):
|
||||
result = {}
|
||||
if maxsize < (1<<32):
|
||||
result.update({ # Windows 32-bits
|
||||
'HALF_PTR': 'short',
|
||||
'INT_PTR': 'int',
|
||||
'LONG_PTR': 'long',
|
||||
'UHALF_PTR': 'unsigned short',
|
||||
'UINT_PTR': 'unsigned int',
|
||||
'ULONG_PTR': 'unsigned long',
|
||||
})
|
||||
else:
|
||||
result.update({ # Windows 64-bits
|
||||
'HALF_PTR': 'int',
|
||||
'INT_PTR': 'long long',
|
||||
'LONG_PTR': 'long long',
|
||||
'UHALF_PTR': 'unsigned int',
|
||||
'UINT_PTR': 'unsigned long long',
|
||||
'ULONG_PTR': 'unsigned long long',
|
||||
})
|
||||
result.update({
|
||||
"BYTE": "unsigned char",
|
||||
"BOOL": "int",
|
||||
"CCHAR": "char",
|
||||
"CHAR": "char",
|
||||
"DWORD": "unsigned long",
|
||||
"DWORD32": "unsigned int",
|
||||
"DWORD64": "unsigned long long",
|
||||
"FLOAT": "float",
|
||||
"INT": "int",
|
||||
"INT8": "signed char",
|
||||
"INT16": "short",
|
||||
"INT32": "int",
|
||||
"INT64": "long long",
|
||||
"LONG": "long",
|
||||
"LONGLONG": "long long",
|
||||
"LONG32": "int",
|
||||
"LONG64": "long long",
|
||||
"WORD": "unsigned short",
|
||||
"PVOID": model.voidp_type,
|
||||
"ULONGLONG": "unsigned long long",
|
||||
"WCHAR": "wchar_t",
|
||||
"SHORT": "short",
|
||||
"TBYTE": "WCHAR",
|
||||
"TCHAR": "WCHAR",
|
||||
"UCHAR": "unsigned char",
|
||||
"UINT": "unsigned int",
|
||||
"UINT8": "unsigned char",
|
||||
"UINT16": "unsigned short",
|
||||
"UINT32": "unsigned int",
|
||||
"UINT64": "unsigned long long",
|
||||
"ULONG": "unsigned long",
|
||||
"ULONG32": "unsigned int",
|
||||
"ULONG64": "unsigned long long",
|
||||
"USHORT": "unsigned short",
|
||||
|
||||
"SIZE_T": "ULONG_PTR",
|
||||
"SSIZE_T": "LONG_PTR",
|
||||
"ATOM": "WORD",
|
||||
"BOOLEAN": "BYTE",
|
||||
"COLORREF": "DWORD",
|
||||
|
||||
"HANDLE": "PVOID",
|
||||
"DWORDLONG": "ULONGLONG",
|
||||
"DWORD_PTR": "ULONG_PTR",
|
||||
"HACCEL": "HANDLE",
|
||||
|
||||
"HBITMAP": "HANDLE",
|
||||
"HBRUSH": "HANDLE",
|
||||
"HCOLORSPACE": "HANDLE",
|
||||
"HCONV": "HANDLE",
|
||||
"HCONVLIST": "HANDLE",
|
||||
"HDC": "HANDLE",
|
||||
"HDDEDATA": "HANDLE",
|
||||
"HDESK": "HANDLE",
|
||||
"HDROP": "HANDLE",
|
||||
"HDWP": "HANDLE",
|
||||
"HENHMETAFILE": "HANDLE",
|
||||
"HFILE": "int",
|
||||
"HFONT": "HANDLE",
|
||||
"HGDIOBJ": "HANDLE",
|
||||
"HGLOBAL": "HANDLE",
|
||||
"HHOOK": "HANDLE",
|
||||
"HICON": "HANDLE",
|
||||
"HCURSOR": "HICON",
|
||||
"HINSTANCE": "HANDLE",
|
||||
"HKEY": "HANDLE",
|
||||
"HKL": "HANDLE",
|
||||
"HLOCAL": "HANDLE",
|
||||
"HMENU": "HANDLE",
|
||||
"HMETAFILE": "HANDLE",
|
||||
"HMODULE": "HINSTANCE",
|
||||
"HMONITOR": "HANDLE",
|
||||
"HPALETTE": "HANDLE",
|
||||
"HPEN": "HANDLE",
|
||||
"HRESULT": "LONG",
|
||||
"HRGN": "HANDLE",
|
||||
"HRSRC": "HANDLE",
|
||||
"HSZ": "HANDLE",
|
||||
"WINSTA": "HANDLE",
|
||||
"HWND": "HANDLE",
|
||||
|
||||
"LANGID": "WORD",
|
||||
"LCID": "DWORD",
|
||||
"LCTYPE": "DWORD",
|
||||
"LGRPID": "DWORD",
|
||||
"LPARAM": "LONG_PTR",
|
||||
"LPBOOL": "BOOL *",
|
||||
"LPBYTE": "BYTE *",
|
||||
"LPCOLORREF": "DWORD *",
|
||||
"LPCSTR": "const char *",
|
||||
|
||||
"LPCVOID": model.const_voidp_type,
|
||||
"LPCWSTR": "const WCHAR *",
|
||||
"LPCTSTR": "LPCWSTR",
|
||||
"LPDWORD": "DWORD *",
|
||||
"LPHANDLE": "HANDLE *",
|
||||
"LPINT": "int *",
|
||||
"LPLONG": "long *",
|
||||
"LPSTR": "CHAR *",
|
||||
"LPWSTR": "WCHAR *",
|
||||
"LPTSTR": "LPWSTR",
|
||||
"LPVOID": model.voidp_type,
|
||||
"LPWORD": "WORD *",
|
||||
"LRESULT": "LONG_PTR",
|
||||
"PBOOL": "BOOL *",
|
||||
"PBOOLEAN": "BOOLEAN *",
|
||||
"PBYTE": "BYTE *",
|
||||
"PCHAR": "CHAR *",
|
||||
"PCSTR": "const CHAR *",
|
||||
"PCTSTR": "LPCWSTR",
|
||||
"PCWSTR": "const WCHAR *",
|
||||
"PDWORD": "DWORD *",
|
||||
"PDWORDLONG": "DWORDLONG *",
|
||||
"PDWORD_PTR": "DWORD_PTR *",
|
||||
"PDWORD32": "DWORD32 *",
|
||||
"PDWORD64": "DWORD64 *",
|
||||
"PFLOAT": "FLOAT *",
|
||||
"PHALF_PTR": "HALF_PTR *",
|
||||
"PHANDLE": "HANDLE *",
|
||||
"PHKEY": "HKEY *",
|
||||
"PINT": "int *",
|
||||
"PINT_PTR": "INT_PTR *",
|
||||
"PINT8": "INT8 *",
|
||||
"PINT16": "INT16 *",
|
||||
"PINT32": "INT32 *",
|
||||
"PINT64": "INT64 *",
|
||||
"PLCID": "PDWORD",
|
||||
"PLONG": "LONG *",
|
||||
"PLONGLONG": "LONGLONG *",
|
||||
"PLONG_PTR": "LONG_PTR *",
|
||||
"PLONG32": "LONG32 *",
|
||||
"PLONG64": "LONG64 *",
|
||||
"PSHORT": "SHORT *",
|
||||
"PSIZE_T": "SIZE_T *",
|
||||
"PSSIZE_T": "SSIZE_T *",
|
||||
"PSTR": "CHAR *",
|
||||
"PTBYTE": "TBYTE *",
|
||||
"PTCHAR": "TCHAR *",
|
||||
"PTSTR": "LPWSTR",
|
||||
"PUCHAR": "UCHAR *",
|
||||
"PUHALF_PTR": "UHALF_PTR *",
|
||||
"PUINT": "UINT *",
|
||||
"PUINT_PTR": "UINT_PTR *",
|
||||
"PUINT8": "UINT8 *",
|
||||
"PUINT16": "UINT16 *",
|
||||
"PUINT32": "UINT32 *",
|
||||
"PUINT64": "UINT64 *",
|
||||
"PULONG": "ULONG *",
|
||||
"PULONGLONG": "ULONGLONG *",
|
||||
"PULONG_PTR": "ULONG_PTR *",
|
||||
"PULONG32": "ULONG32 *",
|
||||
"PULONG64": "ULONG64 *",
|
||||
"PUSHORT": "USHORT *",
|
||||
"PWCHAR": "WCHAR *",
|
||||
"PWORD": "WORD *",
|
||||
"PWSTR": "WCHAR *",
|
||||
"QWORD": "unsigned long long",
|
||||
"SC_HANDLE": "HANDLE",
|
||||
"SC_LOCK": "LPVOID",
|
||||
"SERVICE_STATUS_HANDLE": "HANDLE",
|
||||
|
||||
"UNICODE_STRING": model.StructType(
|
||||
"_UNICODE_STRING",
|
||||
["Length",
|
||||
"MaximumLength",
|
||||
"Buffer"],
|
||||
[model.PrimitiveType("unsigned short"),
|
||||
model.PrimitiveType("unsigned short"),
|
||||
model.PointerType(model.PrimitiveType("wchar_t"))],
|
||||
[-1, -1, -1]),
|
||||
"PUNICODE_STRING": "UNICODE_STRING *",
|
||||
"PCUNICODE_STRING": "const UNICODE_STRING *",
|
||||
|
||||
"USN": "LONGLONG",
|
||||
"VOID": model.void_type,
|
||||
"WPARAM": "UINT_PTR",
|
||||
})
|
||||
return result
|
||||
|
||||
|
||||
if sys.platform == 'win32':
|
||||
COMMON_TYPES.update(win_common_types(sys.maxsize))
|
|
@ -1,584 +0,0 @@
|
|||
|
||||
from . import api, model
|
||||
from .commontypes import COMMON_TYPES, resolve_common_type
|
||||
try:
|
||||
from . import _pycparser as pycparser
|
||||
except ImportError:
|
||||
import pycparser
|
||||
import weakref, re, sys
|
||||
|
||||
try:
|
||||
if sys.version_info < (3,):
|
||||
import thread as _thread
|
||||
else:
|
||||
import _thread
|
||||
lock = _thread.allocate_lock()
|
||||
except ImportError:
|
||||
lock = None
|
||||
|
||||
_r_comment = re.compile(r"/\*.*?\*/|//.*?$", re.DOTALL | re.MULTILINE)
|
||||
_r_define = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)\s+(.*?)$",
|
||||
re.MULTILINE)
|
||||
_r_partial_enum = re.compile(r"=\s*\.\.\.\s*[,}]|\.\.\.\s*\}")
|
||||
_r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$")
|
||||
_r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]")
|
||||
_r_words = re.compile(r"\w+|\S")
|
||||
_parser_cache = None
|
||||
_r_int_literal = re.compile(r"^0?x?[0-9a-f]+u?l?$", re.IGNORECASE)
|
||||
|
||||
def _get_parser():
|
||||
global _parser_cache
|
||||
if _parser_cache is None:
|
||||
_parser_cache = pycparser.CParser()
|
||||
return _parser_cache
|
||||
|
||||
def _preprocess(csource):
|
||||
# Remove comments. NOTE: this only work because the cdef() section
|
||||
# should not contain any string literal!
|
||||
csource = _r_comment.sub(' ', csource)
|
||||
# Remove the "#define FOO x" lines
|
||||
macros = {}
|
||||
for match in _r_define.finditer(csource):
|
||||
macroname, macrovalue = match.groups()
|
||||
macros[macroname] = macrovalue
|
||||
csource = _r_define.sub('', csource)
|
||||
# Replace "[...]" with "[__dotdotdotarray__]"
|
||||
csource = _r_partial_array.sub('[__dotdotdotarray__]', csource)
|
||||
# Replace "...}" with "__dotdotdotNUM__}". This construction should
|
||||
# occur only at the end of enums; at the end of structs we have "...;}"
|
||||
# and at the end of vararg functions "...);". Also replace "=...[,}]"
|
||||
# with ",__dotdotdotNUM__[,}]": this occurs in the enums too, when
|
||||
# giving an unknown value.
|
||||
matches = list(_r_partial_enum.finditer(csource))
|
||||
for number, match in enumerate(reversed(matches)):
|
||||
p = match.start()
|
||||
if csource[p] == '=':
|
||||
p2 = csource.find('...', p, match.end())
|
||||
assert p2 > p
|
||||
csource = '%s,__dotdotdot%d__ %s' % (csource[:p], number,
|
||||
csource[p2+3:])
|
||||
else:
|
||||
assert csource[p:p+3] == '...'
|
||||
csource = '%s __dotdotdot%d__ %s' % (csource[:p], number,
|
||||
csource[p+3:])
|
||||
# Replace all remaining "..." with the same name, "__dotdotdot__",
|
||||
# which is declared with a typedef for the purpose of C parsing.
|
||||
return csource.replace('...', ' __dotdotdot__ '), macros
|
||||
|
||||
def _common_type_names(csource):
|
||||
# Look in the source for what looks like usages of types from the
|
||||
# list of common types. A "usage" is approximated here as the
|
||||
# appearance of the word, minus a "definition" of the type, which
|
||||
# is the last word in a "typedef" statement. Approximative only
|
||||
# but should be fine for all the common types.
|
||||
look_for_words = set(COMMON_TYPES)
|
||||
look_for_words.add(';')
|
||||
look_for_words.add('typedef')
|
||||
words_used = set()
|
||||
is_typedef = False
|
||||
previous_word = ''
|
||||
for word in _r_words.findall(csource):
|
||||
if word in look_for_words:
|
||||
if word == ';':
|
||||
if is_typedef:
|
||||
words_used.discard(previous_word)
|
||||
look_for_words.discard(previous_word)
|
||||
is_typedef = False
|
||||
elif word == 'typedef':
|
||||
is_typedef = True
|
||||
else: # word in COMMON_TYPES
|
||||
words_used.add(word)
|
||||
previous_word = word
|
||||
return words_used
|
||||
|
||||
|
||||
class Parser(object):
|
||||
|
||||
def __init__(self):
|
||||
self._declarations = {}
|
||||
self._anonymous_counter = 0
|
||||
self._structnode2type = weakref.WeakKeyDictionary()
|
||||
self._override = False
|
||||
self._packed = False
|
||||
self._int_constants = {}
|
||||
|
||||
def _parse(self, csource):
|
||||
csource, macros = _preprocess(csource)
|
||||
# XXX: for more efficiency we would need to poke into the
|
||||
# internals of CParser... the following registers the
|
||||
# typedefs, because their presence or absence influences the
|
||||
# parsing itself (but what they are typedef'ed to plays no role)
|
||||
ctn = _common_type_names(csource)
|
||||
typenames = []
|
||||
for name in sorted(self._declarations):
|
||||
if name.startswith('typedef '):
|
||||
name = name[8:]
|
||||
typenames.append(name)
|
||||
ctn.discard(name)
|
||||
typenames += sorted(ctn)
|
||||
#
|
||||
csourcelines = ['typedef int %s;' % typename for typename in typenames]
|
||||
csourcelines.append('typedef int __dotdotdot__;')
|
||||
csourcelines.append(csource)
|
||||
csource = '\n'.join(csourcelines)
|
||||
if lock is not None:
|
||||
lock.acquire() # pycparser is not thread-safe...
|
||||
try:
|
||||
ast = _get_parser().parse(csource)
|
||||
except pycparser.c_parser.ParseError as e:
|
||||
self.convert_pycparser_error(e, csource)
|
||||
finally:
|
||||
if lock is not None:
|
||||
lock.release()
|
||||
# csource will be used to find buggy source text
|
||||
return ast, macros, csource
|
||||
|
||||
def _convert_pycparser_error(self, e, csource):
|
||||
# xxx look for ":NUM:" at the start of str(e) and try to interpret
|
||||
# it as a line number
|
||||
line = None
|
||||
msg = str(e)
|
||||
if msg.startswith(':') and ':' in msg[1:]:
|
||||
linenum = msg[1:msg.find(':',1)]
|
||||
if linenum.isdigit():
|
||||
linenum = int(linenum, 10)
|
||||
csourcelines = csource.splitlines()
|
||||
if 1 <= linenum <= len(csourcelines):
|
||||
line = csourcelines[linenum-1]
|
||||
return line
|
||||
|
||||
def convert_pycparser_error(self, e, csource):
|
||||
line = self._convert_pycparser_error(e, csource)
|
||||
|
||||
msg = str(e)
|
||||
if line:
|
||||
msg = 'cannot parse "%s"\n%s' % (line.strip(), msg)
|
||||
else:
|
||||
msg = 'parse error\n%s' % (msg,)
|
||||
raise api.CDefError(msg)
|
||||
|
||||
def parse(self, csource, override=False, packed=False):
|
||||
prev_override = self._override
|
||||
prev_packed = self._packed
|
||||
try:
|
||||
self._override = override
|
||||
self._packed = packed
|
||||
self._internal_parse(csource)
|
||||
finally:
|
||||
self._override = prev_override
|
||||
self._packed = prev_packed
|
||||
|
||||
def _internal_parse(self, csource):
|
||||
ast, macros, csource = self._parse(csource)
|
||||
# add the macros
|
||||
self._process_macros(macros)
|
||||
# find the first "__dotdotdot__" and use that as a separator
|
||||
# between the repeated typedefs and the real csource
|
||||
iterator = iter(ast.ext)
|
||||
for decl in iterator:
|
||||
if decl.name == '__dotdotdot__':
|
||||
break
|
||||
#
|
||||
try:
|
||||
for decl in iterator:
|
||||
if isinstance(decl, pycparser.c_ast.Decl):
|
||||
self._parse_decl(decl)
|
||||
elif isinstance(decl, pycparser.c_ast.Typedef):
|
||||
if not decl.name:
|
||||
raise api.CDefError("typedef does not declare any name",
|
||||
decl)
|
||||
if (isinstance(decl.type.type, pycparser.c_ast.IdentifierType)
|
||||
and decl.type.type.names == ['__dotdotdot__']):
|
||||
realtype = model.unknown_type(decl.name)
|
||||
elif (isinstance(decl.type, pycparser.c_ast.PtrDecl) and
|
||||
isinstance(decl.type.type, pycparser.c_ast.TypeDecl) and
|
||||
isinstance(decl.type.type.type,
|
||||
pycparser.c_ast.IdentifierType) and
|
||||
decl.type.type.type.names == ['__dotdotdot__']):
|
||||
realtype = model.unknown_ptr_type(decl.name)
|
||||
else:
|
||||
realtype = self._get_type(decl.type, name=decl.name)
|
||||
self._declare('typedef ' + decl.name, realtype)
|
||||
else:
|
||||
raise api.CDefError("unrecognized construct", decl)
|
||||
except api.FFIError as e:
|
||||
msg = self._convert_pycparser_error(e, csource)
|
||||
if msg:
|
||||
e.args = (e.args[0] + "\n *** Err: %s" % msg,)
|
||||
raise
|
||||
|
||||
def _add_constants(self, key, val):
|
||||
if key in self._int_constants:
|
||||
raise api.FFIError(
|
||||
"multiple declarations of constant: %s" % (key,))
|
||||
self._int_constants[key] = val
|
||||
|
||||
def _process_macros(self, macros):
|
||||
for key, value in macros.items():
|
||||
value = value.strip()
|
||||
match = _r_int_literal.search(value)
|
||||
if match is not None:
|
||||
int_str = match.group(0).lower().rstrip("ul")
|
||||
|
||||
# "010" is not valid oct in py3
|
||||
if (int_str.startswith("0") and
|
||||
int_str != "0" and
|
||||
not int_str.startswith("0x")):
|
||||
int_str = "0o" + int_str[1:]
|
||||
|
||||
pyvalue = int(int_str, 0)
|
||||
self._add_constants(key, pyvalue)
|
||||
elif value == '...':
|
||||
self._declare('macro ' + key, value)
|
||||
else:
|
||||
raise api.CDefError('only supports the syntax "#define '
|
||||
'%s ..." (literally) or "#define '
|
||||
'%s 0x1FF" for now' % (key, key))
|
||||
|
||||
def _parse_decl(self, decl):
|
||||
node = decl.type
|
||||
if isinstance(node, pycparser.c_ast.FuncDecl):
|
||||
tp = self._get_type(node, name=decl.name)
|
||||
assert isinstance(tp, model.RawFunctionType)
|
||||
tp = self._get_type_pointer(tp)
|
||||
self._declare('function ' + decl.name, tp)
|
||||
else:
|
||||
if isinstance(node, pycparser.c_ast.Struct):
|
||||
# XXX do we need self._declare in any of those?
|
||||
if node.decls is not None:
|
||||
self._get_struct_union_enum_type('struct', node)
|
||||
elif isinstance(node, pycparser.c_ast.Union):
|
||||
if node.decls is not None:
|
||||
self._get_struct_union_enum_type('union', node)
|
||||
elif isinstance(node, pycparser.c_ast.Enum):
|
||||
if node.values is not None:
|
||||
self._get_struct_union_enum_type('enum', node)
|
||||
elif not decl.name:
|
||||
raise api.CDefError("construct does not declare any variable",
|
||||
decl)
|
||||
#
|
||||
if decl.name:
|
||||
tp = self._get_type(node, partial_length_ok=True)
|
||||
if self._is_constant_globalvar(node):
|
||||
self._declare('constant ' + decl.name, tp)
|
||||
else:
|
||||
self._declare('variable ' + decl.name, tp)
|
||||
|
||||
def parse_type(self, cdecl):
|
||||
ast, macros = self._parse('void __dummy(\n%s\n);' % cdecl)[:2]
|
||||
assert not macros
|
||||
exprnode = ast.ext[-1].type.args.params[0]
|
||||
if isinstance(exprnode, pycparser.c_ast.ID):
|
||||
raise api.CDefError("unknown identifier '%s'" % (exprnode.name,))
|
||||
return self._get_type(exprnode.type)
|
||||
|
||||
def _declare(self, name, obj):
|
||||
if name in self._declarations:
|
||||
if self._declarations[name] is obj:
|
||||
return
|
||||
if not self._override:
|
||||
raise api.FFIError(
|
||||
"multiple declarations of %s (for interactive usage, "
|
||||
"try cdef(xx, override=True))" % (name,))
|
||||
assert '__dotdotdot__' not in name.split()
|
||||
self._declarations[name] = obj
|
||||
|
||||
def _get_type_pointer(self, type, const=False):
|
||||
if isinstance(type, model.RawFunctionType):
|
||||
return type.as_function_pointer()
|
||||
if const:
|
||||
return model.ConstPointerType(type)
|
||||
return model.PointerType(type)
|
||||
|
||||
def _get_type(self, typenode, name=None, partial_length_ok=False):
|
||||
# first, dereference typedefs, if we have it already parsed, we're good
|
||||
if (isinstance(typenode, pycparser.c_ast.TypeDecl) and
|
||||
isinstance(typenode.type, pycparser.c_ast.IdentifierType) and
|
||||
len(typenode.type.names) == 1 and
|
||||
('typedef ' + typenode.type.names[0]) in self._declarations):
|
||||
type = self._declarations['typedef ' + typenode.type.names[0]]
|
||||
return type
|
||||
#
|
||||
if isinstance(typenode, pycparser.c_ast.ArrayDecl):
|
||||
# array type
|
||||
if typenode.dim is None:
|
||||
length = None
|
||||
else:
|
||||
length = self._parse_constant(
|
||||
typenode.dim, partial_length_ok=partial_length_ok)
|
||||
return model.ArrayType(self._get_type(typenode.type), length)
|
||||
#
|
||||
if isinstance(typenode, pycparser.c_ast.PtrDecl):
|
||||
# pointer type
|
||||
const = (isinstance(typenode.type, pycparser.c_ast.TypeDecl)
|
||||
and 'const' in typenode.type.quals)
|
||||
return self._get_type_pointer(self._get_type(typenode.type), const)
|
||||
#
|
||||
if isinstance(typenode, pycparser.c_ast.TypeDecl):
|
||||
type = typenode.type
|
||||
if isinstance(type, pycparser.c_ast.IdentifierType):
|
||||
# assume a primitive type. get it from .names, but reduce
|
||||
# synonyms to a single chosen combination
|
||||
names = list(type.names)
|
||||
if names != ['signed', 'char']: # keep this unmodified
|
||||
prefixes = {}
|
||||
while names:
|
||||
name = names[0]
|
||||
if name in ('short', 'long', 'signed', 'unsigned'):
|
||||
prefixes[name] = prefixes.get(name, 0) + 1
|
||||
del names[0]
|
||||
else:
|
||||
break
|
||||
# ignore the 'signed' prefix below, and reorder the others
|
||||
newnames = []
|
||||
for prefix in ('unsigned', 'short', 'long'):
|
||||
for i in range(prefixes.get(prefix, 0)):
|
||||
newnames.append(prefix)
|
||||
if not names:
|
||||
names = ['int'] # implicitly
|
||||
if names == ['int']: # but kill it if 'short' or 'long'
|
||||
if 'short' in prefixes or 'long' in prefixes:
|
||||
names = []
|
||||
names = newnames + names
|
||||
ident = ' '.join(names)
|
||||
if ident == 'void':
|
||||
return model.void_type
|
||||
if ident == '__dotdotdot__':
|
||||
raise api.FFIError(':%d: bad usage of "..."' %
|
||||
typenode.coord.line)
|
||||
return resolve_common_type(ident)
|
||||
#
|
||||
if isinstance(type, pycparser.c_ast.Struct):
|
||||
# 'struct foobar'
|
||||
return self._get_struct_union_enum_type('struct', type, name)
|
||||
#
|
||||
if isinstance(type, pycparser.c_ast.Union):
|
||||
# 'union foobar'
|
||||
return self._get_struct_union_enum_type('union', type, name)
|
||||
#
|
||||
if isinstance(type, pycparser.c_ast.Enum):
|
||||
# 'enum foobar'
|
||||
return self._get_struct_union_enum_type('enum', type, name)
|
||||
#
|
||||
if isinstance(typenode, pycparser.c_ast.FuncDecl):
|
||||
# a function type
|
||||
return self._parse_function_type(typenode, name)
|
||||
#
|
||||
# nested anonymous structs or unions end up here
|
||||
if isinstance(typenode, pycparser.c_ast.Struct):
|
||||
return self._get_struct_union_enum_type('struct', typenode, name,
|
||||
nested=True)
|
||||
if isinstance(typenode, pycparser.c_ast.Union):
|
||||
return self._get_struct_union_enum_type('union', typenode, name,
|
||||
nested=True)
|
||||
#
|
||||
raise api.FFIError(":%d: bad or unsupported type declaration" %
|
||||
typenode.coord.line)
|
||||
|
||||
def _parse_function_type(self, typenode, funcname=None):
|
||||
params = list(getattr(typenode.args, 'params', []))
|
||||
ellipsis = (
|
||||
len(params) > 0 and
|
||||
isinstance(params[-1].type, pycparser.c_ast.TypeDecl) and
|
||||
isinstance(params[-1].type.type,
|
||||
pycparser.c_ast.IdentifierType) and
|
||||
params[-1].type.type.names == ['__dotdotdot__'])
|
||||
if ellipsis:
|
||||
params.pop()
|
||||
if not params:
|
||||
raise api.CDefError(
|
||||
"%s: a function with only '(...)' as argument"
|
||||
" is not correct C" % (funcname or 'in expression'))
|
||||
elif (len(params) == 1 and
|
||||
isinstance(params[0].type, pycparser.c_ast.TypeDecl) and
|
||||
isinstance(params[0].type.type, pycparser.c_ast.IdentifierType)
|
||||
and list(params[0].type.type.names) == ['void']):
|
||||
del params[0]
|
||||
args = [self._as_func_arg(self._get_type(argdeclnode.type))
|
||||
for argdeclnode in params]
|
||||
result = self._get_type(typenode.type)
|
||||
return model.RawFunctionType(tuple(args), result, ellipsis)
|
||||
|
||||
def _as_func_arg(self, type):
|
||||
if isinstance(type, model.ArrayType):
|
||||
return model.PointerType(type.item)
|
||||
elif isinstance(type, model.RawFunctionType):
|
||||
return type.as_function_pointer()
|
||||
else:
|
||||
return type
|
||||
|
||||
def _is_constant_globalvar(self, typenode):
|
||||
if isinstance(typenode, pycparser.c_ast.PtrDecl):
|
||||
return 'const' in typenode.quals
|
||||
if isinstance(typenode, pycparser.c_ast.TypeDecl):
|
||||
return 'const' in typenode.quals
|
||||
return False
|
||||
|
||||
def _get_struct_union_enum_type(self, kind, type, name=None, nested=False):
|
||||
# First, a level of caching on the exact 'type' node of the AST.
|
||||
# This is obscure, but needed because pycparser "unrolls" declarations
|
||||
# such as "typedef struct { } foo_t, *foo_p" and we end up with
|
||||
# an AST that is not a tree, but a DAG, with the "type" node of the
|
||||
# two branches foo_t and foo_p of the trees being the same node.
|
||||
# It's a bit silly but detecting "DAG-ness" in the AST tree seems
|
||||
# to be the only way to distinguish this case from two independent
|
||||
# structs. See test_struct_with_two_usages.
|
||||
try:
|
||||
return self._structnode2type[type]
|
||||
except KeyError:
|
||||
pass
|
||||
#
|
||||
# Note that this must handle parsing "struct foo" any number of
|
||||
# times and always return the same StructType object. Additionally,
|
||||
# one of these times (not necessarily the first), the fields of
|
||||
# the struct can be specified with "struct foo { ...fields... }".
|
||||
# If no name is given, then we have to create a new anonymous struct
|
||||
# with no caching; in this case, the fields are either specified
|
||||
# right now or never.
|
||||
#
|
||||
force_name = name
|
||||
name = type.name
|
||||
#
|
||||
# get the type or create it if needed
|
||||
if name is None:
|
||||
# 'force_name' is used to guess a more readable name for
|
||||
# anonymous structs, for the common case "typedef struct { } foo".
|
||||
if force_name is not None:
|
||||
explicit_name = '$%s' % force_name
|
||||
else:
|
||||
self._anonymous_counter += 1
|
||||
explicit_name = '$%d' % self._anonymous_counter
|
||||
tp = None
|
||||
else:
|
||||
explicit_name = name
|
||||
key = '%s %s' % (kind, name)
|
||||
tp = self._declarations.get(key, None)
|
||||
#
|
||||
if tp is None:
|
||||
if kind == 'struct':
|
||||
tp = model.StructType(explicit_name, None, None, None)
|
||||
elif kind == 'union':
|
||||
tp = model.UnionType(explicit_name, None, None, None)
|
||||
elif kind == 'enum':
|
||||
tp = self._build_enum_type(explicit_name, type.values)
|
||||
else:
|
||||
raise AssertionError("kind = %r" % (kind,))
|
||||
if name is not None:
|
||||
self._declare(key, tp)
|
||||
else:
|
||||
if kind == 'enum' and type.values is not None:
|
||||
raise NotImplementedError(
|
||||
"enum %s: the '{}' declaration should appear on the first "
|
||||
"time the enum is mentioned, not later" % explicit_name)
|
||||
if not tp.forcename:
|
||||
tp.force_the_name(force_name)
|
||||
if tp.forcename and '$' in tp.name:
|
||||
self._declare('anonymous %s' % tp.forcename, tp)
|
||||
#
|
||||
self._structnode2type[type] = tp
|
||||
#
|
||||
# enums: done here
|
||||
if kind == 'enum':
|
||||
return tp
|
||||
#
|
||||
# is there a 'type.decls'? If yes, then this is the place in the
|
||||
# C sources that declare the fields. If no, then just return the
|
||||
# existing type, possibly still incomplete.
|
||||
if type.decls is None:
|
||||
return tp
|
||||
#
|
||||
if tp.fldnames is not None:
|
||||
raise api.CDefError("duplicate declaration of struct %s" % name)
|
||||
fldnames = []
|
||||
fldtypes = []
|
||||
fldbitsize = []
|
||||
for decl in type.decls:
|
||||
if (isinstance(decl.type, pycparser.c_ast.IdentifierType) and
|
||||
''.join(decl.type.names) == '__dotdotdot__'):
|
||||
# XXX pycparser is inconsistent: 'names' should be a list
|
||||
# of strings, but is sometimes just one string. Use
|
||||
# str.join() as a way to cope with both.
|
||||
self._make_partial(tp, nested)
|
||||
continue
|
||||
if decl.bitsize is None:
|
||||
bitsize = -1
|
||||
else:
|
||||
bitsize = self._parse_constant(decl.bitsize)
|
||||
self._partial_length = False
|
||||
type = self._get_type(decl.type, partial_length_ok=True)
|
||||
if self._partial_length:
|
||||
self._make_partial(tp, nested)
|
||||
if isinstance(type, model.StructType) and type.partial:
|
||||
self._make_partial(tp, nested)
|
||||
fldnames.append(decl.name or '')
|
||||
fldtypes.append(type)
|
||||
fldbitsize.append(bitsize)
|
||||
tp.fldnames = tuple(fldnames)
|
||||
tp.fldtypes = tuple(fldtypes)
|
||||
tp.fldbitsize = tuple(fldbitsize)
|
||||
if fldbitsize != [-1] * len(fldbitsize):
|
||||
if isinstance(tp, model.StructType) and tp.partial:
|
||||
raise NotImplementedError("%s: using both bitfields and '...;'"
|
||||
% (tp,))
|
||||
tp.packed = self._packed
|
||||
return tp
|
||||
|
||||
def _make_partial(self, tp, nested):
|
||||
if not isinstance(tp, model.StructOrUnion):
|
||||
raise api.CDefError("%s cannot be partial" % (tp,))
|
||||
if not tp.has_c_name() and not nested:
|
||||
raise NotImplementedError("%s is partial but has no C name" %(tp,))
|
||||
tp.partial = True
|
||||
|
||||
def _parse_constant(self, exprnode, partial_length_ok=False):
|
||||
# for now, limited to expressions that are an immediate number
|
||||
# or negative number
|
||||
if isinstance(exprnode, pycparser.c_ast.Constant):
|
||||
return int(exprnode.value, 0)
|
||||
#
|
||||
if (isinstance(exprnode, pycparser.c_ast.UnaryOp) and
|
||||
exprnode.op == '-'):
|
||||
return -self._parse_constant(exprnode.expr)
|
||||
# load previously defined int constant
|
||||
if (isinstance(exprnode, pycparser.c_ast.ID) and
|
||||
exprnode.name in self._int_constants):
|
||||
return self._int_constants[exprnode.name]
|
||||
#
|
||||
if partial_length_ok:
|
||||
if (isinstance(exprnode, pycparser.c_ast.ID) and
|
||||
exprnode.name == '__dotdotdotarray__'):
|
||||
self._partial_length = True
|
||||
return '...'
|
||||
#
|
||||
raise api.FFIError(":%d: unsupported expression: expected a "
|
||||
"simple numeric constant" % exprnode.coord.line)
|
||||
|
||||
def _build_enum_type(self, explicit_name, decls):
|
||||
if decls is not None:
|
||||
enumerators1 = [enum.name for enum in decls.enumerators]
|
||||
enumerators = [s for s in enumerators1
|
||||
if not _r_enum_dotdotdot.match(s)]
|
||||
partial = len(enumerators) < len(enumerators1)
|
||||
enumerators = tuple(enumerators)
|
||||
enumvalues = []
|
||||
nextenumvalue = 0
|
||||
for enum in decls.enumerators[:len(enumerators)]:
|
||||
if enum.value is not None:
|
||||
nextenumvalue = self._parse_constant(enum.value)
|
||||
enumvalues.append(nextenumvalue)
|
||||
self._add_constants(enum.name, nextenumvalue)
|
||||
nextenumvalue += 1
|
||||
enumvalues = tuple(enumvalues)
|
||||
tp = model.EnumType(explicit_name, enumerators, enumvalues)
|
||||
tp.partial = partial
|
||||
else: # opaque enum
|
||||
tp = model.EnumType(explicit_name, (), ())
|
||||
return tp
|
||||
|
||||
def include(self, other):
|
||||
for name, tp in other._declarations.items():
|
||||
kind = name.split(' ', 1)[0]
|
||||
if kind in ('typedef', 'struct', 'union', 'enum'):
|
||||
self._declare(name, tp)
|
||||
for k, v in other._int_constants.items():
|
||||
self._add_constants(k, v)
|
|
@ -1,112 +0,0 @@
|
|||
import os
|
||||
|
||||
|
||||
class VerificationError(Exception):
|
||||
""" An error raised when verification fails
|
||||
"""
|
||||
|
||||
class VerificationMissing(Exception):
|
||||
""" An error raised when incomplete structures are passed into
|
||||
cdef, but no verification has been done
|
||||
"""
|
||||
|
||||
|
||||
def get_extension(srcfilename, modname, sources=(), **kwds):
|
||||
from distutils.core import Extension
|
||||
allsources = [srcfilename]
|
||||
allsources.extend(sources)
|
||||
return Extension(name=modname, sources=allsources, **kwds)
|
||||
|
||||
def compile(tmpdir, ext):
|
||||
"""Compile a C extension module using distutils."""
|
||||
|
||||
saved_environ = os.environ.copy()
|
||||
try:
|
||||
outputfilename = _build(tmpdir, ext)
|
||||
outputfilename = os.path.abspath(outputfilename)
|
||||
finally:
|
||||
# workaround for a distutils bugs where some env vars can
|
||||
# become longer and longer every time it is used
|
||||
for key, value in saved_environ.items():
|
||||
if os.environ.get(key) != value:
|
||||
os.environ[key] = value
|
||||
return outputfilename
|
||||
|
||||
def _build(tmpdir, ext):
|
||||
# XXX compact but horrible :-(
|
||||
from distutils.core import Distribution
|
||||
import distutils.errors
|
||||
#
|
||||
dist = Distribution({'ext_modules': [ext]})
|
||||
dist.parse_config_files()
|
||||
options = dist.get_option_dict('build_ext')
|
||||
options['force'] = ('ffiplatform', True)
|
||||
options['build_lib'] = ('ffiplatform', tmpdir)
|
||||
options['build_temp'] = ('ffiplatform', tmpdir)
|
||||
#
|
||||
try:
|
||||
dist.run_command('build_ext')
|
||||
except (distutils.errors.CompileError,
|
||||
distutils.errors.LinkError) as e:
|
||||
raise VerificationError('%s: %s' % (e.__class__.__name__, e))
|
||||
#
|
||||
cmd_obj = dist.get_command_obj('build_ext')
|
||||
[soname] = cmd_obj.get_outputs()
|
||||
return soname
|
||||
|
||||
try:
|
||||
from os.path import samefile
|
||||
except ImportError:
|
||||
def samefile(f1, f2):
|
||||
return os.path.abspath(f1) == os.path.abspath(f2)
|
||||
|
||||
def maybe_relative_path(path):
|
||||
if not os.path.isabs(path):
|
||||
return path # already relative
|
||||
dir = path
|
||||
names = []
|
||||
while True:
|
||||
prevdir = dir
|
||||
dir, name = os.path.split(prevdir)
|
||||
if dir == prevdir or not dir:
|
||||
return path # failed to make it relative
|
||||
names.append(name)
|
||||
try:
|
||||
if samefile(dir, os.curdir):
|
||||
names.reverse()
|
||||
return os.path.join(*names)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# ____________________________________________________________
|
||||
|
||||
try:
|
||||
int_or_long = (int, long)
|
||||
import cStringIO
|
||||
except NameError:
|
||||
int_or_long = int # Python 3
|
||||
import io as cStringIO
|
||||
|
||||
def _flatten(x, f):
|
||||
if isinstance(x, str):
|
||||
f.write('%ds%s' % (len(x), x))
|
||||
elif isinstance(x, dict):
|
||||
keys = sorted(x.keys())
|
||||
f.write('%dd' % len(keys))
|
||||
for key in keys:
|
||||
_flatten(key, f)
|
||||
_flatten(x[key], f)
|
||||
elif isinstance(x, (list, tuple)):
|
||||
f.write('%dl' % len(x))
|
||||
for value in x:
|
||||
_flatten(value, f)
|
||||
elif isinstance(x, int_or_long):
|
||||
f.write('%di' % (x,))
|
||||
else:
|
||||
raise TypeError(
|
||||
"the keywords to verify() contains unsupported object %r" % (x,))
|
||||
|
||||
def flatten(x):
|
||||
f = cStringIO.StringIO()
|
||||
_flatten(x, f)
|
||||
return f.getvalue()
|
|
@ -1,19 +0,0 @@
|
|||
from weakref import ref
|
||||
|
||||
|
||||
class GcWeakrefs(object):
|
||||
# code copied and adapted from WeakKeyDictionary.
|
||||
|
||||
def __init__(self, ffi):
|
||||
self.ffi = ffi
|
||||
self.data = data = {}
|
||||
def remove(k):
|
||||
destructor, cdata = data.pop(k)
|
||||
destructor(cdata)
|
||||
self.remove = remove
|
||||
|
||||
def build(self, cdata, destructor):
|
||||
# make a new cdata of the same type as the original one
|
||||
new_cdata = self.ffi.cast(self.ffi._backend.typeof(cdata), cdata)
|
||||
self.data[ref(new_cdata, self.remove)] = destructor, cdata
|
||||
return new_cdata
|
|
@ -1,30 +0,0 @@
|
|||
import sys
|
||||
|
||||
if sys.version_info < (3,):
|
||||
try:
|
||||
from thread import allocate_lock
|
||||
except ImportError:
|
||||
from dummy_thread import allocate_lock
|
||||
else:
|
||||
try:
|
||||
from _thread import allocate_lock
|
||||
except ImportError:
|
||||
from _dummy_thread import allocate_lock
|
||||
|
||||
|
||||
##import sys
|
||||
##l1 = allocate_lock
|
||||
|
||||
##class allocate_lock(object):
|
||||
## def __init__(self):
|
||||
## self._real = l1()
|
||||
## def __enter__(self):
|
||||
## for i in range(4, 0, -1):
|
||||
## print sys._getframe(i).f_code
|
||||
## print
|
||||
## return self._real.__enter__()
|
||||
## def __exit__(self, *args):
|
||||
## return self._real.__exit__(*args)
|
||||
## def acquire(self, f):
|
||||
## assert f is False
|
||||
## return self._real.acquire(f)
|
|
@ -1,499 +0,0 @@
|
|||
import types
|
||||
import weakref
|
||||
|
||||
from .lock import allocate_lock
|
||||
|
||||
|
||||
class BaseTypeByIdentity(object):
|
||||
is_array_type = False
|
||||
is_raw_function = False
|
||||
|
||||
def get_c_name(self, replace_with='', context='a C file'):
|
||||
result = self.c_name_with_marker
|
||||
assert result.count('&') == 1
|
||||
# some logic duplication with ffi.getctype()... :-(
|
||||
replace_with = replace_with.strip()
|
||||
if replace_with:
|
||||
if replace_with.startswith('*') and '&[' in result:
|
||||
replace_with = '(%s)' % replace_with
|
||||
elif not replace_with[0] in '[(':
|
||||
replace_with = ' ' + replace_with
|
||||
result = result.replace('&', replace_with)
|
||||
if '$' in result:
|
||||
from .ffiplatform import VerificationError
|
||||
raise VerificationError(
|
||||
"cannot generate '%s' in %s: unknown type name"
|
||||
% (self._get_c_name(), context))
|
||||
return result
|
||||
|
||||
def _get_c_name(self):
|
||||
return self.c_name_with_marker.replace('&', '')
|
||||
|
||||
def has_c_name(self):
|
||||
return '$' not in self._get_c_name()
|
||||
|
||||
def get_cached_btype(self, ffi, finishlist, can_delay=False):
|
||||
try:
|
||||
BType = ffi._cached_btypes[self]
|
||||
except KeyError:
|
||||
BType = self.build_backend_type(ffi, finishlist)
|
||||
BType2 = ffi._cached_btypes.setdefault(self, BType)
|
||||
assert BType2 is BType
|
||||
return BType
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s>' % (self._get_c_name(),)
|
||||
|
||||
def _get_items(self):
|
||||
return [(name, getattr(self, name)) for name in self._attrs_]
|
||||
|
||||
|
||||
class BaseType(BaseTypeByIdentity):
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.__class__ == other.__class__ and
|
||||
self._get_items() == other._get_items())
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.__class__, tuple(self._get_items())))
|
||||
|
||||
|
||||
class VoidType(BaseType):
|
||||
_attrs_ = ()
|
||||
|
||||
def __init__(self):
|
||||
self.c_name_with_marker = 'void&'
|
||||
|
||||
def build_backend_type(self, ffi, finishlist):
|
||||
return global_cache(self, ffi, 'new_void_type')
|
||||
|
||||
void_type = VoidType()
|
||||
|
||||
|
||||
class PrimitiveType(BaseType):
|
||||
_attrs_ = ('name',)
|
||||
|
||||
ALL_PRIMITIVE_TYPES = {
|
||||
'char': 'c',
|
||||
'short': 'i',
|
||||
'int': 'i',
|
||||
'long': 'i',
|
||||
'long long': 'i',
|
||||
'signed char': 'i',
|
||||
'unsigned char': 'i',
|
||||
'unsigned short': 'i',
|
||||
'unsigned int': 'i',
|
||||
'unsigned long': 'i',
|
||||
'unsigned long long': 'i',
|
||||
'float': 'f',
|
||||
'double': 'f',
|
||||
'long double': 'f',
|
||||
'_Bool': 'i',
|
||||
# the following types are not primitive in the C sense
|
||||
'wchar_t': 'c',
|
||||
'int8_t': 'i',
|
||||
'uint8_t': 'i',
|
||||
'int16_t': 'i',
|
||||
'uint16_t': 'i',
|
||||
'int32_t': 'i',
|
||||
'uint32_t': 'i',
|
||||
'int64_t': 'i',
|
||||
'uint64_t': 'i',
|
||||
'intptr_t': 'i',
|
||||
'uintptr_t': 'i',
|
||||
'ptrdiff_t': 'i',
|
||||
'size_t': 'i',
|
||||
'ssize_t': 'i',
|
||||
}
|
||||
|
||||
def __init__(self, name):
|
||||
assert name in self.ALL_PRIMITIVE_TYPES
|
||||
self.name = name
|
||||
self.c_name_with_marker = name + '&'
|
||||
|
||||
def is_char_type(self):
|
||||
return self.ALL_PRIMITIVE_TYPES[self.name] == 'c'
|
||||
def is_integer_type(self):
|
||||
return self.ALL_PRIMITIVE_TYPES[self.name] == 'i'
|
||||
def is_float_type(self):
|
||||
return self.ALL_PRIMITIVE_TYPES[self.name] == 'f'
|
||||
|
||||
def build_backend_type(self, ffi, finishlist):
|
||||
return global_cache(self, ffi, 'new_primitive_type', self.name)
|
||||
|
||||
|
||||
class BaseFunctionType(BaseType):
|
||||
_attrs_ = ('args', 'result', 'ellipsis')
|
||||
|
||||
def __init__(self, args, result, ellipsis):
|
||||
self.args = args
|
||||
self.result = result
|
||||
self.ellipsis = ellipsis
|
||||
#
|
||||
reprargs = [arg._get_c_name() for arg in self.args]
|
||||
if self.ellipsis:
|
||||
reprargs.append('...')
|
||||
reprargs = reprargs or ['void']
|
||||
replace_with = self._base_pattern % (', '.join(reprargs),)
|
||||
self.c_name_with_marker = (
|
||||
self.result.c_name_with_marker.replace('&', replace_with))
|
||||
|
||||
|
||||
class RawFunctionType(BaseFunctionType):
|
||||
# Corresponds to a C type like 'int(int)', which is the C type of
|
||||
# a function, but not a pointer-to-function. The backend has no
|
||||
# notion of such a type; it's used temporarily by parsing.
|
||||
_base_pattern = '(&)(%s)'
|
||||
is_raw_function = True
|
||||
|
||||
def build_backend_type(self, ffi, finishlist):
|
||||
from . import api
|
||||
raise api.CDefError("cannot render the type %r: it is a function "
|
||||
"type, not a pointer-to-function type" % (self,))
|
||||
|
||||
def as_function_pointer(self):
|
||||
return FunctionPtrType(self.args, self.result, self.ellipsis)
|
||||
|
||||
|
||||
class FunctionPtrType(BaseFunctionType):
|
||||
_base_pattern = '(*&)(%s)'
|
||||
|
||||
def build_backend_type(self, ffi, finishlist):
|
||||
result = self.result.get_cached_btype(ffi, finishlist)
|
||||
args = []
|
||||
for tp in self.args:
|
||||
args.append(tp.get_cached_btype(ffi, finishlist))
|
||||
return global_cache(self, ffi, 'new_function_type',
|
||||
tuple(args), result, self.ellipsis)
|
||||
|
||||
|
||||
class PointerType(BaseType):
|
||||
_attrs_ = ('totype',)
|
||||
_base_pattern = " *&"
|
||||
_base_pattern_array = "(*&)"
|
||||
|
||||
def __init__(self, totype):
|
||||
self.totype = totype
|
||||
if totype.is_array_type:
|
||||
extra = self._base_pattern_array
|
||||
else:
|
||||
extra = self._base_pattern
|
||||
self.c_name_with_marker = totype.c_name_with_marker.replace('&', extra)
|
||||
|
||||
def build_backend_type(self, ffi, finishlist):
|
||||
BItem = self.totype.get_cached_btype(ffi, finishlist, can_delay=True)
|
||||
return global_cache(self, ffi, 'new_pointer_type', BItem)
|
||||
|
||||
voidp_type = PointerType(void_type)
|
||||
|
||||
|
||||
class ConstPointerType(PointerType):
|
||||
_base_pattern = " const *&"
|
||||
_base_pattern_array = "(const *&)"
|
||||
|
||||
const_voidp_type = ConstPointerType(void_type)
|
||||
|
||||
|
||||
class NamedPointerType(PointerType):
|
||||
_attrs_ = ('totype', 'name')
|
||||
|
||||
def __init__(self, totype, name):
|
||||
PointerType.__init__(self, totype)
|
||||
self.name = name
|
||||
self.c_name_with_marker = name + '&'
|
||||
|
||||
|
||||
class ArrayType(BaseType):
|
||||
_attrs_ = ('item', 'length')
|
||||
is_array_type = True
|
||||
|
||||
def __init__(self, item, length):
|
||||
self.item = item
|
||||
self.length = length
|
||||
#
|
||||
if length is None:
|
||||
brackets = '&[]'
|
||||
elif length == '...':
|
||||
brackets = '&[/*...*/]'
|
||||
else:
|
||||
brackets = '&[%d]' % length
|
||||
self.c_name_with_marker = (
|
||||
self.item.c_name_with_marker.replace('&', brackets))
|
||||
|
||||
def resolve_length(self, newlength):
|
||||
return ArrayType(self.item, newlength)
|
||||
|
||||
def build_backend_type(self, ffi, finishlist):
|
||||
if self.length == '...':
|
||||
from . import api
|
||||
raise api.CDefError("cannot render the type %r: unknown length" %
|
||||
(self,))
|
||||
self.item.get_cached_btype(ffi, finishlist) # force the item BType
|
||||
BPtrItem = PointerType(self.item).get_cached_btype(ffi, finishlist)
|
||||
return global_cache(self, ffi, 'new_array_type', BPtrItem, self.length)
|
||||
|
||||
|
||||
class StructOrUnionOrEnum(BaseTypeByIdentity):
|
||||
_attrs_ = ('name',)
|
||||
forcename = None
|
||||
|
||||
def build_c_name_with_marker(self):
|
||||
name = self.forcename or '%s %s' % (self.kind, self.name)
|
||||
self.c_name_with_marker = name + '&'
|
||||
|
||||
def force_the_name(self, forcename):
|
||||
self.forcename = forcename
|
||||
self.build_c_name_with_marker()
|
||||
|
||||
def get_official_name(self):
|
||||
assert self.c_name_with_marker.endswith('&')
|
||||
return self.c_name_with_marker[:-1]
|
||||
|
||||
|
||||
class StructOrUnion(StructOrUnionOrEnum):
|
||||
fixedlayout = None
|
||||
completed = False
|
||||
partial = False
|
||||
packed = False
|
||||
|
||||
def __init__(self, name, fldnames, fldtypes, fldbitsize):
|
||||
self.name = name
|
||||
self.fldnames = fldnames
|
||||
self.fldtypes = fldtypes
|
||||
self.fldbitsize = fldbitsize
|
||||
self.build_c_name_with_marker()
|
||||
|
||||
def enumfields(self):
|
||||
for name, type, bitsize in zip(self.fldnames, self.fldtypes,
|
||||
self.fldbitsize):
|
||||
if name == '' and isinstance(type, StructOrUnion):
|
||||
# nested anonymous struct/union
|
||||
for result in type.enumfields():
|
||||
yield result
|
||||
else:
|
||||
yield (name, type, bitsize)
|
||||
|
||||
def force_flatten(self):
|
||||
# force the struct or union to have a declaration that lists
|
||||
# directly all fields returned by enumfields(), flattening
|
||||
# nested anonymous structs/unions.
|
||||
names = []
|
||||
types = []
|
||||
bitsizes = []
|
||||
for name, type, bitsize in self.enumfields():
|
||||
names.append(name)
|
||||
types.append(type)
|
||||
bitsizes.append(bitsize)
|
||||
self.fldnames = tuple(names)
|
||||
self.fldtypes = tuple(types)
|
||||
self.fldbitsize = tuple(bitsizes)
|
||||
|
||||
def get_cached_btype(self, ffi, finishlist, can_delay=False):
|
||||
BType = StructOrUnionOrEnum.get_cached_btype(self, ffi, finishlist,
|
||||
can_delay)
|
||||
if not can_delay:
|
||||
self.finish_backend_type(ffi, finishlist)
|
||||
return BType
|
||||
|
||||
def finish_backend_type(self, ffi, finishlist):
|
||||
if self.completed:
|
||||
if self.completed != 2:
|
||||
raise NotImplementedError("recursive structure declaration "
|
||||
"for '%s'" % (self.name,))
|
||||
return
|
||||
BType = ffi._cached_btypes[self]
|
||||
if self.fldtypes is None:
|
||||
return # not completing it: it's an opaque struct
|
||||
#
|
||||
self.completed = 1
|
||||
#
|
||||
if self.fixedlayout is None:
|
||||
fldtypes = [tp.get_cached_btype(ffi, finishlist)
|
||||
for tp in self.fldtypes]
|
||||
lst = list(zip(self.fldnames, fldtypes, self.fldbitsize))
|
||||
sflags = 0
|
||||
if self.packed:
|
||||
sflags = 8 # SF_PACKED
|
||||
ffi._backend.complete_struct_or_union(BType, lst, self,
|
||||
-1, -1, sflags)
|
||||
#
|
||||
else:
|
||||
fldtypes = []
|
||||
fieldofs, fieldsize, totalsize, totalalignment = self.fixedlayout
|
||||
for i in range(len(self.fldnames)):
|
||||
fsize = fieldsize[i]
|
||||
ftype = self.fldtypes[i]
|
||||
#
|
||||
if isinstance(ftype, ArrayType) and ftype.length == '...':
|
||||
# fix the length to match the total size
|
||||
BItemType = ftype.item.get_cached_btype(ffi, finishlist)
|
||||
nlen, nrest = divmod(fsize, ffi.sizeof(BItemType))
|
||||
if nrest != 0:
|
||||
self._verification_error(
|
||||
"field '%s.%s' has a bogus size?" % (
|
||||
self.name, self.fldnames[i] or '{}'))
|
||||
ftype = ftype.resolve_length(nlen)
|
||||
self.fldtypes = (self.fldtypes[:i] + (ftype,) +
|
||||
self.fldtypes[i+1:])
|
||||
#
|
||||
BFieldType = ftype.get_cached_btype(ffi, finishlist)
|
||||
if isinstance(ftype, ArrayType) and ftype.length is None:
|
||||
assert fsize == 0
|
||||
else:
|
||||
bitemsize = ffi.sizeof(BFieldType)
|
||||
if bitemsize != fsize:
|
||||
self._verification_error(
|
||||
"field '%s.%s' is declared as %d bytes, but is "
|
||||
"really %d bytes" % (self.name,
|
||||
self.fldnames[i] or '{}',
|
||||
bitemsize, fsize))
|
||||
fldtypes.append(BFieldType)
|
||||
#
|
||||
lst = list(zip(self.fldnames, fldtypes, self.fldbitsize, fieldofs))
|
||||
ffi._backend.complete_struct_or_union(BType, lst, self,
|
||||
totalsize, totalalignment)
|
||||
self.completed = 2
|
||||
|
||||
def _verification_error(self, msg):
|
||||
from .ffiplatform import VerificationError
|
||||
raise VerificationError(msg)
|
||||
|
||||
def check_not_partial(self):
|
||||
if self.partial and self.fixedlayout is None:
|
||||
from . import ffiplatform
|
||||
raise ffiplatform.VerificationMissing(self._get_c_name())
|
||||
|
||||
def build_backend_type(self, ffi, finishlist):
|
||||
self.check_not_partial()
|
||||
finishlist.append(self)
|
||||
#
|
||||
return global_cache(self, ffi, 'new_%s_type' % self.kind,
|
||||
self.get_official_name(), key=self)
|
||||
|
||||
|
||||
class StructType(StructOrUnion):
|
||||
kind = 'struct'
|
||||
|
||||
|
||||
class UnionType(StructOrUnion):
|
||||
kind = 'union'
|
||||
|
||||
|
||||
class EnumType(StructOrUnionOrEnum):
|
||||
kind = 'enum'
|
||||
partial = False
|
||||
partial_resolved = False
|
||||
|
||||
def __init__(self, name, enumerators, enumvalues, baseinttype=None):
|
||||
self.name = name
|
||||
self.enumerators = enumerators
|
||||
self.enumvalues = enumvalues
|
||||
self.baseinttype = baseinttype
|
||||
self.build_c_name_with_marker()
|
||||
|
||||
def force_the_name(self, forcename):
|
||||
StructOrUnionOrEnum.force_the_name(self, forcename)
|
||||
if self.forcename is None:
|
||||
name = self.get_official_name()
|
||||
self.forcename = '$' + name.replace(' ', '_')
|
||||
|
||||
def check_not_partial(self):
|
||||
if self.partial and not self.partial_resolved:
|
||||
from . import ffiplatform
|
||||
raise ffiplatform.VerificationMissing(self._get_c_name())
|
||||
|
||||
def build_backend_type(self, ffi, finishlist):
|
||||
self.check_not_partial()
|
||||
base_btype = self.build_baseinttype(ffi, finishlist)
|
||||
return global_cache(self, ffi, 'new_enum_type',
|
||||
self.get_official_name(),
|
||||
self.enumerators, self.enumvalues,
|
||||
base_btype, key=self)
|
||||
|
||||
def build_baseinttype(self, ffi, finishlist):
|
||||
if self.baseinttype is not None:
|
||||
return self.baseinttype.get_cached_btype(ffi, finishlist)
|
||||
#
|
||||
if self.enumvalues:
|
||||
smallest_value = min(self.enumvalues)
|
||||
largest_value = max(self.enumvalues)
|
||||
else:
|
||||
smallest_value = 0
|
||||
largest_value = 0
|
||||
if smallest_value < 0: # needs a signed type
|
||||
sign = 1
|
||||
candidate1 = PrimitiveType("int")
|
||||
candidate2 = PrimitiveType("long")
|
||||
else:
|
||||
sign = 0
|
||||
candidate1 = PrimitiveType("unsigned int")
|
||||
candidate2 = PrimitiveType("unsigned long")
|
||||
btype1 = candidate1.get_cached_btype(ffi, finishlist)
|
||||
btype2 = candidate2.get_cached_btype(ffi, finishlist)
|
||||
size1 = ffi.sizeof(btype1)
|
||||
size2 = ffi.sizeof(btype2)
|
||||
if (smallest_value >= ((-1) << (8*size1-1)) and
|
||||
largest_value < (1 << (8*size1-sign))):
|
||||
return btype1
|
||||
if (smallest_value >= ((-1) << (8*size2-1)) and
|
||||
largest_value < (1 << (8*size2-sign))):
|
||||
return btype2
|
||||
raise api.CDefError("%s values don't all fit into either 'long' "
|
||||
"or 'unsigned long'" % self._get_c_name())
|
||||
|
||||
def unknown_type(name, structname=None):
|
||||
if structname is None:
|
||||
structname = '$%s' % name
|
||||
tp = StructType(structname, None, None, None)
|
||||
tp.force_the_name(name)
|
||||
return tp
|
||||
|
||||
def unknown_ptr_type(name, structname=None):
|
||||
if structname is None:
|
||||
structname = '*$%s' % name
|
||||
tp = StructType(structname, None, None, None)
|
||||
return NamedPointerType(tp, name)
|
||||
|
||||
|
||||
global_lock = allocate_lock()
|
||||
|
||||
def global_cache(srctype, ffi, funcname, *args, **kwds):
|
||||
key = kwds.pop('key', (funcname, args))
|
||||
assert not kwds
|
||||
try:
|
||||
return ffi._backend.__typecache[key]
|
||||
except KeyError:
|
||||
pass
|
||||
except AttributeError:
|
||||
# initialize the __typecache attribute, either at the module level
|
||||
# if ffi._backend is a module, or at the class level if ffi._backend
|
||||
# is some instance.
|
||||
if isinstance(ffi._backend, types.ModuleType):
|
||||
ffi._backend.__typecache = weakref.WeakValueDictionary()
|
||||
else:
|
||||
type(ffi._backend).__typecache = weakref.WeakValueDictionary()
|
||||
try:
|
||||
res = getattr(ffi._backend, funcname)(*args)
|
||||
except NotImplementedError as e:
|
||||
raise NotImplementedError("%r: %s" % (srctype, e))
|
||||
# note that setdefault() on WeakValueDictionary is not atomic
|
||||
# and contains a rare bug (http://bugs.python.org/issue19542);
|
||||
# we have to use a lock and do it ourselves
|
||||
cache = ffi._backend.__typecache
|
||||
with global_lock:
|
||||
res1 = cache.get(key)
|
||||
if res1 is None:
|
||||
cache[key] = res
|
||||
return res
|
||||
else:
|
||||
return res1
|
||||
|
||||
def pointer_cache(ffi, BType):
|
||||
return global_cache('?', ffi, 'new_pointer_type', BType)
|
||||
|
||||
def attach_exception_info(e, name):
|
||||
if e.args and type(e.args[0]) is str:
|
||||
e.args = ('%s: %s' % (name, e.args[0]),) + e.args[1:]
|
|
@ -1,951 +0,0 @@
|
|||
import sys, imp
|
||||
from . import model, ffiplatform
|
||||
|
||||
|
||||
class VCPythonEngine(object):
|
||||
_class_key = 'x'
|
||||
_gen_python_module = True
|
||||
|
||||
def __init__(self, verifier):
|
||||
self.verifier = verifier
|
||||
self.ffi = verifier.ffi
|
||||
self._struct_pending_verification = {}
|
||||
self._types_of_builtin_functions = {}
|
||||
|
||||
def patch_extension_kwds(self, kwds):
|
||||
pass
|
||||
|
||||
def find_module(self, module_name, path, so_suffixes):
|
||||
try:
|
||||
f, filename, descr = imp.find_module(module_name, path)
|
||||
except ImportError:
|
||||
return None
|
||||
if f is not None:
|
||||
f.close()
|
||||
# Note that after a setuptools installation, there are both .py
|
||||
# and .so files with the same basename. The code here relies on
|
||||
# imp.find_module() locating the .so in priority.
|
||||
if descr[0] not in so_suffixes:
|
||||
return None
|
||||
return filename
|
||||
|
||||
def collect_types(self):
|
||||
self._typesdict = {}
|
||||
self._generate("collecttype")
|
||||
|
||||
def _prnt(self, what=''):
|
||||
self._f.write(what + '\n')
|
||||
|
||||
def _gettypenum(self, type):
|
||||
# a KeyError here is a bug. please report it! :-)
|
||||
return self._typesdict[type]
|
||||
|
||||
def _do_collect_type(self, tp):
|
||||
if ((not isinstance(tp, model.PrimitiveType)
|
||||
or tp.name == 'long double')
|
||||
and tp not in self._typesdict):
|
||||
num = len(self._typesdict)
|
||||
self._typesdict[tp] = num
|
||||
|
||||
def write_source_to_f(self):
|
||||
self.collect_types()
|
||||
#
|
||||
# The new module will have a _cffi_setup() function that receives
|
||||
# objects from the ffi world, and that calls some setup code in
|
||||
# the module. This setup code is split in several independent
|
||||
# functions, e.g. one per constant. The functions are "chained"
|
||||
# by ending in a tail call to each other.
|
||||
#
|
||||
# This is further split in two chained lists, depending on if we
|
||||
# can do it at import-time or if we must wait for _cffi_setup() to
|
||||
# provide us with the <ctype> objects. This is needed because we
|
||||
# need the values of the enum constants in order to build the
|
||||
# <ctype 'enum'> that we may have to pass to _cffi_setup().
|
||||
#
|
||||
# The following two 'chained_list_constants' items contains
|
||||
# the head of these two chained lists, as a string that gives the
|
||||
# call to do, if any.
|
||||
self._chained_list_constants = ['0', '0']
|
||||
#
|
||||
prnt = self._prnt
|
||||
# first paste some standard set of lines that are mostly '#define'
|
||||
prnt(cffimod_header)
|
||||
prnt()
|
||||
# then paste the C source given by the user, verbatim.
|
||||
prnt(self.verifier.preamble)
|
||||
prnt()
|
||||
#
|
||||
# call generate_cpy_xxx_decl(), for every xxx found from
|
||||
# ffi._parser._declarations. This generates all the functions.
|
||||
self._generate("decl")
|
||||
#
|
||||
# implement the function _cffi_setup_custom() as calling the
|
||||
# head of the chained list.
|
||||
self._generate_setup_custom()
|
||||
prnt()
|
||||
#
|
||||
# produce the method table, including the entries for the
|
||||
# generated Python->C function wrappers, which are done
|
||||
# by generate_cpy_function_method().
|
||||
prnt('static PyMethodDef _cffi_methods[] = {')
|
||||
self._generate("method")
|
||||
prnt(' {"_cffi_setup", _cffi_setup, METH_VARARGS, NULL},')
|
||||
prnt(' {NULL, NULL, 0, NULL} /* Sentinel */')
|
||||
prnt('};')
|
||||
prnt()
|
||||
#
|
||||
# standard init.
|
||||
modname = self.verifier.get_module_name()
|
||||
constants = self._chained_list_constants[False]
|
||||
prnt('#if PY_MAJOR_VERSION >= 3')
|
||||
prnt()
|
||||
prnt('static struct PyModuleDef _cffi_module_def = {')
|
||||
prnt(' PyModuleDef_HEAD_INIT,')
|
||||
prnt(' "%s",' % modname)
|
||||
prnt(' NULL,')
|
||||
prnt(' -1,')
|
||||
prnt(' _cffi_methods,')
|
||||
prnt(' NULL, NULL, NULL, NULL')
|
||||
prnt('};')
|
||||
prnt()
|
||||
prnt('PyMODINIT_FUNC')
|
||||
prnt('PyInit_%s(void)' % modname)
|
||||
prnt('{')
|
||||
prnt(' PyObject *lib;')
|
||||
prnt(' lib = PyModule_Create(&_cffi_module_def);')
|
||||
prnt(' if (lib == NULL)')
|
||||
prnt(' return NULL;')
|
||||
prnt(' if (%s < 0 || _cffi_init() < 0) {' % (constants,))
|
||||
prnt(' Py_DECREF(lib);')
|
||||
prnt(' return NULL;')
|
||||
prnt(' }')
|
||||
prnt(' return lib;')
|
||||
prnt('}')
|
||||
prnt()
|
||||
prnt('#else')
|
||||
prnt()
|
||||
prnt('PyMODINIT_FUNC')
|
||||
prnt('init%s(void)' % modname)
|
||||
prnt('{')
|
||||
prnt(' PyObject *lib;')
|
||||
prnt(' lib = Py_InitModule("%s", _cffi_methods);' % modname)
|
||||
prnt(' if (lib == NULL)')
|
||||
prnt(' return;')
|
||||
prnt(' if (%s < 0 || _cffi_init() < 0)' % (constants,))
|
||||
prnt(' return;')
|
||||
prnt(' return;')
|
||||
prnt('}')
|
||||
prnt()
|
||||
prnt('#endif')
|
||||
|
||||
def load_library(self):
|
||||
# XXX review all usages of 'self' here!
|
||||
# import it as a new extension module
|
||||
try:
|
||||
module = imp.load_dynamic(self.verifier.get_module_name(),
|
||||
self.verifier.modulefilename)
|
||||
except ImportError as e:
|
||||
error = "importing %r: %s" % (self.verifier.modulefilename, e)
|
||||
raise ffiplatform.VerificationError(error)
|
||||
#
|
||||
# call loading_cpy_struct() to get the struct layout inferred by
|
||||
# the C compiler
|
||||
self._load(module, 'loading')
|
||||
#
|
||||
# the C code will need the <ctype> objects. Collect them in
|
||||
# order in a list.
|
||||
revmapping = dict([(value, key)
|
||||
for (key, value) in self._typesdict.items()])
|
||||
lst = [revmapping[i] for i in range(len(revmapping))]
|
||||
lst = list(map(self.ffi._get_cached_btype, lst))
|
||||
#
|
||||
# build the FFILibrary class and instance and call _cffi_setup().
|
||||
# this will set up some fields like '_cffi_types', and only then
|
||||
# it will invoke the chained list of functions that will really
|
||||
# build (notably) the constant objects, as <cdata> if they are
|
||||
# pointers, and store them as attributes on the 'library' object.
|
||||
class FFILibrary(object):
|
||||
_cffi_python_module = module
|
||||
_cffi_ffi = self.ffi
|
||||
_cffi_dir = []
|
||||
def __dir__(self):
|
||||
return FFILibrary._cffi_dir + list(self.__dict__)
|
||||
library = FFILibrary()
|
||||
if module._cffi_setup(lst, ffiplatform.VerificationError, library):
|
||||
import warnings
|
||||
warnings.warn("reimporting %r might overwrite older definitions"
|
||||
% (self.verifier.get_module_name()))
|
||||
#
|
||||
# finally, call the loaded_cpy_xxx() functions. This will perform
|
||||
# the final adjustments, like copying the Python->C wrapper
|
||||
# functions from the module to the 'library' object, and setting
|
||||
# up the FFILibrary class with properties for the global C variables.
|
||||
self._load(module, 'loaded', library=library)
|
||||
module._cffi_original_ffi = self.ffi
|
||||
module._cffi_types_of_builtin_funcs = self._types_of_builtin_functions
|
||||
return library
|
||||
|
||||
def _get_declarations(self):
|
||||
return sorted(self.ffi._parser._declarations.items())
|
||||
|
||||
def _generate(self, step_name):
|
||||
for name, tp in self._get_declarations():
|
||||
kind, realname = name.split(' ', 1)
|
||||
try:
|
||||
method = getattr(self, '_generate_cpy_%s_%s' % (kind,
|
||||
step_name))
|
||||
except AttributeError:
|
||||
raise ffiplatform.VerificationError(
|
||||
"not implemented in verify(): %r" % name)
|
||||
try:
|
||||
method(tp, realname)
|
||||
except Exception as e:
|
||||
model.attach_exception_info(e, name)
|
||||
raise
|
||||
|
||||
def _load(self, module, step_name, **kwds):
|
||||
for name, tp in self._get_declarations():
|
||||
kind, realname = name.split(' ', 1)
|
||||
method = getattr(self, '_%s_cpy_%s' % (step_name, kind))
|
||||
try:
|
||||
method(tp, realname, module, **kwds)
|
||||
except Exception as e:
|
||||
model.attach_exception_info(e, name)
|
||||
raise
|
||||
|
||||
def _generate_nothing(self, tp, name):
|
||||
pass
|
||||
|
||||
def _loaded_noop(self, tp, name, module, **kwds):
|
||||
pass
|
||||
|
||||
# ----------
|
||||
|
||||
def _convert_funcarg_to_c(self, tp, fromvar, tovar, errcode):
|
||||
extraarg = ''
|
||||
if isinstance(tp, model.PrimitiveType):
|
||||
if tp.is_integer_type() and tp.name != '_Bool':
|
||||
converter = '_cffi_to_c_int'
|
||||
extraarg = ', %s' % tp.name
|
||||
else:
|
||||
converter = '_cffi_to_c_%s' % (tp.name.replace(' ', '_'),)
|
||||
errvalue = '-1'
|
||||
#
|
||||
elif isinstance(tp, model.PointerType):
|
||||
self._convert_funcarg_to_c_ptr_or_array(tp, fromvar,
|
||||
tovar, errcode)
|
||||
return
|
||||
#
|
||||
elif isinstance(tp, (model.StructOrUnion, model.EnumType)):
|
||||
# a struct (not a struct pointer) as a function argument
|
||||
self._prnt(' if (_cffi_to_c((char *)&%s, _cffi_type(%d), %s) < 0)'
|
||||
% (tovar, self._gettypenum(tp), fromvar))
|
||||
self._prnt(' %s;' % errcode)
|
||||
return
|
||||
#
|
||||
elif isinstance(tp, model.FunctionPtrType):
|
||||
converter = '(%s)_cffi_to_c_pointer' % tp.get_c_name('')
|
||||
extraarg = ', _cffi_type(%d)' % self._gettypenum(tp)
|
||||
errvalue = 'NULL'
|
||||
#
|
||||
else:
|
||||
raise NotImplementedError(tp)
|
||||
#
|
||||
self._prnt(' %s = %s(%s%s);' % (tovar, converter, fromvar, extraarg))
|
||||
self._prnt(' if (%s == (%s)%s && PyErr_Occurred())' % (
|
||||
tovar, tp.get_c_name(''), errvalue))
|
||||
self._prnt(' %s;' % errcode)
|
||||
|
||||
def _extra_local_variables(self, tp, localvars):
|
||||
if isinstance(tp, model.PointerType):
|
||||
localvars.add('Py_ssize_t datasize')
|
||||
|
||||
def _convert_funcarg_to_c_ptr_or_array(self, tp, fromvar, tovar, errcode):
|
||||
self._prnt(' datasize = _cffi_prepare_pointer_call_argument(')
|
||||
self._prnt(' _cffi_type(%d), %s, (char **)&%s);' % (
|
||||
self._gettypenum(tp), fromvar, tovar))
|
||||
self._prnt(' if (datasize != 0) {')
|
||||
self._prnt(' if (datasize < 0)')
|
||||
self._prnt(' %s;' % errcode)
|
||||
self._prnt(' %s = alloca(datasize);' % (tovar,))
|
||||
self._prnt(' memset((void *)%s, 0, datasize);' % (tovar,))
|
||||
self._prnt(' if (_cffi_convert_array_from_object('
|
||||
'(char *)%s, _cffi_type(%d), %s) < 0)' % (
|
||||
tovar, self._gettypenum(tp), fromvar))
|
||||
self._prnt(' %s;' % errcode)
|
||||
self._prnt(' }')
|
||||
|
||||
def _convert_expr_from_c(self, tp, var, context):
|
||||
if isinstance(tp, model.PrimitiveType):
|
||||
if tp.is_integer_type():
|
||||
return '_cffi_from_c_int(%s, %s)' % (var, tp.name)
|
||||
elif tp.name != 'long double':
|
||||
return '_cffi_from_c_%s(%s)' % (tp.name.replace(' ', '_'), var)
|
||||
else:
|
||||
return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % (
|
||||
var, self._gettypenum(tp))
|
||||
elif isinstance(tp, (model.PointerType, model.FunctionPtrType)):
|
||||
return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % (
|
||||
var, self._gettypenum(tp))
|
||||
elif isinstance(tp, model.ArrayType):
|
||||
return '_cffi_from_c_pointer((char *)%s, _cffi_type(%d))' % (
|
||||
var, self._gettypenum(model.PointerType(tp.item)))
|
||||
elif isinstance(tp, model.StructType):
|
||||
if tp.fldnames is None:
|
||||
raise TypeError("'%s' is used as %s, but is opaque" % (
|
||||
tp._get_c_name(), context))
|
||||
return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % (
|
||||
var, self._gettypenum(tp))
|
||||
elif isinstance(tp, model.EnumType):
|
||||
return '_cffi_from_c_deref((char *)&%s, _cffi_type(%d))' % (
|
||||
var, self._gettypenum(tp))
|
||||
else:
|
||||
raise NotImplementedError(tp)
|
||||
|
||||
# ----------
|
||||
# typedefs: generates no code so far
|
||||
|
||||
_generate_cpy_typedef_collecttype = _generate_nothing
|
||||
_generate_cpy_typedef_decl = _generate_nothing
|
||||
_generate_cpy_typedef_method = _generate_nothing
|
||||
_loading_cpy_typedef = _loaded_noop
|
||||
_loaded_cpy_typedef = _loaded_noop
|
||||
|
||||
# ----------
|
||||
# function declarations
|
||||
|
||||
def _generate_cpy_function_collecttype(self, tp, name):
|
||||
assert isinstance(tp, model.FunctionPtrType)
|
||||
if tp.ellipsis:
|
||||
self._do_collect_type(tp)
|
||||
else:
|
||||
# don't call _do_collect_type(tp) in this common case,
|
||||
# otherwise test_autofilled_struct_as_argument fails
|
||||
for type in tp.args:
|
||||
self._do_collect_type(type)
|
||||
self._do_collect_type(tp.result)
|
||||
|
||||
def _generate_cpy_function_decl(self, tp, name):
|
||||
assert isinstance(tp, model.FunctionPtrType)
|
||||
if tp.ellipsis:
|
||||
# cannot support vararg functions better than this: check for its
|
||||
# exact type (including the fixed arguments), and build it as a
|
||||
# constant function pointer (no CPython wrapper)
|
||||
self._generate_cpy_const(False, name, tp)
|
||||
return
|
||||
prnt = self._prnt
|
||||
numargs = len(tp.args)
|
||||
if numargs == 0:
|
||||
argname = 'no_arg'
|
||||
elif numargs == 1:
|
||||
argname = 'arg0'
|
||||
else:
|
||||
argname = 'args'
|
||||
prnt('static PyObject *')
|
||||
prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname))
|
||||
prnt('{')
|
||||
#
|
||||
context = 'argument of %s' % name
|
||||
for i, type in enumerate(tp.args):
|
||||
prnt(' %s;' % type.get_c_name(' x%d' % i, context))
|
||||
#
|
||||
localvars = set()
|
||||
for type in tp.args:
|
||||
self._extra_local_variables(type, localvars)
|
||||
for decl in localvars:
|
||||
prnt(' %s;' % (decl,))
|
||||
#
|
||||
if not isinstance(tp.result, model.VoidType):
|
||||
result_code = 'result = '
|
||||
context = 'result of %s' % name
|
||||
prnt(' %s;' % tp.result.get_c_name(' result', context))
|
||||
else:
|
||||
result_code = ''
|
||||
#
|
||||
if len(tp.args) > 1:
|
||||
rng = range(len(tp.args))
|
||||
for i in rng:
|
||||
prnt(' PyObject *arg%d;' % i)
|
||||
prnt()
|
||||
prnt(' if (!PyArg_ParseTuple(args, "%s:%s", %s))' % (
|
||||
'O' * numargs, name, ', '.join(['&arg%d' % i for i in rng])))
|
||||
prnt(' return NULL;')
|
||||
prnt()
|
||||
#
|
||||
for i, type in enumerate(tp.args):
|
||||
self._convert_funcarg_to_c(type, 'arg%d' % i, 'x%d' % i,
|
||||
'return NULL')
|
||||
prnt()
|
||||
#
|
||||
prnt(' Py_BEGIN_ALLOW_THREADS')
|
||||
prnt(' _cffi_restore_errno();')
|
||||
prnt(' { %s%s(%s); }' % (
|
||||
result_code, name,
|
||||
', '.join(['x%d' % i for i in range(len(tp.args))])))
|
||||
prnt(' _cffi_save_errno();')
|
||||
prnt(' Py_END_ALLOW_THREADS')
|
||||
prnt()
|
||||
#
|
||||
if result_code:
|
||||
prnt(' return %s;' %
|
||||
self._convert_expr_from_c(tp.result, 'result', 'result type'))
|
||||
else:
|
||||
prnt(' Py_INCREF(Py_None);')
|
||||
prnt(' return Py_None;')
|
||||
prnt('}')
|
||||
prnt()
|
||||
|
||||
def _generate_cpy_function_method(self, tp, name):
|
||||
if tp.ellipsis:
|
||||
return
|
||||
numargs = len(tp.args)
|
||||
if numargs == 0:
|
||||
meth = 'METH_NOARGS'
|
||||
elif numargs == 1:
|
||||
meth = 'METH_O'
|
||||
else:
|
||||
meth = 'METH_VARARGS'
|
||||
self._prnt(' {"%s", _cffi_f_%s, %s, NULL},' % (name, name, meth))
|
||||
|
||||
_loading_cpy_function = _loaded_noop
|
||||
|
||||
def _loaded_cpy_function(self, tp, name, module, library):
|
||||
if tp.ellipsis:
|
||||
return
|
||||
func = getattr(module, name)
|
||||
setattr(library, name, func)
|
||||
self._types_of_builtin_functions[func] = tp
|
||||
|
||||
# ----------
|
||||
# named structs
|
||||
|
||||
_generate_cpy_struct_collecttype = _generate_nothing
|
||||
def _generate_cpy_struct_decl(self, tp, name):
|
||||
assert name == tp.name
|
||||
self._generate_struct_or_union_decl(tp, 'struct', name)
|
||||
def _generate_cpy_struct_method(self, tp, name):
|
||||
self._generate_struct_or_union_method(tp, 'struct', name)
|
||||
def _loading_cpy_struct(self, tp, name, module):
|
||||
self._loading_struct_or_union(tp, 'struct', name, module)
|
||||
def _loaded_cpy_struct(self, tp, name, module, **kwds):
|
||||
self._loaded_struct_or_union(tp)
|
||||
|
||||
_generate_cpy_union_collecttype = _generate_nothing
|
||||
def _generate_cpy_union_decl(self, tp, name):
|
||||
assert name == tp.name
|
||||
self._generate_struct_or_union_decl(tp, 'union', name)
|
||||
def _generate_cpy_union_method(self, tp, name):
|
||||
self._generate_struct_or_union_method(tp, 'union', name)
|
||||
def _loading_cpy_union(self, tp, name, module):
|
||||
self._loading_struct_or_union(tp, 'union', name, module)
|
||||
def _loaded_cpy_union(self, tp, name, module, **kwds):
|
||||
self._loaded_struct_or_union(tp)
|
||||
|
||||
def _generate_struct_or_union_decl(self, tp, prefix, name):
|
||||
if tp.fldnames is None:
|
||||
return # nothing to do with opaque structs
|
||||
checkfuncname = '_cffi_check_%s_%s' % (prefix, name)
|
||||
layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name)
|
||||
cname = ('%s %s' % (prefix, name)).strip()
|
||||
#
|
||||
prnt = self._prnt
|
||||
prnt('static void %s(%s *p)' % (checkfuncname, cname))
|
||||
prnt('{')
|
||||
prnt(' /* only to generate compile-time warnings or errors */')
|
||||
for fname, ftype, fbitsize in tp.enumfields():
|
||||
if (isinstance(ftype, model.PrimitiveType)
|
||||
and ftype.is_integer_type()) or fbitsize >= 0:
|
||||
# accept all integers, but complain on float or double
|
||||
prnt(' (void)((p->%s) << 1);' % fname)
|
||||
else:
|
||||
# only accept exactly the type declared.
|
||||
try:
|
||||
prnt(' { %s = &p->%s; (void)tmp; }' % (
|
||||
ftype.get_c_name('*tmp', 'field %r'%fname), fname))
|
||||
except ffiplatform.VerificationError as e:
|
||||
prnt(' /* %s */' % str(e)) # cannot verify it, ignore
|
||||
prnt('}')
|
||||
prnt('static PyObject *')
|
||||
prnt('%s(PyObject *self, PyObject *noarg)' % (layoutfuncname,))
|
||||
prnt('{')
|
||||
prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname)
|
||||
prnt(' static Py_ssize_t nums[] = {')
|
||||
prnt(' sizeof(%s),' % cname)
|
||||
prnt(' offsetof(struct _cffi_aligncheck, y),')
|
||||
for fname, ftype, fbitsize in tp.enumfields():
|
||||
if fbitsize >= 0:
|
||||
continue # xxx ignore fbitsize for now
|
||||
prnt(' offsetof(%s, %s),' % (cname, fname))
|
||||
if isinstance(ftype, model.ArrayType) and ftype.length is None:
|
||||
prnt(' 0, /* %s */' % ftype._get_c_name())
|
||||
else:
|
||||
prnt(' sizeof(((%s *)0)->%s),' % (cname, fname))
|
||||
prnt(' -1')
|
||||
prnt(' };')
|
||||
prnt(' return _cffi_get_struct_layout(nums);')
|
||||
prnt(' /* the next line is not executed, but compiled */')
|
||||
prnt(' %s(0);' % (checkfuncname,))
|
||||
prnt('}')
|
||||
prnt()
|
||||
|
||||
def _generate_struct_or_union_method(self, tp, prefix, name):
|
||||
if tp.fldnames is None:
|
||||
return # nothing to do with opaque structs
|
||||
layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name)
|
||||
self._prnt(' {"%s", %s, METH_NOARGS, NULL},' % (layoutfuncname,
|
||||
layoutfuncname))
|
||||
|
||||
def _loading_struct_or_union(self, tp, prefix, name, module):
|
||||
if tp.fldnames is None:
|
||||
return # nothing to do with opaque structs
|
||||
layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name)
|
||||
#
|
||||
function = getattr(module, layoutfuncname)
|
||||
layout = function()
|
||||
if isinstance(tp, model.StructOrUnion) and tp.partial:
|
||||
# use the function()'s sizes and offsets to guide the
|
||||
# layout of the struct
|
||||
totalsize = layout[0]
|
||||
totalalignment = layout[1]
|
||||
fieldofs = layout[2::2]
|
||||
fieldsize = layout[3::2]
|
||||
tp.force_flatten()
|
||||
assert len(fieldofs) == len(fieldsize) == len(tp.fldnames)
|
||||
tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment
|
||||
else:
|
||||
cname = ('%s %s' % (prefix, name)).strip()
|
||||
self._struct_pending_verification[tp] = layout, cname
|
||||
|
||||
def _loaded_struct_or_union(self, tp):
|
||||
if tp.fldnames is None:
|
||||
return # nothing to do with opaque structs
|
||||
self.ffi._get_cached_btype(tp) # force 'fixedlayout' to be considered
|
||||
|
||||
if tp in self._struct_pending_verification:
|
||||
# check that the layout sizes and offsets match the real ones
|
||||
def check(realvalue, expectedvalue, msg):
|
||||
if realvalue != expectedvalue:
|
||||
raise ffiplatform.VerificationError(
|
||||
"%s (we have %d, but C compiler says %d)"
|
||||
% (msg, expectedvalue, realvalue))
|
||||
ffi = self.ffi
|
||||
BStruct = ffi._get_cached_btype(tp)
|
||||
layout, cname = self._struct_pending_verification.pop(tp)
|
||||
check(layout[0], ffi.sizeof(BStruct), "wrong total size")
|
||||
check(layout[1], ffi.alignof(BStruct), "wrong total alignment")
|
||||
i = 2
|
||||
for fname, ftype, fbitsize in tp.enumfields():
|
||||
if fbitsize >= 0:
|
||||
continue # xxx ignore fbitsize for now
|
||||
check(layout[i], ffi.offsetof(BStruct, fname),
|
||||
"wrong offset for field %r" % (fname,))
|
||||
if layout[i+1] != 0:
|
||||
BField = ffi._get_cached_btype(ftype)
|
||||
check(layout[i+1], ffi.sizeof(BField),
|
||||
"wrong size for field %r" % (fname,))
|
||||
i += 2
|
||||
assert i == len(layout)
|
||||
|
||||
# ----------
|
||||
# 'anonymous' declarations. These are produced for anonymous structs
|
||||
# or unions; the 'name' is obtained by a typedef.
|
||||
|
||||
_generate_cpy_anonymous_collecttype = _generate_nothing
|
||||
|
||||
def _generate_cpy_anonymous_decl(self, tp, name):
|
||||
if isinstance(tp, model.EnumType):
|
||||
self._generate_cpy_enum_decl(tp, name, '')
|
||||
else:
|
||||
self._generate_struct_or_union_decl(tp, '', name)
|
||||
|
||||
def _generate_cpy_anonymous_method(self, tp, name):
|
||||
if not isinstance(tp, model.EnumType):
|
||||
self._generate_struct_or_union_method(tp, '', name)
|
||||
|
||||
def _loading_cpy_anonymous(self, tp, name, module):
|
||||
if isinstance(tp, model.EnumType):
|
||||
self._loading_cpy_enum(tp, name, module)
|
||||
else:
|
||||
self._loading_struct_or_union(tp, '', name, module)
|
||||
|
||||
def _loaded_cpy_anonymous(self, tp, name, module, **kwds):
|
||||
if isinstance(tp, model.EnumType):
|
||||
self._loaded_cpy_enum(tp, name, module, **kwds)
|
||||
else:
|
||||
self._loaded_struct_or_union(tp)
|
||||
|
||||
# ----------
|
||||
# constants, likely declared with '#define'
|
||||
|
||||
def _generate_cpy_const(self, is_int, name, tp=None, category='const',
|
||||
vartp=None, delayed=True, size_too=False):
|
||||
prnt = self._prnt
|
||||
funcname = '_cffi_%s_%s' % (category, name)
|
||||
prnt('static int %s(PyObject *lib)' % funcname)
|
||||
prnt('{')
|
||||
prnt(' PyObject *o;')
|
||||
prnt(' int res;')
|
||||
if not is_int:
|
||||
prnt(' %s;' % (vartp or tp).get_c_name(' i', name))
|
||||
else:
|
||||
assert category == 'const'
|
||||
#
|
||||
if not is_int:
|
||||
if category == 'var':
|
||||
realexpr = '&' + name
|
||||
else:
|
||||
realexpr = name
|
||||
prnt(' i = (%s);' % (realexpr,))
|
||||
prnt(' o = %s;' % (self._convert_expr_from_c(tp, 'i',
|
||||
'variable type'),))
|
||||
assert delayed
|
||||
else:
|
||||
prnt(' o = _cffi_from_c_int_const(%s);' % name)
|
||||
prnt(' if (o == NULL)')
|
||||
prnt(' return -1;')
|
||||
if size_too:
|
||||
prnt(' {')
|
||||
prnt(' PyObject *o1 = o;')
|
||||
prnt(' o = Py_BuildValue("On", o1, (Py_ssize_t)sizeof(%s));'
|
||||
% (name,))
|
||||
prnt(' Py_DECREF(o1);')
|
||||
prnt(' if (o == NULL)')
|
||||
prnt(' return -1;')
|
||||
prnt(' }')
|
||||
prnt(' res = PyObject_SetAttrString(lib, "%s", o);' % name)
|
||||
prnt(' Py_DECREF(o);')
|
||||
prnt(' if (res < 0)')
|
||||
prnt(' return -1;')
|
||||
prnt(' return %s;' % self._chained_list_constants[delayed])
|
||||
self._chained_list_constants[delayed] = funcname + '(lib)'
|
||||
prnt('}')
|
||||
prnt()
|
||||
|
||||
def _generate_cpy_constant_collecttype(self, tp, name):
|
||||
is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
|
||||
if not is_int:
|
||||
self._do_collect_type(tp)
|
||||
|
||||
def _generate_cpy_constant_decl(self, tp, name):
|
||||
is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
|
||||
self._generate_cpy_const(is_int, name, tp)
|
||||
|
||||
_generate_cpy_constant_method = _generate_nothing
|
||||
_loading_cpy_constant = _loaded_noop
|
||||
_loaded_cpy_constant = _loaded_noop
|
||||
|
||||
# ----------
|
||||
# enums
|
||||
|
||||
def _enum_funcname(self, prefix, name):
|
||||
# "$enum_$1" => "___D_enum____D_1"
|
||||
name = name.replace('$', '___D_')
|
||||
return '_cffi_e_%s_%s' % (prefix, name)
|
||||
|
||||
def _generate_cpy_enum_decl(self, tp, name, prefix='enum'):
|
||||
if tp.partial:
|
||||
for enumerator in tp.enumerators:
|
||||
self._generate_cpy_const(True, enumerator, delayed=False)
|
||||
return
|
||||
#
|
||||
funcname = self._enum_funcname(prefix, name)
|
||||
prnt = self._prnt
|
||||
prnt('static int %s(PyObject *lib)' % funcname)
|
||||
prnt('{')
|
||||
for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues):
|
||||
if enumvalue < 0:
|
||||
prnt(' if ((%s) >= 0 || (long)(%s) != %dL) {' % (
|
||||
enumerator, enumerator, enumvalue))
|
||||
else:
|
||||
prnt(' if ((%s) < 0 || (unsigned long)(%s) != %dUL) {' % (
|
||||
enumerator, enumerator, enumvalue))
|
||||
prnt(' char buf[64];')
|
||||
prnt(' if ((%s) < 0)' % enumerator)
|
||||
prnt(' snprintf(buf, 63, "%%ld", (long)(%s));' % enumerator)
|
||||
prnt(' else')
|
||||
prnt(' snprintf(buf, 63, "%%lu", (unsigned long)(%s));' %
|
||||
enumerator)
|
||||
prnt(' PyErr_Format(_cffi_VerificationError,')
|
||||
prnt(' "enum %s: %s has the real value %s, '
|
||||
'not %s",')
|
||||
prnt(' "%s", "%s", buf, "%d");' % (
|
||||
name, enumerator, enumvalue))
|
||||
prnt(' return -1;')
|
||||
prnt(' }')
|
||||
prnt(' return %s;' % self._chained_list_constants[True])
|
||||
self._chained_list_constants[True] = funcname + '(lib)'
|
||||
prnt('}')
|
||||
prnt()
|
||||
|
||||
_generate_cpy_enum_collecttype = _generate_nothing
|
||||
_generate_cpy_enum_method = _generate_nothing
|
||||
|
||||
def _loading_cpy_enum(self, tp, name, module):
|
||||
if tp.partial:
|
||||
enumvalues = [getattr(module, enumerator)
|
||||
for enumerator in tp.enumerators]
|
||||
tp.enumvalues = tuple(enumvalues)
|
||||
tp.partial_resolved = True
|
||||
|
||||
def _loaded_cpy_enum(self, tp, name, module, library):
|
||||
for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues):
|
||||
setattr(library, enumerator, enumvalue)
|
||||
|
||||
# ----------
|
||||
# macros: for now only for integers
|
||||
|
||||
def _generate_cpy_macro_decl(self, tp, name):
|
||||
assert tp == '...'
|
||||
self._generate_cpy_const(True, name)
|
||||
|
||||
_generate_cpy_macro_collecttype = _generate_nothing
|
||||
_generate_cpy_macro_method = _generate_nothing
|
||||
_loading_cpy_macro = _loaded_noop
|
||||
_loaded_cpy_macro = _loaded_noop
|
||||
|
||||
# ----------
|
||||
# global variables
|
||||
|
||||
def _generate_cpy_variable_collecttype(self, tp, name):
|
||||
if isinstance(tp, model.ArrayType):
|
||||
tp_ptr = model.PointerType(tp.item)
|
||||
else:
|
||||
tp_ptr = model.PointerType(tp)
|
||||
self._do_collect_type(tp_ptr)
|
||||
|
||||
def _generate_cpy_variable_decl(self, tp, name):
|
||||
if isinstance(tp, model.ArrayType):
|
||||
tp_ptr = model.PointerType(tp.item)
|
||||
self._generate_cpy_const(False, name, tp, vartp=tp_ptr,
|
||||
size_too = (tp.length == '...'))
|
||||
else:
|
||||
tp_ptr = model.PointerType(tp)
|
||||
self._generate_cpy_const(False, name, tp_ptr, category='var')
|
||||
|
||||
_generate_cpy_variable_method = _generate_nothing
|
||||
_loading_cpy_variable = _loaded_noop
|
||||
|
||||
def _loaded_cpy_variable(self, tp, name, module, library):
|
||||
value = getattr(library, name)
|
||||
if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the
|
||||
# sense that "a=..." is forbidden
|
||||
if tp.length == '...':
|
||||
assert isinstance(value, tuple)
|
||||
(value, size) = value
|
||||
BItemType = self.ffi._get_cached_btype(tp.item)
|
||||
length, rest = divmod(size, self.ffi.sizeof(BItemType))
|
||||
if rest != 0:
|
||||
raise ffiplatform.VerificationError(
|
||||
"bad size: %r does not seem to be an array of %s" %
|
||||
(name, tp.item))
|
||||
tp = tp.resolve_length(length)
|
||||
# 'value' is a <cdata 'type *'> which we have to replace with
|
||||
# a <cdata 'type[N]'> if the N is actually known
|
||||
if tp.length is not None:
|
||||
BArray = self.ffi._get_cached_btype(tp)
|
||||
value = self.ffi.cast(BArray, value)
|
||||
setattr(library, name, value)
|
||||
return
|
||||
# remove ptr=<cdata 'int *'> from the library instance, and replace
|
||||
# it by a property on the class, which reads/writes into ptr[0].
|
||||
ptr = value
|
||||
delattr(library, name)
|
||||
def getter(library):
|
||||
return ptr[0]
|
||||
def setter(library, value):
|
||||
ptr[0] = value
|
||||
setattr(type(library), name, property(getter, setter))
|
||||
type(library)._cffi_dir.append(name)
|
||||
|
||||
# ----------
|
||||
|
||||
def _generate_setup_custom(self):
|
||||
prnt = self._prnt
|
||||
prnt('static int _cffi_setup_custom(PyObject *lib)')
|
||||
prnt('{')
|
||||
prnt(' return %s;' % self._chained_list_constants[True])
|
||||
prnt('}')
|
||||
|
||||
cffimod_header = r'''
|
||||
#include <Python.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* this block of #ifs should be kept exactly identical between
|
||||
c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py */
|
||||
#if defined(_MSC_VER)
|
||||
# include <malloc.h> /* for alloca() */
|
||||
# if _MSC_VER < 1600 /* MSVC < 2010 */
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# else
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
# if _MSC_VER < 1800 /* MSVC < 2013 */
|
||||
typedef unsigned char _Bool;
|
||||
# endif
|
||||
#else
|
||||
# include <stdint.h>
|
||||
# if (defined (__SVR4) && defined (__sun)) || defined(_AIX)
|
||||
# include <alloca.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
# undef PyCapsule_CheckExact
|
||||
# undef PyCapsule_GetPointer
|
||||
# define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule))
|
||||
# define PyCapsule_GetPointer(capsule, name) \
|
||||
(PyCObject_AsVoidPtr(capsule))
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
# define PyInt_FromLong PyLong_FromLong
|
||||
#endif
|
||||
|
||||
#define _cffi_from_c_double PyFloat_FromDouble
|
||||
#define _cffi_from_c_float PyFloat_FromDouble
|
||||
#define _cffi_from_c_long PyInt_FromLong
|
||||
#define _cffi_from_c_ulong PyLong_FromUnsignedLong
|
||||
#define _cffi_from_c_longlong PyLong_FromLongLong
|
||||
#define _cffi_from_c_ulonglong PyLong_FromUnsignedLongLong
|
||||
|
||||
#define _cffi_to_c_double PyFloat_AsDouble
|
||||
#define _cffi_to_c_float PyFloat_AsDouble
|
||||
|
||||
#define _cffi_from_c_int_const(x) \
|
||||
(((x) > 0) ? \
|
||||
((unsigned long long)(x) <= (unsigned long long)LONG_MAX) ? \
|
||||
PyInt_FromLong((long)(x)) : \
|
||||
PyLong_FromUnsignedLongLong((unsigned long long)(x)) : \
|
||||
((long long)(x) >= (long long)LONG_MIN) ? \
|
||||
PyInt_FromLong((long)(x)) : \
|
||||
PyLong_FromLongLong((long long)(x)))
|
||||
|
||||
#define _cffi_from_c_int(x, type) \
|
||||
(((type)-1) > 0 ? /* unsigned */ \
|
||||
(sizeof(type) < sizeof(long) ? PyInt_FromLong(x) : \
|
||||
sizeof(type) == sizeof(long) ? PyLong_FromUnsignedLong(x) : \
|
||||
PyLong_FromUnsignedLongLong(x)) \
|
||||
: (sizeof(type) <= sizeof(long) ? PyInt_FromLong(x) : \
|
||||
PyLong_FromLongLong(x)))
|
||||
|
||||
#define _cffi_to_c_int(o, type) \
|
||||
(sizeof(type) == 1 ? (((type)-1) > 0 ? (type)_cffi_to_c_u8(o) \
|
||||
: (type)_cffi_to_c_i8(o)) : \
|
||||
sizeof(type) == 2 ? (((type)-1) > 0 ? (type)_cffi_to_c_u16(o) \
|
||||
: (type)_cffi_to_c_i16(o)) : \
|
||||
sizeof(type) == 4 ? (((type)-1) > 0 ? (type)_cffi_to_c_u32(o) \
|
||||
: (type)_cffi_to_c_i32(o)) : \
|
||||
sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o) \
|
||||
: (type)_cffi_to_c_i64(o)) : \
|
||||
(Py_FatalError("unsupported size for type " #type), 0))
|
||||
|
||||
#define _cffi_to_c_i8 \
|
||||
((int(*)(PyObject *))_cffi_exports[1])
|
||||
#define _cffi_to_c_u8 \
|
||||
((int(*)(PyObject *))_cffi_exports[2])
|
||||
#define _cffi_to_c_i16 \
|
||||
((int(*)(PyObject *))_cffi_exports[3])
|
||||
#define _cffi_to_c_u16 \
|
||||
((int(*)(PyObject *))_cffi_exports[4])
|
||||
#define _cffi_to_c_i32 \
|
||||
((int(*)(PyObject *))_cffi_exports[5])
|
||||
#define _cffi_to_c_u32 \
|
||||
((unsigned int(*)(PyObject *))_cffi_exports[6])
|
||||
#define _cffi_to_c_i64 \
|
||||
((long long(*)(PyObject *))_cffi_exports[7])
|
||||
#define _cffi_to_c_u64 \
|
||||
((unsigned long long(*)(PyObject *))_cffi_exports[8])
|
||||
#define _cffi_to_c_char \
|
||||
((int(*)(PyObject *))_cffi_exports[9])
|
||||
#define _cffi_from_c_pointer \
|
||||
((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[10])
|
||||
#define _cffi_to_c_pointer \
|
||||
((char *(*)(PyObject *, CTypeDescrObject *))_cffi_exports[11])
|
||||
#define _cffi_get_struct_layout \
|
||||
((PyObject *(*)(Py_ssize_t[]))_cffi_exports[12])
|
||||
#define _cffi_restore_errno \
|
||||
((void(*)(void))_cffi_exports[13])
|
||||
#define _cffi_save_errno \
|
||||
((void(*)(void))_cffi_exports[14])
|
||||
#define _cffi_from_c_char \
|
||||
((PyObject *(*)(char))_cffi_exports[15])
|
||||
#define _cffi_from_c_deref \
|
||||
((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16])
|
||||
#define _cffi_to_c \
|
||||
((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[17])
|
||||
#define _cffi_from_c_struct \
|
||||
((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[18])
|
||||
#define _cffi_to_c_wchar_t \
|
||||
((wchar_t(*)(PyObject *))_cffi_exports[19])
|
||||
#define _cffi_from_c_wchar_t \
|
||||
((PyObject *(*)(wchar_t))_cffi_exports[20])
|
||||
#define _cffi_to_c_long_double \
|
||||
((long double(*)(PyObject *))_cffi_exports[21])
|
||||
#define _cffi_to_c__Bool \
|
||||
((_Bool(*)(PyObject *))_cffi_exports[22])
|
||||
#define _cffi_prepare_pointer_call_argument \
|
||||
((Py_ssize_t(*)(CTypeDescrObject *, PyObject *, char **))_cffi_exports[23])
|
||||
#define _cffi_convert_array_from_object \
|
||||
((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[24])
|
||||
#define _CFFI_NUM_EXPORTS 25
|
||||
|
||||
typedef struct _ctypedescr CTypeDescrObject;
|
||||
|
||||
static void *_cffi_exports[_CFFI_NUM_EXPORTS];
|
||||
static PyObject *_cffi_types, *_cffi_VerificationError;
|
||||
|
||||
static int _cffi_setup_custom(PyObject *lib); /* forward */
|
||||
|
||||
static PyObject *_cffi_setup(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *library;
|
||||
int was_alive = (_cffi_types != NULL);
|
||||
if (!PyArg_ParseTuple(args, "OOO", &_cffi_types, &_cffi_VerificationError,
|
||||
&library))
|
||||
return NULL;
|
||||
Py_INCREF(_cffi_types);
|
||||
Py_INCREF(_cffi_VerificationError);
|
||||
if (_cffi_setup_custom(library) < 0)
|
||||
return NULL;
|
||||
return PyBool_FromLong(was_alive);
|
||||
}
|
||||
|
||||
static int _cffi_init(void)
|
||||
{
|
||||
PyObject *module, *c_api_object = NULL;
|
||||
|
||||
module = PyImport_ImportModule("_cffi_backend");
|
||||
if (module == NULL)
|
||||
goto failure;
|
||||
|
||||
c_api_object = PyObject_GetAttrString(module, "_C_API");
|
||||
if (c_api_object == NULL)
|
||||
goto failure;
|
||||
if (!PyCapsule_CheckExact(c_api_object)) {
|
||||
PyErr_SetNone(PyExc_ImportError);
|
||||
goto failure;
|
||||
}
|
||||
memcpy(_cffi_exports, PyCapsule_GetPointer(c_api_object, "cffi"),
|
||||
_CFFI_NUM_EXPORTS * sizeof(void *));
|
||||
|
||||
Py_DECREF(module);
|
||||
Py_DECREF(c_api_object);
|
||||
return 0;
|
||||
|
||||
failure:
|
||||
Py_XDECREF(module);
|
||||
Py_XDECREF(c_api_object);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define _cffi_type(num) ((CTypeDescrObject *)PyList_GET_ITEM(_cffi_types, num))
|
||||
|
||||
/**********/
|
||||
'''
|
|
@ -1,580 +0,0 @@
|
|||
import sys, os
|
||||
import types
|
||||
|
||||
from . import model, ffiplatform
|
||||
|
||||
|
||||
class VGenericEngine(object):
|
||||
_class_key = 'g'
|
||||
_gen_python_module = False
|
||||
|
||||
def __init__(self, verifier):
|
||||
self.verifier = verifier
|
||||
self.ffi = verifier.ffi
|
||||
self.export_symbols = []
|
||||
self._struct_pending_verification = {}
|
||||
|
||||
def patch_extension_kwds(self, kwds):
|
||||
# add 'export_symbols' to the dictionary. Note that we add the
|
||||
# list before filling it. When we fill it, it will thus also show
|
||||
# up in kwds['export_symbols'].
|
||||
kwds.setdefault('export_symbols', self.export_symbols)
|
||||
|
||||
def find_module(self, module_name, path, so_suffixes):
|
||||
for so_suffix in so_suffixes:
|
||||
basename = module_name + so_suffix
|
||||
if path is None:
|
||||
path = sys.path
|
||||
for dirname in path:
|
||||
filename = os.path.join(dirname, basename)
|
||||
if os.path.isfile(filename):
|
||||
return filename
|
||||
|
||||
def collect_types(self):
|
||||
pass # not needed in the generic engine
|
||||
|
||||
def _prnt(self, what=''):
|
||||
self._f.write(what + '\n')
|
||||
|
||||
def write_source_to_f(self):
|
||||
prnt = self._prnt
|
||||
# first paste some standard set of lines that are mostly '#include'
|
||||
prnt(cffimod_header)
|
||||
# then paste the C source given by the user, verbatim.
|
||||
prnt(self.verifier.preamble)
|
||||
#
|
||||
# call generate_gen_xxx_decl(), for every xxx found from
|
||||
# ffi._parser._declarations. This generates all the functions.
|
||||
self._generate('decl')
|
||||
#
|
||||
# on Windows, distutils insists on putting init_cffi_xyz in
|
||||
# 'export_symbols', so instead of fighting it, just give up and
|
||||
# give it one
|
||||
if sys.platform == 'win32':
|
||||
if sys.version_info >= (3,):
|
||||
prefix = 'PyInit_'
|
||||
else:
|
||||
prefix = 'init'
|
||||
modname = self.verifier.get_module_name()
|
||||
prnt("void %s%s(void) { }\n" % (prefix, modname))
|
||||
|
||||
def load_library(self):
|
||||
# import it with the CFFI backend
|
||||
backend = self.ffi._backend
|
||||
# needs to make a path that contains '/', on Posix
|
||||
filename = os.path.join(os.curdir, self.verifier.modulefilename)
|
||||
module = backend.load_library(filename)
|
||||
#
|
||||
# call loading_gen_struct() to get the struct layout inferred by
|
||||
# the C compiler
|
||||
self._load(module, 'loading')
|
||||
|
||||
# build the FFILibrary class and instance, this is a module subclass
|
||||
# because modules are expected to have usually-constant-attributes and
|
||||
# in PyPy this means the JIT is able to treat attributes as constant,
|
||||
# which we want.
|
||||
class FFILibrary(types.ModuleType):
|
||||
_cffi_generic_module = module
|
||||
_cffi_ffi = self.ffi
|
||||
_cffi_dir = []
|
||||
def __dir__(self):
|
||||
return FFILibrary._cffi_dir
|
||||
library = FFILibrary("")
|
||||
#
|
||||
# finally, call the loaded_gen_xxx() functions. This will set
|
||||
# up the 'library' object.
|
||||
self._load(module, 'loaded', library=library)
|
||||
return library
|
||||
|
||||
def _get_declarations(self):
|
||||
return sorted(self.ffi._parser._declarations.items())
|
||||
|
||||
def _generate(self, step_name):
|
||||
for name, tp in self._get_declarations():
|
||||
kind, realname = name.split(' ', 1)
|
||||
try:
|
||||
method = getattr(self, '_generate_gen_%s_%s' % (kind,
|
||||
step_name))
|
||||
except AttributeError:
|
||||
raise ffiplatform.VerificationError(
|
||||
"not implemented in verify(): %r" % name)
|
||||
try:
|
||||
method(tp, realname)
|
||||
except Exception as e:
|
||||
model.attach_exception_info(e, name)
|
||||
raise
|
||||
|
||||
def _load(self, module, step_name, **kwds):
|
||||
for name, tp in self._get_declarations():
|
||||
kind, realname = name.split(' ', 1)
|
||||
method = getattr(self, '_%s_gen_%s' % (step_name, kind))
|
||||
try:
|
||||
method(tp, realname, module, **kwds)
|
||||
except Exception as e:
|
||||
model.attach_exception_info(e, name)
|
||||
raise
|
||||
|
||||
def _generate_nothing(self, tp, name):
|
||||
pass
|
||||
|
||||
def _loaded_noop(self, tp, name, module, **kwds):
|
||||
pass
|
||||
|
||||
# ----------
|
||||
# typedefs: generates no code so far
|
||||
|
||||
_generate_gen_typedef_decl = _generate_nothing
|
||||
_loading_gen_typedef = _loaded_noop
|
||||
_loaded_gen_typedef = _loaded_noop
|
||||
|
||||
# ----------
|
||||
# function declarations
|
||||
|
||||
def _generate_gen_function_decl(self, tp, name):
|
||||
assert isinstance(tp, model.FunctionPtrType)
|
||||
if tp.ellipsis:
|
||||
# cannot support vararg functions better than this: check for its
|
||||
# exact type (including the fixed arguments), and build it as a
|
||||
# constant function pointer (no _cffi_f_%s wrapper)
|
||||
self._generate_gen_const(False, name, tp)
|
||||
return
|
||||
prnt = self._prnt
|
||||
numargs = len(tp.args)
|
||||
argnames = []
|
||||
for i, type in enumerate(tp.args):
|
||||
indirection = ''
|
||||
if isinstance(type, model.StructOrUnion):
|
||||
indirection = '*'
|
||||
argnames.append('%sx%d' % (indirection, i))
|
||||
context = 'argument of %s' % name
|
||||
arglist = [type.get_c_name(' %s' % arg, context)
|
||||
for type, arg in zip(tp.args, argnames)]
|
||||
arglist = ', '.join(arglist) or 'void'
|
||||
wrappername = '_cffi_f_%s' % name
|
||||
self.export_symbols.append(wrappername)
|
||||
funcdecl = ' %s(%s)' % (wrappername, arglist)
|
||||
context = 'result of %s' % name
|
||||
prnt(tp.result.get_c_name(funcdecl, context))
|
||||
prnt('{')
|
||||
#
|
||||
if not isinstance(tp.result, model.VoidType):
|
||||
result_code = 'return '
|
||||
else:
|
||||
result_code = ''
|
||||
prnt(' %s%s(%s);' % (result_code, name, ', '.join(argnames)))
|
||||
prnt('}')
|
||||
prnt()
|
||||
|
||||
_loading_gen_function = _loaded_noop
|
||||
|
||||
def _loaded_gen_function(self, tp, name, module, library):
|
||||
assert isinstance(tp, model.FunctionPtrType)
|
||||
if tp.ellipsis:
|
||||
newfunction = self._load_constant(False, tp, name, module)
|
||||
else:
|
||||
indirections = []
|
||||
base_tp = tp
|
||||
if any(isinstance(typ, model.StructOrUnion) for typ in tp.args):
|
||||
indirect_args = []
|
||||
for i, typ in enumerate(tp.args):
|
||||
if isinstance(typ, model.StructOrUnion):
|
||||
typ = model.PointerType(typ)
|
||||
indirections.append((i, typ))
|
||||
indirect_args.append(typ)
|
||||
tp = model.FunctionPtrType(tuple(indirect_args),
|
||||
tp.result, tp.ellipsis)
|
||||
BFunc = self.ffi._get_cached_btype(tp)
|
||||
wrappername = '_cffi_f_%s' % name
|
||||
newfunction = module.load_function(BFunc, wrappername)
|
||||
for i, typ in indirections:
|
||||
newfunction = self._make_struct_wrapper(newfunction, i, typ,
|
||||
base_tp)
|
||||
setattr(library, name, newfunction)
|
||||
type(library)._cffi_dir.append(name)
|
||||
|
||||
def _make_struct_wrapper(self, oldfunc, i, tp, base_tp):
|
||||
backend = self.ffi._backend
|
||||
BType = self.ffi._get_cached_btype(tp)
|
||||
def newfunc(*args):
|
||||
args = args[:i] + (backend.newp(BType, args[i]),) + args[i+1:]
|
||||
return oldfunc(*args)
|
||||
newfunc._cffi_base_type = base_tp
|
||||
return newfunc
|
||||
|
||||
# ----------
|
||||
# named structs
|
||||
|
||||
def _generate_gen_struct_decl(self, tp, name):
|
||||
assert name == tp.name
|
||||
self._generate_struct_or_union_decl(tp, 'struct', name)
|
||||
|
||||
def _loading_gen_struct(self, tp, name, module):
|
||||
self._loading_struct_or_union(tp, 'struct', name, module)
|
||||
|
||||
def _loaded_gen_struct(self, tp, name, module, **kwds):
|
||||
self._loaded_struct_or_union(tp)
|
||||
|
||||
def _generate_gen_union_decl(self, tp, name):
|
||||
assert name == tp.name
|
||||
self._generate_struct_or_union_decl(tp, 'union', name)
|
||||
|
||||
def _loading_gen_union(self, tp, name, module):
|
||||
self._loading_struct_or_union(tp, 'union', name, module)
|
||||
|
||||
def _loaded_gen_union(self, tp, name, module, **kwds):
|
||||
self._loaded_struct_or_union(tp)
|
||||
|
||||
def _generate_struct_or_union_decl(self, tp, prefix, name):
|
||||
if tp.fldnames is None:
|
||||
return # nothing to do with opaque structs
|
||||
checkfuncname = '_cffi_check_%s_%s' % (prefix, name)
|
||||
layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name)
|
||||
cname = ('%s %s' % (prefix, name)).strip()
|
||||
#
|
||||
prnt = self._prnt
|
||||
prnt('static void %s(%s *p)' % (checkfuncname, cname))
|
||||
prnt('{')
|
||||
prnt(' /* only to generate compile-time warnings or errors */')
|
||||
for fname, ftype, fbitsize in tp.enumfields():
|
||||
if (isinstance(ftype, model.PrimitiveType)
|
||||
and ftype.is_integer_type()) or fbitsize >= 0:
|
||||
# accept all integers, but complain on float or double
|
||||
prnt(' (void)((p->%s) << 1);' % fname)
|
||||
else:
|
||||
# only accept exactly the type declared.
|
||||
try:
|
||||
prnt(' { %s = &p->%s; (void)tmp; }' % (
|
||||
ftype.get_c_name('*tmp', 'field %r'%fname), fname))
|
||||
except ffiplatform.VerificationError as e:
|
||||
prnt(' /* %s */' % str(e)) # cannot verify it, ignore
|
||||
prnt('}')
|
||||
self.export_symbols.append(layoutfuncname)
|
||||
prnt('intptr_t %s(intptr_t i)' % (layoutfuncname,))
|
||||
prnt('{')
|
||||
prnt(' struct _cffi_aligncheck { char x; %s y; };' % cname)
|
||||
prnt(' static intptr_t nums[] = {')
|
||||
prnt(' sizeof(%s),' % cname)
|
||||
prnt(' offsetof(struct _cffi_aligncheck, y),')
|
||||
for fname, ftype, fbitsize in tp.enumfields():
|
||||
if fbitsize >= 0:
|
||||
continue # xxx ignore fbitsize for now
|
||||
prnt(' offsetof(%s, %s),' % (cname, fname))
|
||||
if isinstance(ftype, model.ArrayType) and ftype.length is None:
|
||||
prnt(' 0, /* %s */' % ftype._get_c_name())
|
||||
else:
|
||||
prnt(' sizeof(((%s *)0)->%s),' % (cname, fname))
|
||||
prnt(' -1')
|
||||
prnt(' };')
|
||||
prnt(' return nums[i];')
|
||||
prnt(' /* the next line is not executed, but compiled */')
|
||||
prnt(' %s(0);' % (checkfuncname,))
|
||||
prnt('}')
|
||||
prnt()
|
||||
|
||||
def _loading_struct_or_union(self, tp, prefix, name, module):
|
||||
if tp.fldnames is None:
|
||||
return # nothing to do with opaque structs
|
||||
layoutfuncname = '_cffi_layout_%s_%s' % (prefix, name)
|
||||
#
|
||||
BFunc = self.ffi._typeof_locked("intptr_t(*)(intptr_t)")[0]
|
||||
function = module.load_function(BFunc, layoutfuncname)
|
||||
layout = []
|
||||
num = 0
|
||||
while True:
|
||||
x = function(num)
|
||||
if x < 0: break
|
||||
layout.append(x)
|
||||
num += 1
|
||||
if isinstance(tp, model.StructOrUnion) and tp.partial:
|
||||
# use the function()'s sizes and offsets to guide the
|
||||
# layout of the struct
|
||||
totalsize = layout[0]
|
||||
totalalignment = layout[1]
|
||||
fieldofs = layout[2::2]
|
||||
fieldsize = layout[3::2]
|
||||
tp.force_flatten()
|
||||
assert len(fieldofs) == len(fieldsize) == len(tp.fldnames)
|
||||
tp.fixedlayout = fieldofs, fieldsize, totalsize, totalalignment
|
||||
else:
|
||||
cname = ('%s %s' % (prefix, name)).strip()
|
||||
self._struct_pending_verification[tp] = layout, cname
|
||||
|
||||
def _loaded_struct_or_union(self, tp):
|
||||
if tp.fldnames is None:
|
||||
return # nothing to do with opaque structs
|
||||
self.ffi._get_cached_btype(tp) # force 'fixedlayout' to be considered
|
||||
|
||||
if tp in self._struct_pending_verification:
|
||||
# check that the layout sizes and offsets match the real ones
|
||||
def check(realvalue, expectedvalue, msg):
|
||||
if realvalue != expectedvalue:
|
||||
raise ffiplatform.VerificationError(
|
||||
"%s (we have %d, but C compiler says %d)"
|
||||
% (msg, expectedvalue, realvalue))
|
||||
ffi = self.ffi
|
||||
BStruct = ffi._get_cached_btype(tp)
|
||||
layout, cname = self._struct_pending_verification.pop(tp)
|
||||
check(layout[0], ffi.sizeof(BStruct), "wrong total size")
|
||||
check(layout[1], ffi.alignof(BStruct), "wrong total alignment")
|
||||
i = 2
|
||||
for fname, ftype, fbitsize in tp.enumfields():
|
||||
if fbitsize >= 0:
|
||||
continue # xxx ignore fbitsize for now
|
||||
check(layout[i], ffi.offsetof(BStruct, fname),
|
||||
"wrong offset for field %r" % (fname,))
|
||||
if layout[i+1] != 0:
|
||||
BField = ffi._get_cached_btype(ftype)
|
||||
check(layout[i+1], ffi.sizeof(BField),
|
||||
"wrong size for field %r" % (fname,))
|
||||
i += 2
|
||||
assert i == len(layout)
|
||||
|
||||
# ----------
|
||||
# 'anonymous' declarations. These are produced for anonymous structs
|
||||
# or unions; the 'name' is obtained by a typedef.
|
||||
|
||||
def _generate_gen_anonymous_decl(self, tp, name):
|
||||
if isinstance(tp, model.EnumType):
|
||||
self._generate_gen_enum_decl(tp, name, '')
|
||||
else:
|
||||
self._generate_struct_or_union_decl(tp, '', name)
|
||||
|
||||
def _loading_gen_anonymous(self, tp, name, module):
|
||||
if isinstance(tp, model.EnumType):
|
||||
self._loading_gen_enum(tp, name, module, '')
|
||||
else:
|
||||
self._loading_struct_or_union(tp, '', name, module)
|
||||
|
||||
def _loaded_gen_anonymous(self, tp, name, module, **kwds):
|
||||
if isinstance(tp, model.EnumType):
|
||||
self._loaded_gen_enum(tp, name, module, **kwds)
|
||||
else:
|
||||
self._loaded_struct_or_union(tp)
|
||||
|
||||
# ----------
|
||||
# constants, likely declared with '#define'
|
||||
|
||||
def _generate_gen_const(self, is_int, name, tp=None, category='const'):
|
||||
prnt = self._prnt
|
||||
funcname = '_cffi_%s_%s' % (category, name)
|
||||
self.export_symbols.append(funcname)
|
||||
if is_int:
|
||||
assert category == 'const'
|
||||
prnt('int %s(long long *out_value)' % funcname)
|
||||
prnt('{')
|
||||
prnt(' *out_value = (long long)(%s);' % (name,))
|
||||
prnt(' return (%s) <= 0;' % (name,))
|
||||
prnt('}')
|
||||
else:
|
||||
assert tp is not None
|
||||
prnt(tp.get_c_name(' %s(void)' % funcname, name),)
|
||||
prnt('{')
|
||||
if category == 'var':
|
||||
ampersand = '&'
|
||||
else:
|
||||
ampersand = ''
|
||||
prnt(' return (%s%s);' % (ampersand, name))
|
||||
prnt('}')
|
||||
prnt()
|
||||
|
||||
def _generate_gen_constant_decl(self, tp, name):
|
||||
is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
|
||||
self._generate_gen_const(is_int, name, tp)
|
||||
|
||||
_loading_gen_constant = _loaded_noop
|
||||
|
||||
def _load_constant(self, is_int, tp, name, module):
|
||||
funcname = '_cffi_const_%s' % name
|
||||
if is_int:
|
||||
BType = self.ffi._typeof_locked("long long*")[0]
|
||||
BFunc = self.ffi._typeof_locked("int(*)(long long*)")[0]
|
||||
function = module.load_function(BFunc, funcname)
|
||||
p = self.ffi.new(BType)
|
||||
negative = function(p)
|
||||
value = int(p[0])
|
||||
if value < 0 and not negative:
|
||||
BLongLong = self.ffi._typeof_locked("long long")[0]
|
||||
value += (1 << (8*self.ffi.sizeof(BLongLong)))
|
||||
else:
|
||||
BFunc = self.ffi._typeof_locked(tp.get_c_name('(*)(void)', name))[0]
|
||||
function = module.load_function(BFunc, funcname)
|
||||
value = function()
|
||||
return value
|
||||
|
||||
def _loaded_gen_constant(self, tp, name, module, library):
|
||||
is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
|
||||
value = self._load_constant(is_int, tp, name, module)
|
||||
setattr(library, name, value)
|
||||
type(library)._cffi_dir.append(name)
|
||||
|
||||
# ----------
|
||||
# enums
|
||||
|
||||
def _enum_funcname(self, prefix, name):
|
||||
# "$enum_$1" => "___D_enum____D_1"
|
||||
name = name.replace('$', '___D_')
|
||||
return '_cffi_e_%s_%s' % (prefix, name)
|
||||
|
||||
def _generate_gen_enum_decl(self, tp, name, prefix='enum'):
|
||||
if tp.partial:
|
||||
for enumerator in tp.enumerators:
|
||||
self._generate_gen_const(True, enumerator)
|
||||
return
|
||||
#
|
||||
funcname = self._enum_funcname(prefix, name)
|
||||
self.export_symbols.append(funcname)
|
||||
prnt = self._prnt
|
||||
prnt('int %s(char *out_error)' % funcname)
|
||||
prnt('{')
|
||||
for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues):
|
||||
if enumvalue < 0:
|
||||
prnt(' if ((%s) >= 0 || (long)(%s) != %dL) {' % (
|
||||
enumerator, enumerator, enumvalue))
|
||||
else:
|
||||
prnt(' if ((%s) < 0 || (unsigned long)(%s) != %dUL) {' % (
|
||||
enumerator, enumerator, enumvalue))
|
||||
prnt(' char buf[64];')
|
||||
prnt(' if ((%s) < 0)' % enumerator)
|
||||
prnt(' sprintf(buf, "%%ld", (long)(%s));' % enumerator)
|
||||
prnt(' else')
|
||||
prnt(' sprintf(buf, "%%lu", (unsigned long)(%s));' %
|
||||
enumerator)
|
||||
prnt(' sprintf(out_error,'
|
||||
' "%s has the real value %s, not %s",')
|
||||
prnt(' "%s", buf, "%d");' % (
|
||||
enumerator[:100], enumvalue))
|
||||
prnt(' return -1;')
|
||||
prnt(' }')
|
||||
prnt(' return 0;')
|
||||
prnt('}')
|
||||
prnt()
|
||||
|
||||
def _loading_gen_enum(self, tp, name, module, prefix='enum'):
|
||||
if tp.partial:
|
||||
enumvalues = [self._load_constant(True, tp, enumerator, module)
|
||||
for enumerator in tp.enumerators]
|
||||
tp.enumvalues = tuple(enumvalues)
|
||||
tp.partial_resolved = True
|
||||
else:
|
||||
BType = self.ffi._typeof_locked("char[]")[0]
|
||||
BFunc = self.ffi._typeof_locked("int(*)(char*)")[0]
|
||||
funcname = self._enum_funcname(prefix, name)
|
||||
function = module.load_function(BFunc, funcname)
|
||||
p = self.ffi.new(BType, 256)
|
||||
if function(p) < 0:
|
||||
error = self.ffi.string(p)
|
||||
if sys.version_info >= (3,):
|
||||
error = str(error, 'utf-8')
|
||||
raise ffiplatform.VerificationError(error)
|
||||
|
||||
def _loaded_gen_enum(self, tp, name, module, library):
|
||||
for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues):
|
||||
setattr(library, enumerator, enumvalue)
|
||||
type(library)._cffi_dir.append(enumerator)
|
||||
|
||||
# ----------
|
||||
# macros: for now only for integers
|
||||
|
||||
def _generate_gen_macro_decl(self, tp, name):
|
||||
assert tp == '...'
|
||||
self._generate_gen_const(True, name)
|
||||
|
||||
_loading_gen_macro = _loaded_noop
|
||||
|
||||
def _loaded_gen_macro(self, tp, name, module, library):
|
||||
value = self._load_constant(True, tp, name, module)
|
||||
setattr(library, name, value)
|
||||
type(library)._cffi_dir.append(name)
|
||||
|
||||
# ----------
|
||||
# global variables
|
||||
|
||||
def _generate_gen_variable_decl(self, tp, name):
|
||||
if isinstance(tp, model.ArrayType):
|
||||
if tp.length == '...':
|
||||
prnt = self._prnt
|
||||
funcname = '_cffi_sizeof_%s' % (name,)
|
||||
self.export_symbols.append(funcname)
|
||||
prnt("size_t %s(void)" % funcname)
|
||||
prnt("{")
|
||||
prnt(" return sizeof(%s);" % (name,))
|
||||
prnt("}")
|
||||
tp_ptr = model.PointerType(tp.item)
|
||||
self._generate_gen_const(False, name, tp_ptr)
|
||||
else:
|
||||
tp_ptr = model.PointerType(tp)
|
||||
self._generate_gen_const(False, name, tp_ptr, category='var')
|
||||
|
||||
_loading_gen_variable = _loaded_noop
|
||||
|
||||
def _loaded_gen_variable(self, tp, name, module, library):
|
||||
if isinstance(tp, model.ArrayType): # int a[5] is "constant" in the
|
||||
# sense that "a=..." is forbidden
|
||||
if tp.length == '...':
|
||||
funcname = '_cffi_sizeof_%s' % (name,)
|
||||
BFunc = self.ffi._typeof_locked('size_t(*)(void)')[0]
|
||||
function = module.load_function(BFunc, funcname)
|
||||
size = function()
|
||||
BItemType = self.ffi._get_cached_btype(tp.item)
|
||||
length, rest = divmod(size, self.ffi.sizeof(BItemType))
|
||||
if rest != 0:
|
||||
raise ffiplatform.VerificationError(
|
||||
"bad size: %r does not seem to be an array of %s" %
|
||||
(name, tp.item))
|
||||
tp = tp.resolve_length(length)
|
||||
tp_ptr = model.PointerType(tp.item)
|
||||
value = self._load_constant(False, tp_ptr, name, module)
|
||||
# 'value' is a <cdata 'type *'> which we have to replace with
|
||||
# a <cdata 'type[N]'> if the N is actually known
|
||||
if tp.length is not None:
|
||||
BArray = self.ffi._get_cached_btype(tp)
|
||||
value = self.ffi.cast(BArray, value)
|
||||
setattr(library, name, value)
|
||||
type(library)._cffi_dir.append(name)
|
||||
return
|
||||
# remove ptr=<cdata 'int *'> from the library instance, and replace
|
||||
# it by a property on the class, which reads/writes into ptr[0].
|
||||
funcname = '_cffi_var_%s' % name
|
||||
BFunc = self.ffi._typeof_locked(tp.get_c_name('*(*)(void)', name))[0]
|
||||
function = module.load_function(BFunc, funcname)
|
||||
ptr = function()
|
||||
def getter(library):
|
||||
return ptr[0]
|
||||
def setter(library, value):
|
||||
ptr[0] = value
|
||||
setattr(type(library), name, property(getter, setter))
|
||||
type(library)._cffi_dir.append(name)
|
||||
|
||||
cffimod_header = r'''
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h> /* XXX for ssize_t on some platforms */
|
||||
|
||||
/* this block of #ifs should be kept exactly identical between
|
||||
c/_cffi_backend.c, cffi/vengine_cpy.py, cffi/vengine_gen.py */
|
||||
#if defined(_MSC_VER)
|
||||
# include <malloc.h> /* for alloca() */
|
||||
# if _MSC_VER < 1600 /* MSVC < 2010 */
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# else
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
# if _MSC_VER < 1800 /* MSVC < 2013 */
|
||||
typedef unsigned char _Bool;
|
||||
# endif
|
||||
#else
|
||||
# include <stdint.h>
|
||||
# if (defined (__SVR4) && defined (__sun)) || defined(_AIX)
|
||||
# include <alloca.h>
|
||||
# endif
|
||||
#endif
|
||||
'''
|
|
@ -1,243 +0,0 @@
|
|||
import sys, os, binascii, imp, shutil
|
||||
from . import __version__
|
||||
from . import ffiplatform
|
||||
|
||||
|
||||
class Verifier(object):
|
||||
|
||||
def __init__(self, ffi, preamble, tmpdir=None, modulename=None,
|
||||
ext_package=None, tag='', force_generic_engine=False, **kwds):
|
||||
self.ffi = ffi
|
||||
self.preamble = preamble
|
||||
if not modulename:
|
||||
flattened_kwds = ffiplatform.flatten(kwds)
|
||||
vengine_class = _locate_engine_class(ffi, force_generic_engine)
|
||||
self._vengine = vengine_class(self)
|
||||
self._vengine.patch_extension_kwds(kwds)
|
||||
self.kwds = kwds
|
||||
#
|
||||
if modulename:
|
||||
if tag:
|
||||
raise TypeError("can't specify both 'modulename' and 'tag'")
|
||||
else:
|
||||
key = '\x00'.join([sys.version[:3], __version__, preamble,
|
||||
flattened_kwds] +
|
||||
ffi._cdefsources)
|
||||
if sys.version_info >= (3,):
|
||||
key = key.encode('utf-8')
|
||||
k1 = hex(binascii.crc32(key[0::2]) & 0xffffffff)
|
||||
k1 = k1.lstrip('0x').rstrip('L')
|
||||
k2 = hex(binascii.crc32(key[1::2]) & 0xffffffff)
|
||||
k2 = k2.lstrip('0').rstrip('L')
|
||||
modulename = '_cffi_%s_%s%s%s' % (tag, self._vengine._class_key,
|
||||
k1, k2)
|
||||
suffix = _get_so_suffixes()[0]
|
||||
self.tmpdir = tmpdir or _caller_dir_pycache()
|
||||
self.sourcefilename = os.path.join(self.tmpdir, modulename + '.c')
|
||||
self.modulefilename = os.path.join(self.tmpdir, modulename + suffix)
|
||||
self.ext_package = ext_package
|
||||
self._has_source = False
|
||||
self._has_module = False
|
||||
|
||||
def write_source(self, file=None):
|
||||
"""Write the C source code. It is produced in 'self.sourcefilename',
|
||||
which can be tweaked beforehand."""
|
||||
with self.ffi._lock:
|
||||
if self._has_source and file is None:
|
||||
raise ffiplatform.VerificationError(
|
||||
"source code already written")
|
||||
self._write_source(file)
|
||||
|
||||
def compile_module(self):
|
||||
"""Write the C source code (if not done already) and compile it.
|
||||
This produces a dynamic link library in 'self.modulefilename'."""
|
||||
with self.ffi._lock:
|
||||
if self._has_module:
|
||||
raise ffiplatform.VerificationError("module already compiled")
|
||||
if not self._has_source:
|
||||
self._write_source()
|
||||
self._compile_module()
|
||||
|
||||
def load_library(self):
|
||||
"""Get a C module from this Verifier instance.
|
||||
Returns an instance of a FFILibrary class that behaves like the
|
||||
objects returned by ffi.dlopen(), but that delegates all
|
||||
operations to the C module. If necessary, the C code is written
|
||||
and compiled first.
|
||||
"""
|
||||
with self.ffi._lock:
|
||||
if not self._has_module:
|
||||
self._locate_module()
|
||||
if not self._has_module:
|
||||
if not self._has_source:
|
||||
self._write_source()
|
||||
self._compile_module()
|
||||
return self._load_library()
|
||||
|
||||
def get_module_name(self):
|
||||
basename = os.path.basename(self.modulefilename)
|
||||
# kill both the .so extension and the other .'s, as introduced
|
||||
# by Python 3: 'basename.cpython-33m.so'
|
||||
basename = basename.split('.', 1)[0]
|
||||
# and the _d added in Python 2 debug builds --- but try to be
|
||||
# conservative and not kill a legitimate _d
|
||||
if basename.endswith('_d') and hasattr(sys, 'gettotalrefcount'):
|
||||
basename = basename[:-2]
|
||||
return basename
|
||||
|
||||
def get_extension(self):
|
||||
if not self._has_source:
|
||||
with self.ffi._lock:
|
||||
if not self._has_source:
|
||||
self._write_source()
|
||||
sourcename = ffiplatform.maybe_relative_path(self.sourcefilename)
|
||||
modname = self.get_module_name()
|
||||
return ffiplatform.get_extension(sourcename, modname, **self.kwds)
|
||||
|
||||
def generates_python_module(self):
|
||||
return self._vengine._gen_python_module
|
||||
|
||||
# ----------
|
||||
|
||||
def _locate_module(self):
|
||||
if not os.path.isfile(self.modulefilename):
|
||||
if self.ext_package:
|
||||
try:
|
||||
pkg = __import__(self.ext_package, None, None, ['__doc__'])
|
||||
except ImportError:
|
||||
return # cannot import the package itself, give up
|
||||
# (e.g. it might be called differently before installation)
|
||||
path = pkg.__path__
|
||||
else:
|
||||
path = None
|
||||
filename = self._vengine.find_module(self.get_module_name(), path,
|
||||
_get_so_suffixes())
|
||||
if filename is None:
|
||||
return
|
||||
self.modulefilename = filename
|
||||
self._vengine.collect_types()
|
||||
self._has_module = True
|
||||
|
||||
def _write_source(self, file=None):
|
||||
must_close = (file is None)
|
||||
if must_close:
|
||||
_ensure_dir(self.sourcefilename)
|
||||
file = open(self.sourcefilename, 'w')
|
||||
self._vengine._f = file
|
||||
try:
|
||||
self._vengine.write_source_to_f()
|
||||
finally:
|
||||
del self._vengine._f
|
||||
if must_close:
|
||||
file.close()
|
||||
if must_close:
|
||||
self._has_source = True
|
||||
|
||||
def _compile_module(self):
|
||||
# compile this C source
|
||||
tmpdir = os.path.dirname(self.sourcefilename)
|
||||
outputfilename = ffiplatform.compile(tmpdir, self.get_extension())
|
||||
try:
|
||||
same = ffiplatform.samefile(outputfilename, self.modulefilename)
|
||||
except OSError:
|
||||
same = False
|
||||
if not same:
|
||||
_ensure_dir(self.modulefilename)
|
||||
shutil.move(outputfilename, self.modulefilename)
|
||||
self._has_module = True
|
||||
|
||||
def _load_library(self):
|
||||
assert self._has_module
|
||||
return self._vengine.load_library()
|
||||
|
||||
# ____________________________________________________________
|
||||
|
||||
_FORCE_GENERIC_ENGINE = False # for tests
|
||||
|
||||
def _locate_engine_class(ffi, force_generic_engine):
|
||||
if _FORCE_GENERIC_ENGINE:
|
||||
force_generic_engine = True
|
||||
if not force_generic_engine:
|
||||
if '__pypy__' in sys.builtin_module_names:
|
||||
force_generic_engine = True
|
||||
else:
|
||||
try:
|
||||
import _cffi_backend
|
||||
except ImportError:
|
||||
_cffi_backend = '?'
|
||||
if ffi._backend is not _cffi_backend:
|
||||
force_generic_engine = True
|
||||
if force_generic_engine:
|
||||
from . import vengine_gen
|
||||
return vengine_gen.VGenericEngine
|
||||
else:
|
||||
from . import vengine_cpy
|
||||
return vengine_cpy.VCPythonEngine
|
||||
|
||||
# ____________________________________________________________
|
||||
|
||||
_TMPDIR = None
|
||||
|
||||
def _caller_dir_pycache():
|
||||
if _TMPDIR:
|
||||
return _TMPDIR
|
||||
filename = sys._getframe(2).f_code.co_filename
|
||||
return os.path.abspath(os.path.join(os.path.dirname(filename),
|
||||
'__pycache__'))
|
||||
|
||||
def set_tmpdir(dirname):
|
||||
"""Set the temporary directory to use instead of __pycache__."""
|
||||
global _TMPDIR
|
||||
_TMPDIR = dirname
|
||||
|
||||
def cleanup_tmpdir(tmpdir=None, keep_so=False):
|
||||
"""Clean up the temporary directory by removing all files in it
|
||||
called `_cffi_*.{c,so}` as well as the `build` subdirectory."""
|
||||
tmpdir = tmpdir or _caller_dir_pycache()
|
||||
try:
|
||||
filelist = os.listdir(tmpdir)
|
||||
except OSError:
|
||||
return
|
||||
if keep_so:
|
||||
suffix = '.c' # only remove .c files
|
||||
else:
|
||||
suffix = _get_so_suffixes()[0].lower()
|
||||
for fn in filelist:
|
||||
if fn.lower().startswith('_cffi_') and (
|
||||
fn.lower().endswith(suffix) or fn.lower().endswith('.c')):
|
||||
try:
|
||||
os.unlink(os.path.join(tmpdir, fn))
|
||||
except OSError:
|
||||
pass
|
||||
clean_dir = [os.path.join(tmpdir, 'build')]
|
||||
for dir in clean_dir:
|
||||
try:
|
||||
for fn in os.listdir(dir):
|
||||
fn = os.path.join(dir, fn)
|
||||
if os.path.isdir(fn):
|
||||
clean_dir.append(fn)
|
||||
else:
|
||||
os.unlink(fn)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def _get_so_suffixes():
|
||||
suffixes = []
|
||||
for suffix, mode, type in imp.get_suffixes():
|
||||
if type == imp.C_EXTENSION:
|
||||
suffixes.append(suffix)
|
||||
|
||||
if not suffixes:
|
||||
# bah, no C_EXTENSION available. Occurs on pypy without cpyext
|
||||
if sys.platform == 'win32':
|
||||
suffixes = [".pyd"]
|
||||
else:
|
||||
suffixes = [".so"]
|
||||
|
||||
return suffixes
|
||||
|
||||
def _ensure_dir(filename):
|
||||
try:
|
||||
os.makedirs(os.path.dirname(filename))
|
||||
except OSError:
|
||||
pass
|
|
@ -1,84 +0,0 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: cryptography
|
||||
Version: 0.6
|
||||
Summary: cryptography is a package which provides cryptographic recipes and primitives to Python developers.
|
||||
Home-page: https://github.com/pyca/cryptography
|
||||
Author: The cryptography developers
|
||||
Author-email: cryptography-dev@python.org
|
||||
License: Apache License, Version 2.0
|
||||
Description: Cryptography
|
||||
============
|
||||
|
||||
.. image:: https://pypip.in/version/cryptography/badge.svg
|
||||
:target: https://pypi.python.org/pypi/cryptography/
|
||||
:alt: Latest Version
|
||||
|
||||
.. image:: https://readthedocs.org/projects/cryptography/badge/?version=latest
|
||||
:target: https://cryptography.io
|
||||
:alt: Latest Docs
|
||||
|
||||
.. image:: https://travis-ci.org/pyca/cryptography.svg?branch=master
|
||||
:target: https://travis-ci.org/pyca/cryptography
|
||||
|
||||
.. image:: https://coveralls.io/repos/pyca/cryptography/badge.png?branch=master
|
||||
:target: https://coveralls.io/r/pyca/cryptography?branch=master
|
||||
|
||||
|
||||
``cryptography`` is a package which provides cryptographic recipes and
|
||||
primitives to Python developers. Our goal is for it to be your "cryptographic
|
||||
standard library". It supports Python 2.6-2.7, Python 3.2+, and PyPy.
|
||||
|
||||
``cryptography`` includes both high level recipes, and low level interfaces to
|
||||
common cryptographic algorithms such as symmetric ciphers, message digests and
|
||||
key derivation functions. For example, to encrypt something with
|
||||
``cryptography``'s high level symmetric encryption recipe:
|
||||
|
||||
.. code-block:: pycon
|
||||
|
||||
>>> from cryptography.fernet import Fernet
|
||||
>>> # Put this somewhere safe!
|
||||
>>> key = Fernet.generate_key()
|
||||
>>> f = Fernet(key)
|
||||
>>> token = f.encrypt(b"A really secret message. Not for prying eyes.")
|
||||
>>> token
|
||||
'...'
|
||||
>>> f.decrypt(token)
|
||||
'A really secret message. Not for prying eyes.'
|
||||
|
||||
You can find more information in the `documentation`_.
|
||||
|
||||
Discussion
|
||||
~~~~~~~~~~
|
||||
|
||||
If you run into bugs, you can file them in our `issue tracker`_.
|
||||
|
||||
We maintain a `cryptography-dev`_ mailing list for development discussion.
|
||||
|
||||
You can also join ``#cryptography-dev`` on Freenode to ask questions or get
|
||||
involved.
|
||||
|
||||
|
||||
.. _`documentation`: https://cryptography.io/
|
||||
.. _`issue tracker`: https://github.com/pyca/cryptography/issues
|
||||
.. _`cryptography-dev`: https://mail.python.org/mailman/listinfo/cryptography-dev
|
||||
|
||||
Platform: UNKNOWN
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: Apache Software License
|
||||
Classifier: Natural Language :: English
|
||||
Classifier: Operating System :: MacOS :: MacOS X
|
||||
Classifier: Operating System :: POSIX
|
||||
Classifier: Operating System :: POSIX :: BSD
|
||||
Classifier: Operating System :: POSIX :: Linux
|
||||
Classifier: Operating System :: Microsoft :: Windows
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.2
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||
Classifier: Topic :: Security :: Cryptography
|
|
@ -1,217 +0,0 @@
|
|||
AUTHORS.rst
|
||||
CHANGELOG.rst
|
||||
CONTRIBUTING.rst
|
||||
LICENSE
|
||||
MANIFEST.in
|
||||
README.rst
|
||||
setup.cfg
|
||||
setup.py
|
||||
cryptography/__about__.py
|
||||
cryptography/__init__.py
|
||||
cryptography/exceptions.py
|
||||
cryptography/fernet.py
|
||||
cryptography/utils.py
|
||||
cryptography.egg-info/PKG-INFO
|
||||
cryptography.egg-info/SOURCES.txt
|
||||
cryptography.egg-info/dependency_links.txt
|
||||
cryptography.egg-info/entry_points.txt
|
||||
cryptography.egg-info/not-zip-safe
|
||||
cryptography.egg-info/requires.txt
|
||||
cryptography.egg-info/top_level.txt
|
||||
cryptography/hazmat/__init__.py
|
||||
cryptography/hazmat/backends/__init__.py
|
||||
cryptography/hazmat/backends/interfaces.py
|
||||
cryptography/hazmat/backends/multibackend.py
|
||||
cryptography/hazmat/backends/commoncrypto/__init__.py
|
||||
cryptography/hazmat/backends/commoncrypto/backend.py
|
||||
cryptography/hazmat/backends/commoncrypto/ciphers.py
|
||||
cryptography/hazmat/backends/commoncrypto/hashes.py
|
||||
cryptography/hazmat/backends/commoncrypto/hmac.py
|
||||
cryptography/hazmat/backends/openssl/__init__.py
|
||||
cryptography/hazmat/backends/openssl/backend.py
|
||||
cryptography/hazmat/backends/openssl/ciphers.py
|
||||
cryptography/hazmat/backends/openssl/cmac.py
|
||||
cryptography/hazmat/backends/openssl/dsa.py
|
||||
cryptography/hazmat/backends/openssl/ec.py
|
||||
cryptography/hazmat/backends/openssl/hashes.py
|
||||
cryptography/hazmat/backends/openssl/hmac.py
|
||||
cryptography/hazmat/backends/openssl/rsa.py
|
||||
cryptography/hazmat/bindings/__init__.py
|
||||
cryptography/hazmat/bindings/utils.py
|
||||
cryptography/hazmat/bindings/__pycache__/_Cryptography_cffi_3e31f141x4000d087.c
|
||||
cryptography/hazmat/bindings/commoncrypto/__init__.py
|
||||
cryptography/hazmat/bindings/commoncrypto/binding.py
|
||||
cryptography/hazmat/bindings/commoncrypto/cf.py
|
||||
cryptography/hazmat/bindings/commoncrypto/common_cryptor.py
|
||||
cryptography/hazmat/bindings/commoncrypto/common_digest.py
|
||||
cryptography/hazmat/bindings/commoncrypto/common_hmac.py
|
||||
cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py
|
||||
cryptography/hazmat/bindings/commoncrypto/secimport.py
|
||||
cryptography/hazmat/bindings/commoncrypto/secitem.py
|
||||
cryptography/hazmat/bindings/commoncrypto/seckey.py
|
||||
cryptography/hazmat/bindings/commoncrypto/seckeychain.py
|
||||
cryptography/hazmat/bindings/commoncrypto/sectransform.py
|
||||
cryptography/hazmat/bindings/openssl/__init__.py
|
||||
cryptography/hazmat/bindings/openssl/aes.py
|
||||
cryptography/hazmat/bindings/openssl/asn1.py
|
||||
cryptography/hazmat/bindings/openssl/bignum.py
|
||||
cryptography/hazmat/bindings/openssl/binding.py
|
||||
cryptography/hazmat/bindings/openssl/bio.py
|
||||
cryptography/hazmat/bindings/openssl/cmac.py
|
||||
cryptography/hazmat/bindings/openssl/cms.py
|
||||
cryptography/hazmat/bindings/openssl/conf.py
|
||||
cryptography/hazmat/bindings/openssl/crypto.py
|
||||
cryptography/hazmat/bindings/openssl/dh.py
|
||||
cryptography/hazmat/bindings/openssl/dsa.py
|
||||
cryptography/hazmat/bindings/openssl/ec.py
|
||||
cryptography/hazmat/bindings/openssl/ecdh.py
|
||||
cryptography/hazmat/bindings/openssl/ecdsa.py
|
||||
cryptography/hazmat/bindings/openssl/engine.py
|
||||
cryptography/hazmat/bindings/openssl/err.py
|
||||
cryptography/hazmat/bindings/openssl/evp.py
|
||||
cryptography/hazmat/bindings/openssl/hmac.py
|
||||
cryptography/hazmat/bindings/openssl/nid.py
|
||||
cryptography/hazmat/bindings/openssl/objects.py
|
||||
cryptography/hazmat/bindings/openssl/opensslv.py
|
||||
cryptography/hazmat/bindings/openssl/osrandom_engine.py
|
||||
cryptography/hazmat/bindings/openssl/pem.py
|
||||
cryptography/hazmat/bindings/openssl/pkcs12.py
|
||||
cryptography/hazmat/bindings/openssl/pkcs7.py
|
||||
cryptography/hazmat/bindings/openssl/rand.py
|
||||
cryptography/hazmat/bindings/openssl/rsa.py
|
||||
cryptography/hazmat/bindings/openssl/ssl.py
|
||||
cryptography/hazmat/bindings/openssl/x509.py
|
||||
cryptography/hazmat/bindings/openssl/x509_vfy.py
|
||||
cryptography/hazmat/bindings/openssl/x509name.py
|
||||
cryptography/hazmat/bindings/openssl/x509v3.py
|
||||
cryptography/hazmat/primitives/__init__.py
|
||||
cryptography/hazmat/primitives/cmac.py
|
||||
cryptography/hazmat/primitives/constant_time.py
|
||||
cryptography/hazmat/primitives/hashes.py
|
||||
cryptography/hazmat/primitives/hmac.py
|
||||
cryptography/hazmat/primitives/interfaces.py
|
||||
cryptography/hazmat/primitives/padding.py
|
||||
cryptography/hazmat/primitives/serialization.py
|
||||
cryptography/hazmat/primitives/__pycache__/_Cryptography_cffi_7ab3712bx4f158fee.c
|
||||
cryptography/hazmat/primitives/__pycache__/_Cryptography_cffi_dd416c1exc1767c5a.c
|
||||
cryptography/hazmat/primitives/asymmetric/__init__.py
|
||||
cryptography/hazmat/primitives/asymmetric/dsa.py
|
||||
cryptography/hazmat/primitives/asymmetric/ec.py
|
||||
cryptography/hazmat/primitives/asymmetric/padding.py
|
||||
cryptography/hazmat/primitives/asymmetric/rsa.py
|
||||
cryptography/hazmat/primitives/ciphers/__init__.py
|
||||
cryptography/hazmat/primitives/ciphers/algorithms.py
|
||||
cryptography/hazmat/primitives/ciphers/base.py
|
||||
cryptography/hazmat/primitives/ciphers/modes.py
|
||||
cryptography/hazmat/primitives/kdf/__init__.py
|
||||
cryptography/hazmat/primitives/kdf/hkdf.py
|
||||
cryptography/hazmat/primitives/kdf/pbkdf2.py
|
||||
cryptography/hazmat/primitives/src/constant_time.c
|
||||
cryptography/hazmat/primitives/src/constant_time.h
|
||||
cryptography/hazmat/primitives/twofactor/__init__.py
|
||||
cryptography/hazmat/primitives/twofactor/hotp.py
|
||||
cryptography/hazmat/primitives/twofactor/totp.py
|
||||
docs/Makefile
|
||||
docs/api-stability.rst
|
||||
docs/changelog.rst
|
||||
docs/community.rst
|
||||
docs/conf.py
|
||||
docs/cryptography-docs.py
|
||||
docs/doing-a-release.rst
|
||||
docs/exceptions.rst
|
||||
docs/faq.rst
|
||||
docs/fernet.rst
|
||||
docs/glossary.rst
|
||||
docs/index.rst
|
||||
docs/installation.rst
|
||||
docs/limitations.rst
|
||||
docs/make.bat
|
||||
docs/random-numbers.rst
|
||||
docs/security.rst
|
||||
docs/spelling_wordlist.txt
|
||||
docs/_static/.keep
|
||||
docs/development/c-bindings.rst
|
||||
docs/development/getting-started.rst
|
||||
docs/development/index.rst
|
||||
docs/development/reviewing-patches.rst
|
||||
docs/development/submitting-patches.rst
|
||||
docs/development/test-vectors.rst
|
||||
docs/development/custom-vectors/cast5.rst
|
||||
docs/development/custom-vectors/idea.rst
|
||||
docs/development/custom-vectors/seed.rst
|
||||
docs/development/custom-vectors/cast5/generate_cast5.py
|
||||
docs/development/custom-vectors/cast5/verify_cast5.go
|
||||
docs/development/custom-vectors/idea/generate_idea.py
|
||||
docs/development/custom-vectors/idea/verify_idea.py
|
||||
docs/development/custom-vectors/seed/generate_seed.py
|
||||
docs/development/custom-vectors/seed/verify_seed.py
|
||||
docs/hazmat/backends/commoncrypto.rst
|
||||
docs/hazmat/backends/index.rst
|
||||
docs/hazmat/backends/interfaces.rst
|
||||
docs/hazmat/backends/multibackend.rst
|
||||
docs/hazmat/backends/openssl.rst
|
||||
docs/hazmat/bindings/commoncrypto.rst
|
||||
docs/hazmat/bindings/index.rst
|
||||
docs/hazmat/bindings/openssl.rst
|
||||
docs/hazmat/primitives/constant-time.rst
|
||||
docs/hazmat/primitives/cryptographic-hashes.rst
|
||||
docs/hazmat/primitives/index.rst
|
||||
docs/hazmat/primitives/interfaces.rst
|
||||
docs/hazmat/primitives/key-derivation-functions.rst
|
||||
docs/hazmat/primitives/padding.rst
|
||||
docs/hazmat/primitives/symmetric-encryption.rst
|
||||
docs/hazmat/primitives/twofactor.rst
|
||||
docs/hazmat/primitives/asymmetric/dsa.rst
|
||||
docs/hazmat/primitives/asymmetric/ec.rst
|
||||
docs/hazmat/primitives/asymmetric/index.rst
|
||||
docs/hazmat/primitives/asymmetric/padding.rst
|
||||
docs/hazmat/primitives/asymmetric/rsa.rst
|
||||
docs/hazmat/primitives/asymmetric/serialization.rst
|
||||
docs/hazmat/primitives/mac/cmac.rst
|
||||
docs/hazmat/primitives/mac/hmac.rst
|
||||
docs/hazmat/primitives/mac/index.rst
|
||||
tests/__init__.py
|
||||
tests/conftest.py
|
||||
tests/test_fernet.py
|
||||
tests/test_utils.py
|
||||
tests/utils.py
|
||||
tests/hazmat/__init__.py
|
||||
tests/hazmat/backends/__init__.py
|
||||
tests/hazmat/backends/test_commoncrypto.py
|
||||
tests/hazmat/backends/test_multibackend.py
|
||||
tests/hazmat/backends/test_openssl.py
|
||||
tests/hazmat/bindings/test_commoncrypto.py
|
||||
tests/hazmat/bindings/test_openssl.py
|
||||
tests/hazmat/bindings/test_utils.py
|
||||
tests/hazmat/primitives/__init__.py
|
||||
tests/hazmat/primitives/fixtures_dsa.py
|
||||
tests/hazmat/primitives/fixtures_rsa.py
|
||||
tests/hazmat/primitives/test_3des.py
|
||||
tests/hazmat/primitives/test_aes.py
|
||||
tests/hazmat/primitives/test_arc4.py
|
||||
tests/hazmat/primitives/test_block.py
|
||||
tests/hazmat/primitives/test_blowfish.py
|
||||
tests/hazmat/primitives/test_camellia.py
|
||||
tests/hazmat/primitives/test_cast5.py
|
||||
tests/hazmat/primitives/test_ciphers.py
|
||||
tests/hazmat/primitives/test_cmac.py
|
||||
tests/hazmat/primitives/test_constant_time.py
|
||||
tests/hazmat/primitives/test_dsa.py
|
||||
tests/hazmat/primitives/test_ec.py
|
||||
tests/hazmat/primitives/test_hash_vectors.py
|
||||
tests/hazmat/primitives/test_hashes.py
|
||||
tests/hazmat/primitives/test_hkdf.py
|
||||
tests/hazmat/primitives/test_hkdf_vectors.py
|
||||
tests/hazmat/primitives/test_hmac.py
|
||||
tests/hazmat/primitives/test_hmac_vectors.py
|
||||
tests/hazmat/primitives/test_idea.py
|
||||
tests/hazmat/primitives/test_padding.py
|
||||
tests/hazmat/primitives/test_pbkdf2hmac.py
|
||||
tests/hazmat/primitives/test_pbkdf2hmac_vectors.py
|
||||
tests/hazmat/primitives/test_rsa.py
|
||||
tests/hazmat/primitives/test_seed.py
|
||||
tests/hazmat/primitives/test_serialization.py
|
||||
tests/hazmat/primitives/utils.py
|
||||
tests/hazmat/primitives/twofactor/__init__.py
|
||||
tests/hazmat/primitives/twofactor/test_hotp.py
|
||||
tests/hazmat/primitives/twofactor/test_totp.py
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
[cryptography.backends]
|
||||
openssl = cryptography.hazmat.backends.openssl:backend
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
../cryptography/utils.py
|
||||
../cryptography/__about__.py
|
||||
../cryptography/__init__.py
|
||||
../cryptography/exceptions.py
|
||||
../cryptography/fernet.py
|
||||
../cryptography/hazmat/__init__.py
|
||||
../cryptography/hazmat/bindings/utils.py
|
||||
../cryptography/hazmat/bindings/__init__.py
|
||||
../cryptography/hazmat/primitives/interfaces.py
|
||||
../cryptography/hazmat/primitives/constant_time.py
|
||||
../cryptography/hazmat/primitives/__init__.py
|
||||
../cryptography/hazmat/primitives/hashes.py
|
||||
../cryptography/hazmat/primitives/hmac.py
|
||||
../cryptography/hazmat/primitives/padding.py
|
||||
../cryptography/hazmat/primitives/serialization.py
|
||||
../cryptography/hazmat/primitives/cmac.py
|
||||
../cryptography/hazmat/backends/interfaces.py
|
||||
../cryptography/hazmat/backends/multibackend.py
|
||||
../cryptography/hazmat/backends/__init__.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/secimport.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/common_cryptor.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/seckeychain.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/common_hmac.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/__init__.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/sectransform.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/binding.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/common_digest.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/seckey.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/secitem.py
|
||||
../cryptography/hazmat/bindings/commoncrypto/cf.py
|
||||
../cryptography/hazmat/bindings/openssl/opensslv.py
|
||||
../cryptography/hazmat/bindings/openssl/ec.py
|
||||
../cryptography/hazmat/bindings/openssl/x509_vfy.py
|
||||
../cryptography/hazmat/bindings/openssl/aes.py
|
||||
../cryptography/hazmat/bindings/openssl/asn1.py
|
||||
../cryptography/hazmat/bindings/openssl/objects.py
|
||||
../cryptography/hazmat/bindings/openssl/dsa.py
|
||||
../cryptography/hazmat/bindings/openssl/x509name.py
|
||||
../cryptography/hazmat/bindings/openssl/osrandom_engine.py
|
||||
../cryptography/hazmat/bindings/openssl/rand.py
|
||||
../cryptography/hazmat/bindings/openssl/cms.py
|
||||
../cryptography/hazmat/bindings/openssl/engine.py
|
||||
../cryptography/hazmat/bindings/openssl/__init__.py
|
||||
../cryptography/hazmat/bindings/openssl/ssl.py
|
||||
../cryptography/hazmat/bindings/openssl/nid.py
|
||||
../cryptography/hazmat/bindings/openssl/x509v3.py
|
||||
../cryptography/hazmat/bindings/openssl/err.py
|
||||
../cryptography/hazmat/bindings/openssl/bio.py
|
||||
../cryptography/hazmat/bindings/openssl/ecdsa.py
|
||||
../cryptography/hazmat/bindings/openssl/pkcs7.py
|
||||
../cryptography/hazmat/bindings/openssl/bignum.py
|
||||
../cryptography/hazmat/bindings/openssl/binding.py
|
||||
../cryptography/hazmat/bindings/openssl/pem.py
|
||||
../cryptography/hazmat/bindings/openssl/rsa.py
|
||||
../cryptography/hazmat/bindings/openssl/hmac.py
|
||||
../cryptography/hazmat/bindings/openssl/conf.py
|
||||
../cryptography/hazmat/bindings/openssl/dh.py
|
||||
../cryptography/hazmat/bindings/openssl/x509.py
|
||||
../cryptography/hazmat/bindings/openssl/ecdh.py
|
||||
../cryptography/hazmat/bindings/openssl/evp.py
|
||||
../cryptography/hazmat/bindings/openssl/cmac.py
|
||||
../cryptography/hazmat/bindings/openssl/crypto.py
|
||||
../cryptography/hazmat/bindings/openssl/pkcs12.py
|
||||
../cryptography/hazmat/primitives/kdf/__init__.py
|
||||
../cryptography/hazmat/primitives/kdf/hkdf.py
|
||||
../cryptography/hazmat/primitives/kdf/pbkdf2.py
|
||||
../cryptography/hazmat/primitives/asymmetric/ec.py
|
||||
../cryptography/hazmat/primitives/asymmetric/dsa.py
|
||||
../cryptography/hazmat/primitives/asymmetric/__init__.py
|
||||
../cryptography/hazmat/primitives/asymmetric/rsa.py
|
||||
../cryptography/hazmat/primitives/asymmetric/padding.py
|
||||
../cryptography/hazmat/primitives/ciphers/base.py
|
||||
../cryptography/hazmat/primitives/ciphers/__init__.py
|
||||
../cryptography/hazmat/primitives/ciphers/modes.py
|
||||
../cryptography/hazmat/primitives/ciphers/algorithms.py
|
||||
../cryptography/hazmat/primitives/twofactor/__init__.py
|
||||
../cryptography/hazmat/primitives/twofactor/totp.py
|
||||
../cryptography/hazmat/primitives/twofactor/hotp.py
|
||||
../cryptography/hazmat/backends/commoncrypto/backend.py
|
||||
../cryptography/hazmat/backends/commoncrypto/__init__.py
|
||||
../cryptography/hazmat/backends/commoncrypto/hashes.py
|
||||
../cryptography/hazmat/backends/commoncrypto/hmac.py
|
||||
../cryptography/hazmat/backends/commoncrypto/ciphers.py
|
||||
../cryptography/hazmat/backends/openssl/ec.py
|
||||
../cryptography/hazmat/backends/openssl/dsa.py
|
||||
../cryptography/hazmat/backends/openssl/backend.py
|
||||
../cryptography/hazmat/backends/openssl/__init__.py
|
||||
../cryptography/hazmat/backends/openssl/hashes.py
|
||||
../cryptography/hazmat/backends/openssl/rsa.py
|
||||
../cryptography/hazmat/backends/openssl/hmac.py
|
||||
../cryptography/hazmat/backends/openssl/cmac.py
|
||||
../cryptography/hazmat/backends/openssl/ciphers.py
|
||||
../cryptography/hazmat/bindings/__pycache__/_Cryptography_cffi_3e31f141x4000d087.c
|
||||
../cryptography/hazmat/primitives/__pycache__/_Cryptography_cffi_7ab3712bx4f158fee.c
|
||||
../cryptography/hazmat/primitives/__pycache__/_Cryptography_cffi_dd416c1exc1767c5a.c
|
||||
../cryptography/hazmat/primitives/src/constant_time.c
|
||||
../cryptography/hazmat/primitives/src/constant_time.h
|
||||
../cryptography/__pycache__/utils.cpython-34.pyc
|
||||
../cryptography/__pycache__/__about__.cpython-34.pyc
|
||||
../cryptography/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/__pycache__/exceptions.cpython-34.pyc
|
||||
../cryptography/__pycache__/fernet.cpython-34.pyc
|
||||
../cryptography/hazmat/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/__pycache__/utils.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/__pycache__/interfaces.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/__pycache__/constant_time.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/__pycache__/hashes.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/__pycache__/hmac.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/__pycache__/padding.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/__pycache__/serialization.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/__pycache__/cmac.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/__pycache__/interfaces.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/__pycache__/multibackend.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/secimport.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/common_cryptor.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/seckeychain.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/common_hmac.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/common_key_derivation.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/sectransform.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/binding.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/common_digest.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/seckey.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/secitem.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/commoncrypto/__pycache__/cf.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/opensslv.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/ec.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/x509_vfy.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/aes.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/asn1.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/objects.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/dsa.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/x509name.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/osrandom_engine.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/rand.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/cms.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/engine.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/ssl.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/nid.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/x509v3.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/err.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/bio.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/ecdsa.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/pkcs7.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/bignum.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/binding.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/pem.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/rsa.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/hmac.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/conf.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/dh.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/x509.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/ecdh.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/evp.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/cmac.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/crypto.cpython-34.pyc
|
||||
../cryptography/hazmat/bindings/openssl/__pycache__/pkcs12.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/kdf/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/kdf/__pycache__/hkdf.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/kdf/__pycache__/pbkdf2.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/asymmetric/__pycache__/ec.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/asymmetric/__pycache__/dsa.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/asymmetric/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/asymmetric/__pycache__/rsa.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/asymmetric/__pycache__/padding.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/ciphers/__pycache__/base.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/ciphers/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/ciphers/__pycache__/modes.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/ciphers/__pycache__/algorithms.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/twofactor/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/twofactor/__pycache__/totp.cpython-34.pyc
|
||||
../cryptography/hazmat/primitives/twofactor/__pycache__/hotp.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/commoncrypto/__pycache__/backend.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/commoncrypto/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/commoncrypto/__pycache__/hashes.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/commoncrypto/__pycache__/hmac.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/commoncrypto/__pycache__/ciphers.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/openssl/__pycache__/ec.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/openssl/__pycache__/dsa.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/openssl/__pycache__/backend.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/openssl/__pycache__/__init__.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/openssl/__pycache__/hashes.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/openssl/__pycache__/rsa.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/openssl/__pycache__/hmac.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/openssl/__pycache__/cmac.cpython-34.pyc
|
||||
../cryptography/hazmat/backends/openssl/__pycache__/ciphers.cpython-34.pyc
|
||||
../cryptography/_Cryptography_cffi_3e31f141x4000d087.cpython-34m.so
|
||||
../cryptography/_Cryptography_cffi_7ab3712bx4f158fee.cpython-34m.so
|
||||
../cryptography/_Cryptography_cffi_dd416c1exc1767c5a.cpython-34m.so
|
||||
./
|
||||
dependency_links.txt
|
||||
entry_points.txt
|
||||
PKG-INFO
|
||||
SOURCES.txt
|
||||
not-zip-safe
|
||||
top_level.txt
|
||||
requires.txt
|
|
@ -1,3 +0,0 @@
|
|||
cffi>=0.8
|
||||
six>=1.4.1
|
||||
setuptools
|
|
@ -1,4 +0,0 @@
|
|||
_Cryptography_cffi_7ab3712bx4f158fee
|
||||
_Cryptography_cffi_3e31f141x4000d087
|
||||
cryptography
|
||||
_Cryptography_cffi_dd416c1exc1767c5a
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,31 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__all__ = [
|
||||
"__title__", "__summary__", "__uri__", "__version__", "__author__",
|
||||
"__email__", "__license__", "__copyright__",
|
||||
]
|
||||
|
||||
__title__ = "cryptography"
|
||||
__summary__ = ("cryptography is a package which provides cryptographic recipes"
|
||||
" and primitives to Python developers.")
|
||||
__uri__ = "https://github.com/pyca/cryptography"
|
||||
|
||||
__version__ = "0.6"
|
||||
|
||||
__author__ = "The cryptography developers"
|
||||
__email__ = "cryptography-dev@python.org"
|
||||
|
||||
__license__ = "Apache License, Version 2.0"
|
||||
__copyright__ = "Copyright 2013-2014 {0}".format(__author__)
|
|
@ -1,25 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography.__about__ import (
|
||||
__author__, __copyright__, __email__, __license__, __summary__, __title__,
|
||||
__uri__, __version__
|
||||
)
|
||||
|
||||
|
||||
__all__ = [
|
||||
"__title__", "__summary__", "__uri__", "__version__", "__author__",
|
||||
"__email__", "__license__", "__copyright__",
|
||||
]
|
|
@ -1,63 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
class _Reasons(object):
|
||||
BACKEND_MISSING_INTERFACE = object()
|
||||
UNSUPPORTED_HASH = object()
|
||||
UNSUPPORTED_CIPHER = object()
|
||||
UNSUPPORTED_PADDING = object()
|
||||
UNSUPPORTED_MGF = object()
|
||||
UNSUPPORTED_PUBLIC_KEY_ALGORITHM = object()
|
||||
UNSUPPORTED_ELLIPTIC_CURVE = object()
|
||||
UNSUPPORTED_SERIALIZATION = object()
|
||||
|
||||
|
||||
class UnsupportedAlgorithm(Exception):
|
||||
def __init__(self, message, reason=None):
|
||||
super(UnsupportedAlgorithm, self).__init__(message)
|
||||
self._reason = reason
|
||||
|
||||
|
||||
class AlreadyFinalized(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class AlreadyUpdated(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NotYetFinalized(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidTag(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidSignature(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class InternalError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidKey(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidToken(Exception):
|
||||
pass
|
|
@ -1,129 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import base64
|
||||
import binascii
|
||||
import os
|
||||
import struct
|
||||
import time
|
||||
|
||||
import six
|
||||
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import hashes, padding
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
from cryptography.hazmat.primitives.hmac import HMAC
|
||||
|
||||
|
||||
class InvalidToken(Exception):
|
||||
pass
|
||||
|
||||
|
||||
_MAX_CLOCK_SKEW = 60
|
||||
|
||||
|
||||
class Fernet(object):
|
||||
def __init__(self, key, backend=None):
|
||||
if backend is None:
|
||||
backend = default_backend()
|
||||
|
||||
key = base64.urlsafe_b64decode(key)
|
||||
if len(key) != 32:
|
||||
raise ValueError(
|
||||
"Fernet key must be 32 url-safe base64-encoded bytes."
|
||||
)
|
||||
|
||||
self._signing_key = key[:16]
|
||||
self._encryption_key = key[16:]
|
||||
self._backend = backend
|
||||
|
||||
@classmethod
|
||||
def generate_key(cls):
|
||||
return base64.urlsafe_b64encode(os.urandom(32))
|
||||
|
||||
def encrypt(self, data):
|
||||
current_time = int(time.time())
|
||||
iv = os.urandom(16)
|
||||
return self._encrypt_from_parts(data, current_time, iv)
|
||||
|
||||
def _encrypt_from_parts(self, data, current_time, iv):
|
||||
if not isinstance(data, bytes):
|
||||
raise TypeError("data must be bytes.")
|
||||
|
||||
padder = padding.PKCS7(algorithms.AES.block_size).padder()
|
||||
padded_data = padder.update(data) + padder.finalize()
|
||||
encryptor = Cipher(
|
||||
algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
|
||||
).encryptor()
|
||||
ciphertext = encryptor.update(padded_data) + encryptor.finalize()
|
||||
|
||||
basic_parts = (
|
||||
b"\x80" + struct.pack(">Q", current_time) + iv + ciphertext
|
||||
)
|
||||
|
||||
h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
|
||||
h.update(basic_parts)
|
||||
hmac = h.finalize()
|
||||
return base64.urlsafe_b64encode(basic_parts + hmac)
|
||||
|
||||
def decrypt(self, token, ttl=None):
|
||||
if not isinstance(token, bytes):
|
||||
raise TypeError("token must be bytes.")
|
||||
|
||||
current_time = int(time.time())
|
||||
|
||||
try:
|
||||
data = base64.urlsafe_b64decode(token)
|
||||
except (TypeError, binascii.Error):
|
||||
raise InvalidToken
|
||||
|
||||
if six.indexbytes(data, 0) != 0x80:
|
||||
raise InvalidToken
|
||||
|
||||
try:
|
||||
timestamp, = struct.unpack(">Q", data[1:9])
|
||||
except struct.error:
|
||||
raise InvalidToken
|
||||
if ttl is not None:
|
||||
if timestamp + ttl < current_time:
|
||||
raise InvalidToken
|
||||
if current_time + _MAX_CLOCK_SKEW < timestamp:
|
||||
raise InvalidToken
|
||||
h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend)
|
||||
h.update(data[:-32])
|
||||
try:
|
||||
h.verify(data[-32:])
|
||||
except InvalidSignature:
|
||||
raise InvalidToken
|
||||
|
||||
iv = data[9:25]
|
||||
ciphertext = data[25:-32]
|
||||
decryptor = Cipher(
|
||||
algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend
|
||||
).decryptor()
|
||||
plaintext_padded = decryptor.update(ciphertext)
|
||||
try:
|
||||
plaintext_padded += decryptor.finalize()
|
||||
except ValueError:
|
||||
raise InvalidToken
|
||||
unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
|
||||
|
||||
unpadded = unpadder.update(plaintext_padded)
|
||||
try:
|
||||
unpadded += unpadder.finalize()
|
||||
except ValueError:
|
||||
raise InvalidToken
|
||||
return unpadded
|
|
@ -1,14 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
|
@ -1,46 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import pkg_resources
|
||||
|
||||
from cryptography.hazmat.backends.multibackend import MultiBackend
|
||||
|
||||
|
||||
_available_backends_list = None
|
||||
|
||||
|
||||
def _available_backends():
|
||||
global _available_backends_list
|
||||
|
||||
if _available_backends_list is None:
|
||||
_available_backends_list = [
|
||||
backend.load(require=False)
|
||||
for backend in pkg_resources.iter_entry_points(
|
||||
"cryptography.backends"
|
||||
)
|
||||
]
|
||||
|
||||
return _available_backends_list
|
||||
|
||||
_default_backend = None
|
||||
|
||||
|
||||
def default_backend():
|
||||
global _default_backend
|
||||
|
||||
if _default_backend is None:
|
||||
_default_backend = MultiBackend(_available_backends())
|
||||
|
||||
return _default_backend
|
|
@ -1,19 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography.hazmat.backends.commoncrypto.backend import backend
|
||||
|
||||
|
||||
__all__ = ["backend"]
|
|
@ -1,253 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import InternalError
|
||||
from cryptography.hazmat.backends.commoncrypto.ciphers import (
|
||||
_CipherContext, _GCMCipherContext
|
||||
)
|
||||
from cryptography.hazmat.backends.commoncrypto.hashes import _HashContext
|
||||
from cryptography.hazmat.backends.commoncrypto.hmac import _HMACContext
|
||||
from cryptography.hazmat.backends.interfaces import (
|
||||
CipherBackend, HMACBackend, HashBackend, PBKDF2HMACBackend
|
||||
)
|
||||
from cryptography.hazmat.bindings.commoncrypto.binding import Binding
|
||||
from cryptography.hazmat.primitives.ciphers.algorithms import (
|
||||
AES, ARC4, Blowfish, CAST5, TripleDES
|
||||
)
|
||||
from cryptography.hazmat.primitives.ciphers.modes import (
|
||||
CBC, CFB, CFB8, CTR, ECB, GCM, OFB
|
||||
)
|
||||
|
||||
|
||||
HashMethods = namedtuple(
|
||||
"HashMethods", ["ctx", "hash_init", "hash_update", "hash_final"]
|
||||
)
|
||||
|
||||
|
||||
@utils.register_interface(CipherBackend)
|
||||
@utils.register_interface(HashBackend)
|
||||
@utils.register_interface(HMACBackend)
|
||||
@utils.register_interface(PBKDF2HMACBackend)
|
||||
class Backend(object):
|
||||
"""
|
||||
CommonCrypto API wrapper.
|
||||
"""
|
||||
name = "commoncrypto"
|
||||
|
||||
def __init__(self):
|
||||
self._binding = Binding()
|
||||
self._ffi = self._binding.ffi
|
||||
self._lib = self._binding.lib
|
||||
|
||||
self._cipher_registry = {}
|
||||
self._register_default_ciphers()
|
||||
self._hash_mapping = {
|
||||
"md5": HashMethods(
|
||||
"CC_MD5_CTX *", self._lib.CC_MD5_Init,
|
||||
self._lib.CC_MD5_Update, self._lib.CC_MD5_Final
|
||||
),
|
||||
"sha1": HashMethods(
|
||||
"CC_SHA1_CTX *", self._lib.CC_SHA1_Init,
|
||||
self._lib.CC_SHA1_Update, self._lib.CC_SHA1_Final
|
||||
),
|
||||
"sha224": HashMethods(
|
||||
"CC_SHA256_CTX *", self._lib.CC_SHA224_Init,
|
||||
self._lib.CC_SHA224_Update, self._lib.CC_SHA224_Final
|
||||
),
|
||||
"sha256": HashMethods(
|
||||
"CC_SHA256_CTX *", self._lib.CC_SHA256_Init,
|
||||
self._lib.CC_SHA256_Update, self._lib.CC_SHA256_Final
|
||||
),
|
||||
"sha384": HashMethods(
|
||||
"CC_SHA512_CTX *", self._lib.CC_SHA384_Init,
|
||||
self._lib.CC_SHA384_Update, self._lib.CC_SHA384_Final
|
||||
),
|
||||
"sha512": HashMethods(
|
||||
"CC_SHA512_CTX *", self._lib.CC_SHA512_Init,
|
||||
self._lib.CC_SHA512_Update, self._lib.CC_SHA512_Final
|
||||
),
|
||||
}
|
||||
|
||||
self._supported_hmac_algorithms = {
|
||||
"md5": self._lib.kCCHmacAlgMD5,
|
||||
"sha1": self._lib.kCCHmacAlgSHA1,
|
||||
"sha224": self._lib.kCCHmacAlgSHA224,
|
||||
"sha256": self._lib.kCCHmacAlgSHA256,
|
||||
"sha384": self._lib.kCCHmacAlgSHA384,
|
||||
"sha512": self._lib.kCCHmacAlgSHA512,
|
||||
}
|
||||
|
||||
self._supported_pbkdf2_hmac_algorithms = {
|
||||
"sha1": self._lib.kCCPRFHmacAlgSHA1,
|
||||
"sha224": self._lib.kCCPRFHmacAlgSHA224,
|
||||
"sha256": self._lib.kCCPRFHmacAlgSHA256,
|
||||
"sha384": self._lib.kCCPRFHmacAlgSHA384,
|
||||
"sha512": self._lib.kCCPRFHmacAlgSHA512,
|
||||
}
|
||||
|
||||
def hash_supported(self, algorithm):
|
||||
return algorithm.name in self._hash_mapping
|
||||
|
||||
def hmac_supported(self, algorithm):
|
||||
return algorithm.name in self._supported_hmac_algorithms
|
||||
|
||||
def create_hash_ctx(self, algorithm):
|
||||
return _HashContext(self, algorithm)
|
||||
|
||||
def create_hmac_ctx(self, key, algorithm):
|
||||
return _HMACContext(self, key, algorithm)
|
||||
|
||||
def cipher_supported(self, cipher, mode):
|
||||
return (type(cipher), type(mode)) in self._cipher_registry
|
||||
|
||||
def create_symmetric_encryption_ctx(self, cipher, mode):
|
||||
if isinstance(mode, GCM):
|
||||
return _GCMCipherContext(
|
||||
self, cipher, mode, self._lib.kCCEncrypt
|
||||
)
|
||||
else:
|
||||
return _CipherContext(self, cipher, mode, self._lib.kCCEncrypt)
|
||||
|
||||
def create_symmetric_decryption_ctx(self, cipher, mode):
|
||||
if isinstance(mode, GCM):
|
||||
return _GCMCipherContext(
|
||||
self, cipher, mode, self._lib.kCCDecrypt
|
||||
)
|
||||
else:
|
||||
return _CipherContext(self, cipher, mode, self._lib.kCCDecrypt)
|
||||
|
||||
def pbkdf2_hmac_supported(self, algorithm):
|
||||
return algorithm.name in self._supported_pbkdf2_hmac_algorithms
|
||||
|
||||
def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations,
|
||||
key_material):
|
||||
alg_enum = self._supported_pbkdf2_hmac_algorithms[algorithm.name]
|
||||
buf = self._ffi.new("char[]", length)
|
||||
res = self._lib.CCKeyDerivationPBKDF(
|
||||
self._lib.kCCPBKDF2,
|
||||
key_material,
|
||||
len(key_material),
|
||||
salt,
|
||||
len(salt),
|
||||
alg_enum,
|
||||
iterations,
|
||||
buf,
|
||||
length
|
||||
)
|
||||
self._check_cipher_response(res)
|
||||
|
||||
return self._ffi.buffer(buf)[:]
|
||||
|
||||
def _register_cipher_adapter(self, cipher_cls, cipher_const, mode_cls,
|
||||
mode_const):
|
||||
if (cipher_cls, mode_cls) in self._cipher_registry:
|
||||
raise ValueError("Duplicate registration for: {0} {1}.".format(
|
||||
cipher_cls, mode_cls)
|
||||
)
|
||||
self._cipher_registry[cipher_cls, mode_cls] = (cipher_const,
|
||||
mode_const)
|
||||
|
||||
def _register_default_ciphers(self):
|
||||
for mode_cls, mode_const in [
|
||||
(CBC, self._lib.kCCModeCBC),
|
||||
(ECB, self._lib.kCCModeECB),
|
||||
(CFB, self._lib.kCCModeCFB),
|
||||
(CFB8, self._lib.kCCModeCFB8),
|
||||
(OFB, self._lib.kCCModeOFB),
|
||||
(CTR, self._lib.kCCModeCTR),
|
||||
(GCM, self._lib.kCCModeGCM),
|
||||
]:
|
||||
self._register_cipher_adapter(
|
||||
AES,
|
||||
self._lib.kCCAlgorithmAES128,
|
||||
mode_cls,
|
||||
mode_const
|
||||
)
|
||||
for mode_cls, mode_const in [
|
||||
(CBC, self._lib.kCCModeCBC),
|
||||
(ECB, self._lib.kCCModeECB),
|
||||
(CFB, self._lib.kCCModeCFB),
|
||||
(CFB8, self._lib.kCCModeCFB8),
|
||||
(OFB, self._lib.kCCModeOFB),
|
||||
]:
|
||||
self._register_cipher_adapter(
|
||||
TripleDES,
|
||||
self._lib.kCCAlgorithm3DES,
|
||||
mode_cls,
|
||||
mode_const
|
||||
)
|
||||
for mode_cls, mode_const in [
|
||||
(CBC, self._lib.kCCModeCBC),
|
||||
(ECB, self._lib.kCCModeECB),
|
||||
(CFB, self._lib.kCCModeCFB),
|
||||
(OFB, self._lib.kCCModeOFB)
|
||||
]:
|
||||
self._register_cipher_adapter(
|
||||
Blowfish,
|
||||
self._lib.kCCAlgorithmBlowfish,
|
||||
mode_cls,
|
||||
mode_const
|
||||
)
|
||||
for mode_cls, mode_const in [
|
||||
(CBC, self._lib.kCCModeCBC),
|
||||
(ECB, self._lib.kCCModeECB),
|
||||
(CFB, self._lib.kCCModeCFB),
|
||||
(OFB, self._lib.kCCModeOFB),
|
||||
(CTR, self._lib.kCCModeCTR)
|
||||
]:
|
||||
self._register_cipher_adapter(
|
||||
CAST5,
|
||||
self._lib.kCCAlgorithmCAST,
|
||||
mode_cls,
|
||||
mode_const
|
||||
)
|
||||
self._register_cipher_adapter(
|
||||
ARC4,
|
||||
self._lib.kCCAlgorithmRC4,
|
||||
type(None),
|
||||
self._lib.kCCModeRC4
|
||||
)
|
||||
|
||||
def _check_cipher_response(self, response):
|
||||
if response == self._lib.kCCSuccess:
|
||||
return
|
||||
elif response == self._lib.kCCAlignmentError:
|
||||
# This error is not currently triggered due to a bug filed as
|
||||
# rdar://15589470
|
||||
raise ValueError(
|
||||
"The length of the provided data is not a multiple of "
|
||||
"the block length."
|
||||
)
|
||||
else:
|
||||
raise InternalError(
|
||||
"The backend returned an unknown error, consider filing a bug."
|
||||
" Code: {0}.".format(response)
|
||||
)
|
||||
|
||||
def _release_cipher_ctx(self, ctx):
|
||||
"""
|
||||
Called by the garbage collector and used to safely dereference and
|
||||
release the context.
|
||||
"""
|
||||
if ctx[0] != self._ffi.NULL:
|
||||
res = self._lib.CCCryptorRelease(ctx[0])
|
||||
self._check_cipher_response(res)
|
||||
ctx[0] = self._ffi.NULL
|
||||
|
||||
|
||||
backend = Backend()
|
|
@ -1,203 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import (
|
||||
InvalidTag, UnsupportedAlgorithm, _Reasons
|
||||
)
|
||||
from cryptography.hazmat.primitives import constant_time, interfaces
|
||||
from cryptography.hazmat.primitives.ciphers.modes import (
|
||||
CFB, CFB8, CTR, OFB
|
||||
)
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.CipherContext)
|
||||
class _CipherContext(object):
|
||||
def __init__(self, backend, cipher, mode, operation):
|
||||
self._backend = backend
|
||||
self._cipher = cipher
|
||||
self._mode = mode
|
||||
self._operation = operation
|
||||
# There is a bug in CommonCrypto where block ciphers do not raise
|
||||
# kCCAlignmentError when finalizing if you supply non-block aligned
|
||||
# data. To work around this we need to keep track of the block
|
||||
# alignment ourselves, but only for alg+mode combos that require
|
||||
# block alignment. OFB, CFB, and CTR make a block cipher algorithm
|
||||
# into a stream cipher so we don't need to track them (and thus their
|
||||
# block size is effectively 1 byte just like OpenSSL/CommonCrypto
|
||||
# treat RC4 and other stream cipher block sizes).
|
||||
# This bug has been filed as rdar://15589470
|
||||
self._bytes_processed = 0
|
||||
if (isinstance(cipher, interfaces.BlockCipherAlgorithm) and not
|
||||
isinstance(mode, (OFB, CFB, CFB8, CTR))):
|
||||
self._byte_block_size = cipher.block_size // 8
|
||||
else:
|
||||
self._byte_block_size = 1
|
||||
|
||||
registry = self._backend._cipher_registry
|
||||
try:
|
||||
cipher_enum, mode_enum = registry[type(cipher), type(mode)]
|
||||
except KeyError:
|
||||
raise UnsupportedAlgorithm(
|
||||
"cipher {0} in {1} mode is not supported "
|
||||
"by this backend.".format(
|
||||
cipher.name, mode.name if mode else mode),
|
||||
_Reasons.UNSUPPORTED_CIPHER
|
||||
)
|
||||
|
||||
ctx = self._backend._ffi.new("CCCryptorRef *")
|
||||
ctx = self._backend._ffi.gc(ctx, self._backend._release_cipher_ctx)
|
||||
|
||||
if isinstance(mode, interfaces.ModeWithInitializationVector):
|
||||
iv_nonce = mode.initialization_vector
|
||||
elif isinstance(mode, interfaces.ModeWithNonce):
|
||||
iv_nonce = mode.nonce
|
||||
else:
|
||||
iv_nonce = self._backend._ffi.NULL
|
||||
|
||||
if isinstance(mode, CTR):
|
||||
mode_option = self._backend._lib.kCCModeOptionCTR_BE
|
||||
else:
|
||||
mode_option = 0
|
||||
|
||||
res = self._backend._lib.CCCryptorCreateWithMode(
|
||||
operation,
|
||||
mode_enum, cipher_enum,
|
||||
self._backend._lib.ccNoPadding, iv_nonce,
|
||||
cipher.key, len(cipher.key),
|
||||
self._backend._ffi.NULL, 0, 0, mode_option, ctx)
|
||||
self._backend._check_cipher_response(res)
|
||||
|
||||
self._ctx = ctx
|
||||
|
||||
def update(self, data):
|
||||
# Count bytes processed to handle block alignment.
|
||||
self._bytes_processed += len(data)
|
||||
buf = self._backend._ffi.new(
|
||||
"unsigned char[]", len(data) + self._byte_block_size - 1)
|
||||
outlen = self._backend._ffi.new("size_t *")
|
||||
res = self._backend._lib.CCCryptorUpdate(
|
||||
self._ctx[0], data, len(data), buf,
|
||||
len(data) + self._byte_block_size - 1, outlen)
|
||||
self._backend._check_cipher_response(res)
|
||||
return self._backend._ffi.buffer(buf)[:outlen[0]]
|
||||
|
||||
def finalize(self):
|
||||
# Raise error if block alignment is wrong.
|
||||
if self._bytes_processed % self._byte_block_size:
|
||||
raise ValueError(
|
||||
"The length of the provided data is not a multiple of "
|
||||
"the block length."
|
||||
)
|
||||
buf = self._backend._ffi.new("unsigned char[]", self._byte_block_size)
|
||||
outlen = self._backend._ffi.new("size_t *")
|
||||
res = self._backend._lib.CCCryptorFinal(
|
||||
self._ctx[0], buf, len(buf), outlen)
|
||||
self._backend._check_cipher_response(res)
|
||||
self._backend._release_cipher_ctx(self._ctx)
|
||||
return self._backend._ffi.buffer(buf)[:outlen[0]]
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.AEADCipherContext)
|
||||
@utils.register_interface(interfaces.AEADEncryptionContext)
|
||||
class _GCMCipherContext(object):
|
||||
def __init__(self, backend, cipher, mode, operation):
|
||||
self._backend = backend
|
||||
self._cipher = cipher
|
||||
self._mode = mode
|
||||
self._operation = operation
|
||||
self._tag = None
|
||||
|
||||
registry = self._backend._cipher_registry
|
||||
try:
|
||||
cipher_enum, mode_enum = registry[type(cipher), type(mode)]
|
||||
except KeyError:
|
||||
raise UnsupportedAlgorithm(
|
||||
"cipher {0} in {1} mode is not supported "
|
||||
"by this backend.".format(
|
||||
cipher.name, mode.name if mode else mode),
|
||||
_Reasons.UNSUPPORTED_CIPHER
|
||||
)
|
||||
|
||||
ctx = self._backend._ffi.new("CCCryptorRef *")
|
||||
ctx = self._backend._ffi.gc(ctx, self._backend._release_cipher_ctx)
|
||||
|
||||
self._ctx = ctx
|
||||
|
||||
res = self._backend._lib.CCCryptorCreateWithMode(
|
||||
operation,
|
||||
mode_enum, cipher_enum,
|
||||
self._backend._lib.ccNoPadding,
|
||||
self._backend._ffi.NULL,
|
||||
cipher.key, len(cipher.key),
|
||||
self._backend._ffi.NULL, 0, 0, 0, self._ctx)
|
||||
self._backend._check_cipher_response(res)
|
||||
|
||||
res = self._backend._lib.CCCryptorGCMAddIV(
|
||||
self._ctx[0],
|
||||
mode.initialization_vector,
|
||||
len(mode.initialization_vector)
|
||||
)
|
||||
self._backend._check_cipher_response(res)
|
||||
# CommonCrypto has a bug where calling update without at least one
|
||||
# call to authenticate_additional_data will result in null byte output
|
||||
# for ciphertext. The following empty byte string call prevents the
|
||||
# issue, which is present in at least 10.8 and 10.9.
|
||||
# Filed as rdar://18314544
|
||||
self.authenticate_additional_data(b"")
|
||||
|
||||
def update(self, data):
|
||||
buf = self._backend._ffi.new("unsigned char[]", len(data))
|
||||
args = (self._ctx[0], data, len(data), buf)
|
||||
if self._operation == self._backend._lib.kCCEncrypt:
|
||||
res = self._backend._lib.CCCryptorGCMEncrypt(*args)
|
||||
else:
|
||||
res = self._backend._lib.CCCryptorGCMDecrypt(*args)
|
||||
|
||||
self._backend._check_cipher_response(res)
|
||||
return self._backend._ffi.buffer(buf)[:]
|
||||
|
||||
def finalize(self):
|
||||
# CommonCrypto has a yet another bug where you must make at least one
|
||||
# call to update. If you pass just AAD and call finalize without a call
|
||||
# to update you'll get null bytes for tag. The following update call
|
||||
# prevents this issue, which is present in at least 10.8 and 10.9.
|
||||
# Filed as rdar://18314580
|
||||
self.update(b"")
|
||||
tag_size = self._cipher.block_size // 8
|
||||
tag_buf = self._backend._ffi.new("unsigned char[]", tag_size)
|
||||
tag_len = self._backend._ffi.new("size_t *", tag_size)
|
||||
res = self._backend._lib.CCCryptorGCMFinal(
|
||||
self._ctx[0], tag_buf, tag_len
|
||||
)
|
||||
self._backend._check_cipher_response(res)
|
||||
self._backend._release_cipher_ctx(self._ctx)
|
||||
self._tag = self._backend._ffi.buffer(tag_buf)[:]
|
||||
if (self._operation == self._backend._lib.kCCDecrypt and
|
||||
not constant_time.bytes_eq(
|
||||
self._tag[:len(self._mode.tag)], self._mode.tag
|
||||
)):
|
||||
raise InvalidTag
|
||||
return b""
|
||||
|
||||
def authenticate_additional_data(self, data):
|
||||
res = self._backend._lib.CCCryptorGCMAddAAD(
|
||||
self._ctx[0], data, len(data)
|
||||
)
|
||||
self._backend._check_cipher_response(res)
|
||||
|
||||
@property
|
||||
def tag(self):
|
||||
return self._tag
|
|
@ -1,62 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.primitives import interfaces
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.HashContext)
|
||||
class _HashContext(object):
|
||||
def __init__(self, backend, algorithm, ctx=None):
|
||||
self.algorithm = algorithm
|
||||
self._backend = backend
|
||||
|
||||
if ctx is None:
|
||||
try:
|
||||
methods = self._backend._hash_mapping[self.algorithm.name]
|
||||
except KeyError:
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not a supported hash on this backend.".format(
|
||||
algorithm.name),
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
ctx = self._backend._ffi.new(methods.ctx)
|
||||
res = methods.hash_init(ctx)
|
||||
assert res == 1
|
||||
|
||||
self._ctx = ctx
|
||||
|
||||
def copy(self):
|
||||
methods = self._backend._hash_mapping[self.algorithm.name]
|
||||
new_ctx = self._backend._ffi.new(methods.ctx)
|
||||
# CommonCrypto has no APIs for copying hashes, so we have to copy the
|
||||
# underlying struct.
|
||||
new_ctx[0] = self._ctx[0]
|
||||
|
||||
return _HashContext(self._backend, self.algorithm, ctx=new_ctx)
|
||||
|
||||
def update(self, data):
|
||||
methods = self._backend._hash_mapping[self.algorithm.name]
|
||||
res = methods.hash_update(self._ctx, data, len(data))
|
||||
assert res == 1
|
||||
|
||||
def finalize(self):
|
||||
methods = self._backend._hash_mapping[self.algorithm.name]
|
||||
buf = self._backend._ffi.new("unsigned char[]",
|
||||
self.algorithm.digest_size)
|
||||
res = methods.hash_final(buf, self._ctx)
|
||||
assert res == 1
|
||||
return self._backend._ffi.buffer(buf)[:]
|
|
@ -1,58 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.primitives import interfaces
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.HashContext)
|
||||
class _HMACContext(object):
|
||||
def __init__(self, backend, key, algorithm, ctx=None):
|
||||
self.algorithm = algorithm
|
||||
self._backend = backend
|
||||
if ctx is None:
|
||||
ctx = self._backend._ffi.new("CCHmacContext *")
|
||||
try:
|
||||
alg = self._backend._supported_hmac_algorithms[algorithm.name]
|
||||
except KeyError:
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not a supported HMAC hash on this backend.".format(
|
||||
algorithm.name),
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
|
||||
self._backend._lib.CCHmacInit(ctx, alg, key, len(key))
|
||||
|
||||
self._ctx = ctx
|
||||
self._key = key
|
||||
|
||||
def copy(self):
|
||||
copied_ctx = self._backend._ffi.new("CCHmacContext *")
|
||||
# CommonCrypto has no APIs for copying HMACs, so we have to copy the
|
||||
# underlying struct.
|
||||
copied_ctx[0] = self._ctx[0]
|
||||
return _HMACContext(
|
||||
self._backend, self._key, self.algorithm, ctx=copied_ctx
|
||||
)
|
||||
|
||||
def update(self, data):
|
||||
self._backend._lib.CCHmacUpdate(self._ctx, data, len(data))
|
||||
|
||||
def finalize(self):
|
||||
buf = self._backend._ffi.new("unsigned char[]",
|
||||
self.algorithm.digest_size)
|
||||
self._backend._lib.CCHmacFinal(self._ctx, buf)
|
||||
return self._backend._ffi.buffer(buf)[:]
|
|
@ -1,308 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import abc
|
||||
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class CipherBackend(object):
|
||||
@abc.abstractmethod
|
||||
def cipher_supported(self, cipher, mode):
|
||||
"""
|
||||
Return True if the given cipher and mode are supported.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_symmetric_encryption_ctx(self, cipher, mode):
|
||||
"""
|
||||
Get a CipherContext that can be used for encryption.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_symmetric_decryption_ctx(self, cipher, mode):
|
||||
"""
|
||||
Get a CipherContext that can be used for decryption.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class HashBackend(object):
|
||||
@abc.abstractmethod
|
||||
def hash_supported(self, algorithm):
|
||||
"""
|
||||
Return True if the hash algorithm is supported by this backend.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_hash_ctx(self, algorithm):
|
||||
"""
|
||||
Create a HashContext for calculating a message digest.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class HMACBackend(object):
|
||||
@abc.abstractmethod
|
||||
def hmac_supported(self, algorithm):
|
||||
"""
|
||||
Return True if the hash algorithm is supported for HMAC by this
|
||||
backend.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_hmac_ctx(self, key, algorithm):
|
||||
"""
|
||||
Create a HashContext for calculating a message authentication code.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class CMACBackend(object):
|
||||
@abc.abstractmethod
|
||||
def cmac_algorithm_supported(self, algorithm):
|
||||
"""
|
||||
Returns True if the block cipher is supported for CMAC by this backend
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_cmac_ctx(self, algorithm):
|
||||
"""
|
||||
Create a CMACContext for calculating a message authentication code.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class PBKDF2HMACBackend(object):
|
||||
@abc.abstractmethod
|
||||
def pbkdf2_hmac_supported(self, algorithm):
|
||||
"""
|
||||
Return True if the hash algorithm is supported for PBKDF2 by this
|
||||
backend.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations,
|
||||
key_material):
|
||||
"""
|
||||
Return length bytes derived from provided PBKDF2 parameters.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class RSABackend(object):
|
||||
@abc.abstractmethod
|
||||
def generate_rsa_private_key(self, public_exponent, key_size):
|
||||
"""
|
||||
Generate an RSAPrivateKey instance with public_exponent and a modulus
|
||||
of key_size bits.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_rsa_signature_ctx(self, private_key, padding, algorithm):
|
||||
"""
|
||||
Returns an object conforming to the AsymmetricSignatureContext
|
||||
interface.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_rsa_verification_ctx(self, public_key, signature, padding,
|
||||
algorithm):
|
||||
"""
|
||||
Returns an object conforming to the AsymmetricVerificationContext
|
||||
interface.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def mgf1_hash_supported(self, algorithm):
|
||||
"""
|
||||
Return True if the hash algorithm is supported for MGF1 in PSS.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def decrypt_rsa(self, private_key, ciphertext, padding):
|
||||
"""
|
||||
Returns decrypted bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def encrypt_rsa(self, public_key, plaintext, padding):
|
||||
"""
|
||||
Returns encrypted bytes.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def rsa_padding_supported(self, padding):
|
||||
"""
|
||||
Returns True if the backend supports the given padding options.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def generate_rsa_parameters_supported(self, public_exponent, key_size):
|
||||
"""
|
||||
Returns True if the backend supports the given parameters for key
|
||||
generation.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def load_rsa_private_numbers(self, numbers):
|
||||
"""
|
||||
Returns an RSAPrivateKey provider.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def load_rsa_public_numbers(self, numbers):
|
||||
"""
|
||||
Returns an RSAPublicKey provider.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class DSABackend(object):
|
||||
@abc.abstractmethod
|
||||
def generate_dsa_parameters(self, key_size):
|
||||
"""
|
||||
Generate a DSAParameters instance with a modulus of key_size bits.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def generate_dsa_private_key(self, parameters):
|
||||
"""
|
||||
Generate a DSAPrivateKey instance with parameters as a DSAParameters
|
||||
object.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def generate_dsa_private_key_and_parameters(self, key_size):
|
||||
"""
|
||||
Generate a DSAPrivateKey instance using key size only.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_dsa_signature_ctx(self, private_key, algorithm):
|
||||
"""
|
||||
Returns an object conforming to the AsymmetricSignatureContext
|
||||
interface.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_dsa_verification_ctx(self, public_key, signature, algorithm):
|
||||
"""
|
||||
Returns an object conforming to the AsymmetricVerificationContext
|
||||
interface.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def dsa_hash_supported(self, algorithm):
|
||||
"""
|
||||
Return True if the hash algorithm is supported by the backend for DSA.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def dsa_parameters_supported(self, p, q, g):
|
||||
"""
|
||||
Return True if the parameters are supported by the backend for DSA.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def load_dsa_private_numbers(self, numbers):
|
||||
"""
|
||||
Returns a DSAPrivateKey provider.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def load_dsa_public_numbers(self, numbers):
|
||||
"""
|
||||
Returns a DSAPublicKey provider.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def load_dsa_parameter_numbers(self, numbers):
|
||||
"""
|
||||
Returns a DSAParameters provider.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class EllipticCurveBackend(object):
|
||||
@abc.abstractmethod
|
||||
def elliptic_curve_signature_algorithm_supported(
|
||||
self, signature_algorithm, curve
|
||||
):
|
||||
"""
|
||||
Returns True if the backend supports the named elliptic curve with the
|
||||
specified signature algorithm.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def elliptic_curve_supported(self, curve):
|
||||
"""
|
||||
Returns True if the backend supports the named elliptic curve.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def generate_elliptic_curve_private_key(self, curve):
|
||||
"""
|
||||
Return an object conforming to the EllipticCurvePrivateKey interface.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def load_elliptic_curve_public_numbers(self, numbers):
|
||||
"""
|
||||
Return an EllipticCurvePublicKey provider using the given numbers.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def load_elliptic_curve_private_numbers(self, numbers):
|
||||
"""
|
||||
Return an EllipticCurvePublicKey provider using the given numbers.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class PEMSerializationBackend(object):
|
||||
@abc.abstractmethod
|
||||
def load_pem_private_key(self, data, password):
|
||||
"""
|
||||
Loads a private key from PEM encoded data, using the provided password
|
||||
if the data is encrypted.
|
||||
"""
|
||||
|
||||
@abc.abstractmethod
|
||||
def load_pem_public_key(self, data):
|
||||
"""
|
||||
Loads a public key from PEM encoded data.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class TraditionalOpenSSLSerializationBackend(object):
|
||||
@abc.abstractmethod
|
||||
def load_traditional_openssl_pem_private_key(self, data, password):
|
||||
"""
|
||||
Load a private key from PEM encoded data, using password if the data
|
||||
is encrypted.
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class PKCS8SerializationBackend(object):
|
||||
@abc.abstractmethod
|
||||
def load_pkcs8_pem_private_key(self, data, password):
|
||||
"""
|
||||
Load a private key from PKCS8 encoded data, using password if the data
|
||||
is encrypted.
|
||||
"""
|
|
@ -1,397 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import warnings
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.backends.interfaces import (
|
||||
CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend,
|
||||
HashBackend, PBKDF2HMACBackend, PEMSerializationBackend,
|
||||
PKCS8SerializationBackend, RSABackend,
|
||||
TraditionalOpenSSLSerializationBackend
|
||||
)
|
||||
|
||||
|
||||
@utils.register_interface(CMACBackend)
|
||||
@utils.register_interface(CipherBackend)
|
||||
@utils.register_interface(HashBackend)
|
||||
@utils.register_interface(HMACBackend)
|
||||
@utils.register_interface(PBKDF2HMACBackend)
|
||||
@utils.register_interface(PKCS8SerializationBackend)
|
||||
@utils.register_interface(RSABackend)
|
||||
@utils.register_interface(TraditionalOpenSSLSerializationBackend)
|
||||
@utils.register_interface(DSABackend)
|
||||
@utils.register_interface(EllipticCurveBackend)
|
||||
@utils.register_interface(PEMSerializationBackend)
|
||||
class MultiBackend(object):
|
||||
name = "multibackend"
|
||||
|
||||
def __init__(self, backends):
|
||||
self._backends = backends
|
||||
|
||||
def _filtered_backends(self, interface):
|
||||
for b in self._backends:
|
||||
if isinstance(b, interface):
|
||||
yield b
|
||||
|
||||
def cipher_supported(self, algorithm, mode):
|
||||
return any(
|
||||
b.cipher_supported(algorithm, mode)
|
||||
for b in self._filtered_backends(CipherBackend)
|
||||
)
|
||||
|
||||
def create_symmetric_encryption_ctx(self, algorithm, mode):
|
||||
for b in self._filtered_backends(CipherBackend):
|
||||
try:
|
||||
return b.create_symmetric_encryption_ctx(algorithm, mode)
|
||||
except UnsupportedAlgorithm:
|
||||
pass
|
||||
raise UnsupportedAlgorithm(
|
||||
"cipher {0} in {1} mode is not supported by this backend.".format(
|
||||
algorithm.name, mode.name if mode else mode),
|
||||
_Reasons.UNSUPPORTED_CIPHER
|
||||
)
|
||||
|
||||
def create_symmetric_decryption_ctx(self, algorithm, mode):
|
||||
for b in self._filtered_backends(CipherBackend):
|
||||
try:
|
||||
return b.create_symmetric_decryption_ctx(algorithm, mode)
|
||||
except UnsupportedAlgorithm:
|
||||
pass
|
||||
raise UnsupportedAlgorithm(
|
||||
"cipher {0} in {1} mode is not supported by this backend.".format(
|
||||
algorithm.name, mode.name if mode else mode),
|
||||
_Reasons.UNSUPPORTED_CIPHER
|
||||
)
|
||||
|
||||
def hash_supported(self, algorithm):
|
||||
return any(
|
||||
b.hash_supported(algorithm)
|
||||
for b in self._filtered_backends(HashBackend)
|
||||
)
|
||||
|
||||
def create_hash_ctx(self, algorithm):
|
||||
for b in self._filtered_backends(HashBackend):
|
||||
try:
|
||||
return b.create_hash_ctx(algorithm)
|
||||
except UnsupportedAlgorithm:
|
||||
pass
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not a supported hash on this backend.".format(
|
||||
algorithm.name),
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
|
||||
def hmac_supported(self, algorithm):
|
||||
return any(
|
||||
b.hmac_supported(algorithm)
|
||||
for b in self._filtered_backends(HMACBackend)
|
||||
)
|
||||
|
||||
def create_hmac_ctx(self, key, algorithm):
|
||||
for b in self._filtered_backends(HMACBackend):
|
||||
try:
|
||||
return b.create_hmac_ctx(key, algorithm)
|
||||
except UnsupportedAlgorithm:
|
||||
pass
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not a supported hash on this backend.".format(
|
||||
algorithm.name),
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
|
||||
def pbkdf2_hmac_supported(self, algorithm):
|
||||
return any(
|
||||
b.pbkdf2_hmac_supported(algorithm)
|
||||
for b in self._filtered_backends(PBKDF2HMACBackend)
|
||||
)
|
||||
|
||||
def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations,
|
||||
key_material):
|
||||
for b in self._filtered_backends(PBKDF2HMACBackend):
|
||||
try:
|
||||
return b.derive_pbkdf2_hmac(
|
||||
algorithm, length, salt, iterations, key_material
|
||||
)
|
||||
except UnsupportedAlgorithm:
|
||||
pass
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not a supported hash on this backend.".format(
|
||||
algorithm.name),
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
|
||||
def generate_rsa_private_key(self, public_exponent, key_size):
|
||||
for b in self._filtered_backends(RSABackend):
|
||||
return b.generate_rsa_private_key(public_exponent, key_size)
|
||||
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def generate_rsa_parameters_supported(self, public_exponent, key_size):
|
||||
for b in self._filtered_backends(RSABackend):
|
||||
return b.generate_rsa_parameters_supported(
|
||||
public_exponent, key_size
|
||||
)
|
||||
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def create_rsa_signature_ctx(self, private_key, padding, algorithm):
|
||||
for b in self._filtered_backends(RSABackend):
|
||||
return b.create_rsa_signature_ctx(private_key, padding, algorithm)
|
||||
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def create_rsa_verification_ctx(self, public_key, signature, padding,
|
||||
algorithm):
|
||||
for b in self._filtered_backends(RSABackend):
|
||||
return b.create_rsa_verification_ctx(public_key, signature,
|
||||
padding, algorithm)
|
||||
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def mgf1_hash_supported(self, algorithm):
|
||||
for b in self._filtered_backends(RSABackend):
|
||||
return b.mgf1_hash_supported(algorithm)
|
||||
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def decrypt_rsa(self, private_key, ciphertext, padding):
|
||||
for b in self._filtered_backends(RSABackend):
|
||||
return b.decrypt_rsa(private_key, ciphertext, padding)
|
||||
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def encrypt_rsa(self, public_key, plaintext, padding):
|
||||
for b in self._filtered_backends(RSABackend):
|
||||
return b.encrypt_rsa(public_key, plaintext, padding)
|
||||
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def rsa_padding_supported(self, padding):
|
||||
for b in self._filtered_backends(RSABackend):
|
||||
return b.rsa_padding_supported(padding)
|
||||
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def load_rsa_private_numbers(self, numbers):
|
||||
for b in self._filtered_backends(RSABackend):
|
||||
return b.load_rsa_private_numbers(numbers)
|
||||
|
||||
raise UnsupportedAlgorithm("RSA is not supported by the backend",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def load_rsa_public_numbers(self, numbers):
|
||||
for b in self._filtered_backends(RSABackend):
|
||||
return b.load_rsa_public_numbers(numbers)
|
||||
|
||||
raise UnsupportedAlgorithm("RSA is not supported by the backend",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def generate_dsa_parameters(self, key_size):
|
||||
for b in self._filtered_backends(DSABackend):
|
||||
return b.generate_dsa_parameters(key_size)
|
||||
raise UnsupportedAlgorithm("DSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def generate_dsa_private_key(self, parameters):
|
||||
for b in self._filtered_backends(DSABackend):
|
||||
return b.generate_dsa_private_key(parameters)
|
||||
raise UnsupportedAlgorithm("DSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def generate_dsa_private_key_and_parameters(self, key_size):
|
||||
for b in self._filtered_backends(DSABackend):
|
||||
return b.generate_dsa_private_key_and_parameters(key_size)
|
||||
raise UnsupportedAlgorithm("DSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def create_dsa_verification_ctx(self, public_key, signature, algorithm):
|
||||
for b in self._filtered_backends(DSABackend):
|
||||
return b.create_dsa_verification_ctx(public_key, signature,
|
||||
algorithm)
|
||||
raise UnsupportedAlgorithm("DSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def create_dsa_signature_ctx(self, private_key, algorithm):
|
||||
for b in self._filtered_backends(DSABackend):
|
||||
return b.create_dsa_signature_ctx(private_key, algorithm)
|
||||
raise UnsupportedAlgorithm("DSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def dsa_hash_supported(self, algorithm):
|
||||
for b in self._filtered_backends(DSABackend):
|
||||
return b.dsa_hash_supported(algorithm)
|
||||
raise UnsupportedAlgorithm("DSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def dsa_parameters_supported(self, p, q, g):
|
||||
for b in self._filtered_backends(DSABackend):
|
||||
return b.dsa_parameters_supported(p, q, g)
|
||||
raise UnsupportedAlgorithm("DSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def load_dsa_public_numbers(self, numbers):
|
||||
for b in self._filtered_backends(DSABackend):
|
||||
return b.load_dsa_public_numbers(numbers)
|
||||
raise UnsupportedAlgorithm("DSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def load_dsa_private_numbers(self, numbers):
|
||||
for b in self._filtered_backends(DSABackend):
|
||||
return b.load_dsa_private_numbers(numbers)
|
||||
raise UnsupportedAlgorithm("DSA is not supported by the backend.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def cmac_algorithm_supported(self, algorithm):
|
||||
return any(
|
||||
b.cmac_algorithm_supported(algorithm)
|
||||
for b in self._filtered_backends(CMACBackend)
|
||||
)
|
||||
|
||||
def create_cmac_ctx(self, algorithm):
|
||||
for b in self._filtered_backends(CMACBackend):
|
||||
try:
|
||||
return b.create_cmac_ctx(algorithm)
|
||||
except UnsupportedAlgorithm:
|
||||
pass
|
||||
raise UnsupportedAlgorithm("This backend does not support CMAC.",
|
||||
_Reasons.UNSUPPORTED_CIPHER)
|
||||
|
||||
def elliptic_curve_supported(self, curve):
|
||||
return any(
|
||||
b.elliptic_curve_supported(curve)
|
||||
for b in self._filtered_backends(EllipticCurveBackend)
|
||||
)
|
||||
|
||||
def elliptic_curve_signature_algorithm_supported(
|
||||
self, signature_algorithm, curve
|
||||
):
|
||||
return any(
|
||||
b.elliptic_curve_signature_algorithm_supported(
|
||||
signature_algorithm, curve
|
||||
)
|
||||
for b in self._filtered_backends(EllipticCurveBackend)
|
||||
)
|
||||
|
||||
def generate_elliptic_curve_private_key(self, curve):
|
||||
for b in self._filtered_backends(EllipticCurveBackend):
|
||||
try:
|
||||
return b.generate_elliptic_curve_private_key(curve)
|
||||
except UnsupportedAlgorithm:
|
||||
continue
|
||||
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend does not support this elliptic curve.",
|
||||
_Reasons.UNSUPPORTED_ELLIPTIC_CURVE
|
||||
)
|
||||
|
||||
def elliptic_curve_private_key_from_numbers(self, numbers):
|
||||
warnings.warn(
|
||||
"elliptic_curve_private_key_from_numbers is deprecated and will "
|
||||
"be removed in a future version.",
|
||||
utils.DeprecatedIn06,
|
||||
stacklevel=2
|
||||
)
|
||||
for b in self._filtered_backends(EllipticCurveBackend):
|
||||
try:
|
||||
return b.elliptic_curve_private_key_from_numbers(numbers)
|
||||
except UnsupportedAlgorithm:
|
||||
continue
|
||||
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend does not support this elliptic curve.",
|
||||
_Reasons.UNSUPPORTED_ELLIPTIC_CURVE
|
||||
)
|
||||
|
||||
def load_elliptic_curve_private_numbers(self, numbers):
|
||||
for b in self._filtered_backends(EllipticCurveBackend):
|
||||
try:
|
||||
return b.load_elliptic_curve_private_numbers(numbers)
|
||||
except UnsupportedAlgorithm:
|
||||
continue
|
||||
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend does not support this elliptic curve.",
|
||||
_Reasons.UNSUPPORTED_ELLIPTIC_CURVE
|
||||
)
|
||||
|
||||
def elliptic_curve_public_key_from_numbers(self, numbers):
|
||||
warnings.warn(
|
||||
"elliptic_curve_public_key_from_numbers is deprecated and will "
|
||||
"be removed in a future version.",
|
||||
utils.DeprecatedIn06,
|
||||
stacklevel=2
|
||||
)
|
||||
for b in self._filtered_backends(EllipticCurveBackend):
|
||||
try:
|
||||
return b.elliptic_curve_public_key_from_numbers(numbers)
|
||||
except UnsupportedAlgorithm:
|
||||
continue
|
||||
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend does not support this elliptic curve.",
|
||||
_Reasons.UNSUPPORTED_ELLIPTIC_CURVE
|
||||
)
|
||||
|
||||
def load_elliptic_curve_public_numbers(self, numbers):
|
||||
for b in self._filtered_backends(EllipticCurveBackend):
|
||||
try:
|
||||
return b.load_elliptic_curve_public_numbers(numbers)
|
||||
except UnsupportedAlgorithm:
|
||||
continue
|
||||
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend does not support this elliptic curve.",
|
||||
_Reasons.UNSUPPORTED_ELLIPTIC_CURVE
|
||||
)
|
||||
|
||||
def load_pem_private_key(self, data, password):
|
||||
for b in self._filtered_backends(PEMSerializationBackend):
|
||||
return b.load_pem_private_key(data, password)
|
||||
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend does not support this key serialization.",
|
||||
_Reasons.UNSUPPORTED_SERIALIZATION
|
||||
)
|
||||
|
||||
def load_pem_public_key(self, data):
|
||||
for b in self._filtered_backends(PEMSerializationBackend):
|
||||
return b.load_pem_public_key(data)
|
||||
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend does not support this key serialization.",
|
||||
_Reasons.UNSUPPORTED_SERIALIZATION
|
||||
)
|
||||
|
||||
def load_pkcs8_pem_private_key(self, data, password):
|
||||
for b in self._filtered_backends(PKCS8SerializationBackend):
|
||||
return b.load_pkcs8_pem_private_key(data, password)
|
||||
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend does not support this key serialization.",
|
||||
_Reasons.UNSUPPORTED_SERIALIZATION
|
||||
)
|
||||
|
||||
def load_traditional_openssl_pem_private_key(self, data, password):
|
||||
for b in self._filtered_backends(
|
||||
TraditionalOpenSSLSerializationBackend
|
||||
):
|
||||
return b.load_traditional_openssl_pem_private_key(data, password)
|
||||
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend does not support this key serialization.",
|
||||
_Reasons.UNSUPPORTED_SERIALIZATION
|
||||
)
|
|
@ -1,19 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography.hazmat.backends.openssl.backend import backend
|
||||
|
||||
|
||||
__all__ = ["backend"]
|
File diff suppressed because it is too large
Load diff
|
@ -1,227 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import InvalidTag, UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.primitives import interfaces
|
||||
from cryptography.hazmat.primitives.ciphers.modes import GCM
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.CipherContext)
|
||||
@utils.register_interface(interfaces.AEADCipherContext)
|
||||
@utils.register_interface(interfaces.AEADEncryptionContext)
|
||||
class _CipherContext(object):
|
||||
_ENCRYPT = 1
|
||||
_DECRYPT = 0
|
||||
|
||||
def __init__(self, backend, cipher, mode, operation):
|
||||
self._backend = backend
|
||||
self._cipher = cipher
|
||||
self._mode = mode
|
||||
self._operation = operation
|
||||
self._tag = None
|
||||
|
||||
if isinstance(self._cipher, interfaces.BlockCipherAlgorithm):
|
||||
self._block_size = self._cipher.block_size
|
||||
else:
|
||||
self._block_size = 1
|
||||
|
||||
ctx = self._backend._lib.EVP_CIPHER_CTX_new()
|
||||
ctx = self._backend._ffi.gc(
|
||||
ctx, self._backend._lib.EVP_CIPHER_CTX_free
|
||||
)
|
||||
|
||||
registry = self._backend._cipher_registry
|
||||
try:
|
||||
adapter = registry[type(cipher), type(mode)]
|
||||
except KeyError:
|
||||
raise UnsupportedAlgorithm(
|
||||
"cipher {0} in {1} mode is not supported "
|
||||
"by this backend.".format(
|
||||
cipher.name, mode.name if mode else mode),
|
||||
_Reasons.UNSUPPORTED_CIPHER
|
||||
)
|
||||
|
||||
evp_cipher = adapter(self._backend, cipher, mode)
|
||||
if evp_cipher == self._backend._ffi.NULL:
|
||||
raise UnsupportedAlgorithm(
|
||||
"cipher {0} in {1} mode is not supported "
|
||||
"by this backend.".format(
|
||||
cipher.name, mode.name if mode else mode),
|
||||
_Reasons.UNSUPPORTED_CIPHER
|
||||
)
|
||||
|
||||
if isinstance(mode, interfaces.ModeWithInitializationVector):
|
||||
iv_nonce = mode.initialization_vector
|
||||
elif isinstance(mode, interfaces.ModeWithNonce):
|
||||
iv_nonce = mode.nonce
|
||||
else:
|
||||
iv_nonce = self._backend._ffi.NULL
|
||||
# begin init with cipher and operation type
|
||||
res = self._backend._lib.EVP_CipherInit_ex(ctx, evp_cipher,
|
||||
self._backend._ffi.NULL,
|
||||
self._backend._ffi.NULL,
|
||||
self._backend._ffi.NULL,
|
||||
operation)
|
||||
assert res != 0
|
||||
# set the key length to handle variable key ciphers
|
||||
res = self._backend._lib.EVP_CIPHER_CTX_set_key_length(
|
||||
ctx, len(cipher.key)
|
||||
)
|
||||
assert res != 0
|
||||
if isinstance(mode, GCM):
|
||||
res = self._backend._lib.EVP_CIPHER_CTX_ctrl(
|
||||
ctx, self._backend._lib.EVP_CTRL_GCM_SET_IVLEN,
|
||||
len(iv_nonce), self._backend._ffi.NULL
|
||||
)
|
||||
assert res != 0
|
||||
if operation == self._DECRYPT:
|
||||
res = self._backend._lib.EVP_CIPHER_CTX_ctrl(
|
||||
ctx, self._backend._lib.EVP_CTRL_GCM_SET_TAG,
|
||||
len(mode.tag), mode.tag
|
||||
)
|
||||
assert res != 0
|
||||
|
||||
# pass key/iv
|
||||
res = self._backend._lib.EVP_CipherInit_ex(
|
||||
ctx,
|
||||
self._backend._ffi.NULL,
|
||||
self._backend._ffi.NULL,
|
||||
cipher.key,
|
||||
iv_nonce,
|
||||
operation
|
||||
)
|
||||
assert res != 0
|
||||
# We purposely disable padding here as it's handled higher up in the
|
||||
# API.
|
||||
self._backend._lib.EVP_CIPHER_CTX_set_padding(ctx, 0)
|
||||
self._ctx = ctx
|
||||
|
||||
def update(self, data):
|
||||
# OpenSSL 0.9.8e has an assertion in its EVP code that causes it
|
||||
# to SIGABRT if you call update with an empty byte string. This can be
|
||||
# removed when we drop support for 0.9.8e (CentOS/RHEL 5). This branch
|
||||
# should be taken only when length is zero and mode is not GCM because
|
||||
# AES GCM can return improper tag values if you don't call update
|
||||
# with empty plaintext when authenticating AAD for ...reasons.
|
||||
if len(data) == 0 and not isinstance(self._mode, GCM):
|
||||
return b""
|
||||
|
||||
buf = self._backend._ffi.new("unsigned char[]",
|
||||
len(data) + self._block_size - 1)
|
||||
outlen = self._backend._ffi.new("int *")
|
||||
res = self._backend._lib.EVP_CipherUpdate(self._ctx, buf, outlen, data,
|
||||
len(data))
|
||||
assert res != 0
|
||||
return self._backend._ffi.buffer(buf)[:outlen[0]]
|
||||
|
||||
def finalize(self):
|
||||
# OpenSSL 1.0.1 on Ubuntu 12.04 (and possibly other distributions)
|
||||
# appears to have a bug where you must make at least one call to update
|
||||
# even if you are only using authenticate_additional_data or the
|
||||
# GCM tag will be wrong. An (empty) call to update resolves this
|
||||
# and is harmless for all other versions of OpenSSL.
|
||||
if isinstance(self._mode, GCM):
|
||||
self.update(b"")
|
||||
|
||||
buf = self._backend._ffi.new("unsigned char[]", self._block_size)
|
||||
outlen = self._backend._ffi.new("int *")
|
||||
res = self._backend._lib.EVP_CipherFinal_ex(self._ctx, buf, outlen)
|
||||
if res == 0:
|
||||
errors = self._backend._consume_errors()
|
||||
|
||||
if not errors and isinstance(self._mode, GCM):
|
||||
raise InvalidTag
|
||||
|
||||
assert errors
|
||||
|
||||
if errors[0][1:] == (
|
||||
self._backend._lib.ERR_LIB_EVP,
|
||||
self._backend._lib.EVP_F_EVP_ENCRYPTFINAL_EX,
|
||||
self._backend._lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH
|
||||
) or errors[0][1:] == (
|
||||
self._backend._lib.ERR_LIB_EVP,
|
||||
self._backend._lib.EVP_F_EVP_DECRYPTFINAL_EX,
|
||||
self._backend._lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH
|
||||
):
|
||||
raise ValueError(
|
||||
"The length of the provided data is not a multiple of "
|
||||
"the block length."
|
||||
)
|
||||
else:
|
||||
raise self._backend._unknown_error(errors[0])
|
||||
|
||||
if (isinstance(self._mode, GCM) and
|
||||
self._operation == self._ENCRYPT):
|
||||
block_byte_size = self._block_size // 8
|
||||
tag_buf = self._backend._ffi.new(
|
||||
"unsigned char[]", block_byte_size
|
||||
)
|
||||
res = self._backend._lib.EVP_CIPHER_CTX_ctrl(
|
||||
self._ctx, self._backend._lib.EVP_CTRL_GCM_GET_TAG,
|
||||
block_byte_size, tag_buf
|
||||
)
|
||||
assert res != 0
|
||||
self._tag = self._backend._ffi.buffer(tag_buf)[:]
|
||||
|
||||
res = self._backend._lib.EVP_CIPHER_CTX_cleanup(self._ctx)
|
||||
assert res == 1
|
||||
return self._backend._ffi.buffer(buf)[:outlen[0]]
|
||||
|
||||
def authenticate_additional_data(self, data):
|
||||
outlen = self._backend._ffi.new("int *")
|
||||
res = self._backend._lib.EVP_CipherUpdate(
|
||||
self._ctx, self._backend._ffi.NULL, outlen, data, len(data)
|
||||
)
|
||||
assert res != 0
|
||||
|
||||
@property
|
||||
def tag(self):
|
||||
return self._tag
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.CipherContext)
|
||||
class _AESCTRCipherContext(object):
|
||||
"""
|
||||
This is needed to provide support for AES CTR mode in OpenSSL 0.9.8. It can
|
||||
be removed when we drop 0.9.8 support (RHEL5 extended life ends 2020).
|
||||
"""
|
||||
def __init__(self, backend, cipher, mode):
|
||||
self._backend = backend
|
||||
|
||||
self._key = self._backend._ffi.new("AES_KEY *")
|
||||
assert self._key != self._backend._ffi.NULL
|
||||
res = self._backend._lib.AES_set_encrypt_key(
|
||||
cipher.key, len(cipher.key) * 8, self._key
|
||||
)
|
||||
assert res == 0
|
||||
self._ecount = self._backend._ffi.new("char[]", 16)
|
||||
self._nonce = self._backend._ffi.new("char[16]", mode.nonce)
|
||||
self._num = self._backend._ffi.new("unsigned int *", 0)
|
||||
|
||||
def update(self, data):
|
||||
buf = self._backend._ffi.new("unsigned char[]", len(data))
|
||||
self._backend._lib.AES_ctr128_encrypt(
|
||||
data, buf, len(data), self._key, self._nonce,
|
||||
self._ecount, self._num
|
||||
)
|
||||
return self._backend._ffi.buffer(buf)[:]
|
||||
|
||||
def finalize(self):
|
||||
self._key = None
|
||||
self._ecount = None
|
||||
self._nonce = None
|
||||
self._num = None
|
||||
return b""
|
|
@ -1,80 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.primitives import interfaces
|
||||
from cryptography.hazmat.primitives.ciphers.modes import CBC
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.CMACContext)
|
||||
class _CMACContext(object):
|
||||
def __init__(self, backend, algorithm, ctx=None):
|
||||
if not backend.cmac_algorithm_supported(algorithm):
|
||||
raise UnsupportedAlgorithm("This backend does not support CMAC.",
|
||||
_Reasons.UNSUPPORTED_CIPHER)
|
||||
|
||||
self._backend = backend
|
||||
self._key = algorithm.key
|
||||
self._algorithm = algorithm
|
||||
self._output_length = algorithm.block_size // 8
|
||||
|
||||
if ctx is None:
|
||||
registry = self._backend._cipher_registry
|
||||
adapter = registry[type(algorithm), CBC]
|
||||
|
||||
evp_cipher = adapter(self._backend, algorithm, CBC)
|
||||
|
||||
ctx = self._backend._lib.CMAC_CTX_new()
|
||||
|
||||
assert ctx != self._backend._ffi.NULL
|
||||
ctx = self._backend._ffi.gc(ctx, self._backend._lib.CMAC_CTX_free)
|
||||
|
||||
self._backend._lib.CMAC_Init(
|
||||
ctx, self._key, len(self._key),
|
||||
evp_cipher, self._backend._ffi.NULL
|
||||
)
|
||||
|
||||
self._ctx = ctx
|
||||
|
||||
def update(self, data):
|
||||
res = self._backend._lib.CMAC_Update(self._ctx, data, len(data))
|
||||
assert res == 1
|
||||
|
||||
def finalize(self):
|
||||
buf = self._backend._ffi.new("unsigned char[]", self._output_length)
|
||||
length = self._backend._ffi.new("size_t *", self._output_length)
|
||||
res = self._backend._lib.CMAC_Final(
|
||||
self._ctx, buf, length
|
||||
)
|
||||
assert res == 1
|
||||
|
||||
self._ctx = None
|
||||
|
||||
return self._backend._ffi.buffer(buf)[:]
|
||||
|
||||
def copy(self):
|
||||
copied_ctx = self._backend._lib.CMAC_CTX_new()
|
||||
copied_ctx = self._backend._ffi.gc(
|
||||
copied_ctx, self._backend._lib.CMAC_CTX_free
|
||||
)
|
||||
res = self._backend._lib.CMAC_CTX_copy(
|
||||
copied_ctx, self._ctx
|
||||
)
|
||||
assert res == 1
|
||||
return _CMACContext(
|
||||
self._backend, self._algorithm, ctx=copied_ctx
|
||||
)
|
|
@ -1,190 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
from cryptography.hazmat.primitives import hashes, interfaces
|
||||
from cryptography.hazmat.primitives.asymmetric import dsa
|
||||
from cryptography.hazmat.primitives.interfaces import (
|
||||
DSAParametersWithNumbers, DSAPrivateKeyWithNumbers, DSAPublicKeyWithNumbers
|
||||
)
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.AsymmetricVerificationContext)
|
||||
class _DSAVerificationContext(object):
|
||||
def __init__(self, backend, public_key, signature, algorithm):
|
||||
self._backend = backend
|
||||
self._public_key = public_key
|
||||
self._signature = signature
|
||||
self._algorithm = algorithm
|
||||
|
||||
self._hash_ctx = hashes.Hash(self._algorithm, self._backend)
|
||||
|
||||
def update(self, data):
|
||||
self._hash_ctx.update(data)
|
||||
|
||||
def verify(self):
|
||||
self._dsa_cdata = self._backend._ffi.gc(self._public_key._dsa_cdata,
|
||||
self._backend._lib.DSA_free)
|
||||
|
||||
data_to_verify = self._hash_ctx.finalize()
|
||||
|
||||
# The first parameter passed to DSA_verify is unused by OpenSSL but
|
||||
# must be an integer.
|
||||
res = self._backend._lib.DSA_verify(
|
||||
0, data_to_verify, len(data_to_verify), self._signature,
|
||||
len(self._signature), self._public_key._dsa_cdata)
|
||||
|
||||
if res != 1:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors
|
||||
if res == -1:
|
||||
assert errors[0].lib == self._backend._lib.ERR_LIB_ASN1
|
||||
|
||||
raise InvalidSignature
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.AsymmetricSignatureContext)
|
||||
class _DSASignatureContext(object):
|
||||
def __init__(self, backend, private_key, algorithm):
|
||||
self._backend = backend
|
||||
self._private_key = private_key
|
||||
self._algorithm = algorithm
|
||||
self._hash_ctx = hashes.Hash(self._algorithm, self._backend)
|
||||
|
||||
def update(self, data):
|
||||
self._hash_ctx.update(data)
|
||||
|
||||
def finalize(self):
|
||||
data_to_sign = self._hash_ctx.finalize()
|
||||
sig_buf_len = self._backend._lib.DSA_size(self._private_key._dsa_cdata)
|
||||
sig_buf = self._backend._ffi.new("unsigned char[]", sig_buf_len)
|
||||
buflen = self._backend._ffi.new("unsigned int *")
|
||||
|
||||
# The first parameter passed to DSA_sign is unused by OpenSSL but
|
||||
# must be an integer.
|
||||
res = self._backend._lib.DSA_sign(
|
||||
0, data_to_sign, len(data_to_sign), sig_buf,
|
||||
buflen, self._private_key._dsa_cdata)
|
||||
assert res == 1
|
||||
assert buflen[0]
|
||||
|
||||
return self._backend._ffi.buffer(sig_buf)[:buflen[0]]
|
||||
|
||||
|
||||
@utils.register_interface(DSAParametersWithNumbers)
|
||||
class _DSAParameters(object):
|
||||
def __init__(self, backend, dsa_cdata):
|
||||
self._backend = backend
|
||||
self._dsa_cdata = dsa_cdata
|
||||
|
||||
def parameter_numbers(self):
|
||||
return dsa.DSAParameterNumbers(
|
||||
p=self._backend._bn_to_int(self._dsa_cdata.p),
|
||||
q=self._backend._bn_to_int(self._dsa_cdata.q),
|
||||
g=self._backend._bn_to_int(self._dsa_cdata.g)
|
||||
)
|
||||
|
||||
def generate_private_key(self):
|
||||
return self._backend.generate_dsa_private_key(self)
|
||||
|
||||
|
||||
@utils.register_interface(DSAPrivateKeyWithNumbers)
|
||||
class _DSAPrivateKey(object):
|
||||
def __init__(self, backend, dsa_cdata):
|
||||
self._backend = backend
|
||||
self._dsa_cdata = dsa_cdata
|
||||
self._key_size = self._backend._lib.BN_num_bits(self._dsa_cdata.p)
|
||||
|
||||
@property
|
||||
def key_size(self):
|
||||
return self._key_size
|
||||
|
||||
def signer(self, algorithm):
|
||||
return _DSASignatureContext(self._backend, self, algorithm)
|
||||
|
||||
def private_numbers(self):
|
||||
return dsa.DSAPrivateNumbers(
|
||||
public_numbers=dsa.DSAPublicNumbers(
|
||||
parameter_numbers=dsa.DSAParameterNumbers(
|
||||
p=self._backend._bn_to_int(self._dsa_cdata.p),
|
||||
q=self._backend._bn_to_int(self._dsa_cdata.q),
|
||||
g=self._backend._bn_to_int(self._dsa_cdata.g)
|
||||
),
|
||||
y=self._backend._bn_to_int(self._dsa_cdata.pub_key)
|
||||
),
|
||||
x=self._backend._bn_to_int(self._dsa_cdata.priv_key)
|
||||
)
|
||||
|
||||
def public_key(self):
|
||||
dsa_cdata = self._backend._lib.DSA_new()
|
||||
assert dsa_cdata != self._backend._ffi.NULL
|
||||
dsa_cdata = self._backend._ffi.gc(
|
||||
dsa_cdata, self._backend._lib.DSA_free
|
||||
)
|
||||
dsa_cdata.p = self._backend._lib.BN_dup(self._dsa_cdata.p)
|
||||
dsa_cdata.q = self._backend._lib.BN_dup(self._dsa_cdata.q)
|
||||
dsa_cdata.g = self._backend._lib.BN_dup(self._dsa_cdata.g)
|
||||
dsa_cdata.pub_key = self._backend._lib.BN_dup(self._dsa_cdata.pub_key)
|
||||
return _DSAPublicKey(self._backend, dsa_cdata)
|
||||
|
||||
def parameters(self):
|
||||
dsa_cdata = self._backend._lib.DSA_new()
|
||||
assert dsa_cdata != self._backend._ffi.NULL
|
||||
dsa_cdata = self._backend._ffi.gc(
|
||||
dsa_cdata, self._backend._lib.DSA_free
|
||||
)
|
||||
dsa_cdata.p = self._backend._lib.BN_dup(self._dsa_cdata.p)
|
||||
dsa_cdata.q = self._backend._lib.BN_dup(self._dsa_cdata.q)
|
||||
dsa_cdata.g = self._backend._lib.BN_dup(self._dsa_cdata.g)
|
||||
return _DSAParameters(self._backend, dsa_cdata)
|
||||
|
||||
|
||||
@utils.register_interface(DSAPublicKeyWithNumbers)
|
||||
class _DSAPublicKey(object):
|
||||
def __init__(self, backend, dsa_cdata):
|
||||
self._backend = backend
|
||||
self._dsa_cdata = dsa_cdata
|
||||
self._key_size = self._backend._lib.BN_num_bits(self._dsa_cdata.p)
|
||||
|
||||
@property
|
||||
def key_size(self):
|
||||
return self._key_size
|
||||
|
||||
def verifier(self, signature, algorithm):
|
||||
return _DSAVerificationContext(
|
||||
self._backend, self, signature, algorithm
|
||||
)
|
||||
|
||||
def public_numbers(self):
|
||||
return dsa.DSAPublicNumbers(
|
||||
parameter_numbers=dsa.DSAParameterNumbers(
|
||||
p=self._backend._bn_to_int(self._dsa_cdata.p),
|
||||
q=self._backend._bn_to_int(self._dsa_cdata.q),
|
||||
g=self._backend._bn_to_int(self._dsa_cdata.g)
|
||||
),
|
||||
y=self._backend._bn_to_int(self._dsa_cdata.pub_key)
|
||||
)
|
||||
|
||||
def parameters(self):
|
||||
dsa_cdata = self._backend._lib.DSA_new()
|
||||
assert dsa_cdata != self._backend._ffi.NULL
|
||||
dsa_cdata = self._backend._ffi.gc(
|
||||
dsa_cdata, self._backend._lib.DSA_free
|
||||
)
|
||||
dsa_cdata.p = self._backend._lib.BN_dup(self._dsa_cdata.p)
|
||||
dsa_cdata.q = self._backend._lib.BN_dup(self._dsa_cdata.q)
|
||||
dsa_cdata.g = self._backend._lib.BN_dup(self._dsa_cdata.g)
|
||||
return _DSAParameters(self._backend, dsa_cdata)
|
|
@ -1,254 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import six
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import (
|
||||
InvalidSignature, UnsupportedAlgorithm, _Reasons
|
||||
)
|
||||
from cryptography.hazmat.primitives import hashes, interfaces
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
|
||||
|
||||
def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend):
|
||||
"""
|
||||
This function truncates digests that are longer than a given elliptic
|
||||
curve key's length so they can be signed. Since elliptic curve keys are
|
||||
much shorter than RSA keys many digests (e.g. SHA-512) may require
|
||||
truncation.
|
||||
"""
|
||||
|
||||
_lib = backend._lib
|
||||
_ffi = backend._ffi
|
||||
|
||||
digest_len = len(digest)
|
||||
|
||||
group = _lib.EC_KEY_get0_group(ec_key_cdata)
|
||||
|
||||
with backend._tmp_bn_ctx() as bn_ctx:
|
||||
order = _lib.BN_CTX_get(bn_ctx)
|
||||
assert order != _ffi.NULL
|
||||
|
||||
res = _lib.EC_GROUP_get_order(group, order, bn_ctx)
|
||||
assert res == 1
|
||||
|
||||
order_bits = _lib.BN_num_bits(order)
|
||||
|
||||
if 8 * digest_len > order_bits:
|
||||
digest_len = (order_bits + 7) // 8
|
||||
digest = digest[:digest_len]
|
||||
|
||||
if 8 * digest_len > order_bits:
|
||||
rshift = 8 - (order_bits & 0x7)
|
||||
assert rshift > 0 and rshift < 8
|
||||
|
||||
mask = 0xFF >> rshift << rshift
|
||||
|
||||
# Set the bottom rshift bits to 0
|
||||
digest = digest[:-1] + six.int2byte(six.indexbytes(digest, -1) & mask)
|
||||
|
||||
return digest
|
||||
|
||||
|
||||
def _ec_key_curve_sn(backend, ec_key):
|
||||
group = backend._lib.EC_KEY_get0_group(ec_key)
|
||||
assert group != backend._ffi.NULL
|
||||
|
||||
nid = backend._lib.EC_GROUP_get_curve_name(group)
|
||||
assert nid != backend._lib.NID_undef
|
||||
|
||||
curve_name = backend._lib.OBJ_nid2sn(nid)
|
||||
assert curve_name != backend._ffi.NULL
|
||||
|
||||
sn = backend._ffi.string(curve_name).decode('ascii')
|
||||
return sn
|
||||
|
||||
|
||||
def _sn_to_elliptic_curve(backend, sn):
|
||||
try:
|
||||
return ec._CURVE_TYPES[sn]()
|
||||
except KeyError:
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not a supported elliptic curve".format(sn),
|
||||
_Reasons.UNSUPPORTED_ELLIPTIC_CURVE
|
||||
)
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.AsymmetricSignatureContext)
|
||||
class _ECDSASignatureContext(object):
|
||||
def __init__(self, backend, private_key, algorithm):
|
||||
self._backend = backend
|
||||
self._private_key = private_key
|
||||
self._digest = hashes.Hash(algorithm, backend)
|
||||
|
||||
def update(self, data):
|
||||
self._digest.update(data)
|
||||
|
||||
def finalize(self):
|
||||
ec_key = self._private_key._ec_key
|
||||
|
||||
digest = self._digest.finalize()
|
||||
|
||||
digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend)
|
||||
|
||||
max_size = self._backend._lib.ECDSA_size(ec_key)
|
||||
assert max_size > 0
|
||||
|
||||
sigbuf = self._backend._ffi.new("char[]", max_size)
|
||||
siglen_ptr = self._backend._ffi.new("unsigned int[]", 1)
|
||||
res = self._backend._lib.ECDSA_sign(
|
||||
0,
|
||||
digest,
|
||||
len(digest),
|
||||
sigbuf,
|
||||
siglen_ptr,
|
||||
ec_key
|
||||
)
|
||||
assert res == 1
|
||||
return self._backend._ffi.buffer(sigbuf)[:siglen_ptr[0]]
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.AsymmetricVerificationContext)
|
||||
class _ECDSAVerificationContext(object):
|
||||
def __init__(self, backend, public_key, signature, algorithm):
|
||||
self._backend = backend
|
||||
self._public_key = public_key
|
||||
self._signature = signature
|
||||
self._digest = hashes.Hash(algorithm, backend)
|
||||
|
||||
def update(self, data):
|
||||
self._digest.update(data)
|
||||
|
||||
def verify(self):
|
||||
ec_key = self._public_key._ec_key
|
||||
|
||||
digest = self._digest.finalize()
|
||||
|
||||
digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend)
|
||||
|
||||
res = self._backend._lib.ECDSA_verify(
|
||||
0,
|
||||
digest,
|
||||
len(digest),
|
||||
self._signature,
|
||||
len(self._signature),
|
||||
ec_key
|
||||
)
|
||||
if res != 1:
|
||||
self._backend._consume_errors()
|
||||
raise InvalidSignature
|
||||
return True
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.EllipticCurvePrivateKeyWithNumbers)
|
||||
class _EllipticCurvePrivateKey(object):
|
||||
def __init__(self, backend, ec_key_cdata):
|
||||
self._backend = backend
|
||||
self._ec_key = ec_key_cdata
|
||||
|
||||
sn = _ec_key_curve_sn(backend, ec_key_cdata)
|
||||
self._curve = _sn_to_elliptic_curve(backend, sn)
|
||||
|
||||
@property
|
||||
def curve(self):
|
||||
return self._curve
|
||||
|
||||
def signer(self, signature_algorithm):
|
||||
if isinstance(signature_algorithm, ec.ECDSA):
|
||||
return _ECDSASignatureContext(
|
||||
self._backend, self, signature_algorithm.algorithm
|
||||
)
|
||||
else:
|
||||
raise UnsupportedAlgorithm(
|
||||
"Unsupported elliptic curve signature algorithm.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def public_key(self):
|
||||
group = self._backend._lib.EC_KEY_get0_group(self._ec_key)
|
||||
assert group != self._backend._ffi.NULL
|
||||
|
||||
curve_nid = self._backend._lib.EC_GROUP_get_curve_name(group)
|
||||
|
||||
public_ec_key = self._backend._lib.EC_KEY_new_by_curve_name(curve_nid)
|
||||
assert public_ec_key != self._backend._ffi.NULL
|
||||
public_ec_key = self._backend._ffi.gc(
|
||||
public_ec_key, self._backend._lib.EC_KEY_free
|
||||
)
|
||||
|
||||
point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key)
|
||||
assert point != self._backend._ffi.NULL
|
||||
|
||||
res = self._backend._lib.EC_KEY_set_public_key(public_ec_key, point)
|
||||
assert res == 1
|
||||
|
||||
return _EllipticCurvePublicKey(
|
||||
self._backend, public_ec_key
|
||||
)
|
||||
|
||||
def private_numbers(self):
|
||||
bn = self._backend._lib.EC_KEY_get0_private_key(self._ec_key)
|
||||
private_value = self._backend._bn_to_int(bn)
|
||||
return ec.EllipticCurvePrivateNumbers(
|
||||
private_value=private_value,
|
||||
public_numbers=self.public_key().public_numbers()
|
||||
)
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.EllipticCurvePublicKeyWithNumbers)
|
||||
class _EllipticCurvePublicKey(object):
|
||||
def __init__(self, backend, ec_key_cdata):
|
||||
self._backend = backend
|
||||
self._ec_key = ec_key_cdata
|
||||
|
||||
sn = _ec_key_curve_sn(backend, ec_key_cdata)
|
||||
self._curve = _sn_to_elliptic_curve(backend, sn)
|
||||
|
||||
@property
|
||||
def curve(self):
|
||||
return self._curve
|
||||
|
||||
def verifier(self, signature, signature_algorithm):
|
||||
if isinstance(signature_algorithm, ec.ECDSA):
|
||||
return _ECDSAVerificationContext(
|
||||
self._backend, self, signature, signature_algorithm.algorithm
|
||||
)
|
||||
else:
|
||||
raise UnsupportedAlgorithm(
|
||||
"Unsupported elliptic curve signature algorithm.",
|
||||
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
|
||||
|
||||
def public_numbers(self):
|
||||
set_func, get_func, group = (
|
||||
self._backend._ec_key_determine_group_get_set_funcs(self._ec_key)
|
||||
)
|
||||
point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key)
|
||||
assert point != self._backend._ffi.NULL
|
||||
|
||||
with self._backend._tmp_bn_ctx() as bn_ctx:
|
||||
bn_x = self._backend._lib.BN_CTX_get(bn_ctx)
|
||||
bn_y = self._backend._lib.BN_CTX_get(bn_ctx)
|
||||
|
||||
res = get_func(group, point, bn_x, bn_y, bn_ctx)
|
||||
assert res == 1
|
||||
|
||||
x = self._backend._bn_to_int(bn_x)
|
||||
y = self._backend._bn_to_int(bn_y)
|
||||
|
||||
return ec.EllipticCurvePublicNumbers(
|
||||
x=x,
|
||||
y=y,
|
||||
curve=self._curve
|
||||
)
|
|
@ -1,69 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.primitives import interfaces
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.HashContext)
|
||||
class _HashContext(object):
|
||||
def __init__(self, backend, algorithm, ctx=None):
|
||||
self.algorithm = algorithm
|
||||
|
||||
self._backend = backend
|
||||
|
||||
if ctx is None:
|
||||
ctx = self._backend._lib.EVP_MD_CTX_create()
|
||||
ctx = self._backend._ffi.gc(ctx,
|
||||
self._backend._lib.EVP_MD_CTX_destroy)
|
||||
evp_md = self._backend._lib.EVP_get_digestbyname(
|
||||
algorithm.name.encode("ascii"))
|
||||
if evp_md == self._backend._ffi.NULL:
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not a supported hash on this backend.".format(
|
||||
algorithm.name),
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
res = self._backend._lib.EVP_DigestInit_ex(ctx, evp_md,
|
||||
self._backend._ffi.NULL)
|
||||
assert res != 0
|
||||
|
||||
self._ctx = ctx
|
||||
|
||||
def copy(self):
|
||||
copied_ctx = self._backend._lib.EVP_MD_CTX_create()
|
||||
copied_ctx = self._backend._ffi.gc(
|
||||
copied_ctx, self._backend._lib.EVP_MD_CTX_destroy
|
||||
)
|
||||
res = self._backend._lib.EVP_MD_CTX_copy_ex(copied_ctx, self._ctx)
|
||||
assert res != 0
|
||||
return _HashContext(self._backend, self.algorithm, ctx=copied_ctx)
|
||||
|
||||
def update(self, data):
|
||||
res = self._backend._lib.EVP_DigestUpdate(self._ctx, data, len(data))
|
||||
assert res != 0
|
||||
|
||||
def finalize(self):
|
||||
buf = self._backend._ffi.new("unsigned char[]",
|
||||
self._backend._lib.EVP_MAX_MD_SIZE)
|
||||
outlen = self._backend._ffi.new("unsigned int *")
|
||||
res = self._backend._lib.EVP_DigestFinal_ex(self._ctx, buf, outlen)
|
||||
assert res != 0
|
||||
assert outlen[0] == self.algorithm.digest_size
|
||||
res = self._backend._lib.EVP_MD_CTX_cleanup(self._ctx)
|
||||
assert res == 1
|
||||
return self._backend._ffi.buffer(buf)[:outlen[0]]
|
|
@ -1,80 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import UnsupportedAlgorithm, _Reasons
|
||||
from cryptography.hazmat.primitives import interfaces
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.HashContext)
|
||||
class _HMACContext(object):
|
||||
def __init__(self, backend, key, algorithm, ctx=None):
|
||||
self.algorithm = algorithm
|
||||
self._backend = backend
|
||||
|
||||
if ctx is None:
|
||||
ctx = self._backend._ffi.new("HMAC_CTX *")
|
||||
self._backend._lib.HMAC_CTX_init(ctx)
|
||||
ctx = self._backend._ffi.gc(
|
||||
ctx, self._backend._lib.HMAC_CTX_cleanup
|
||||
)
|
||||
evp_md = self._backend._lib.EVP_get_digestbyname(
|
||||
algorithm.name.encode('ascii'))
|
||||
if evp_md == self._backend._ffi.NULL:
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not a supported hash on this backend.".format(
|
||||
algorithm.name),
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
res = self._backend._lib.Cryptography_HMAC_Init_ex(
|
||||
ctx, key, len(key), evp_md, self._backend._ffi.NULL
|
||||
)
|
||||
assert res != 0
|
||||
|
||||
self._ctx = ctx
|
||||
self._key = key
|
||||
|
||||
def copy(self):
|
||||
copied_ctx = self._backend._ffi.new("HMAC_CTX *")
|
||||
self._backend._lib.HMAC_CTX_init(copied_ctx)
|
||||
copied_ctx = self._backend._ffi.gc(
|
||||
copied_ctx, self._backend._lib.HMAC_CTX_cleanup
|
||||
)
|
||||
res = self._backend._lib.Cryptography_HMAC_CTX_copy(
|
||||
copied_ctx, self._ctx
|
||||
)
|
||||
assert res != 0
|
||||
return _HMACContext(
|
||||
self._backend, self._key, self.algorithm, ctx=copied_ctx
|
||||
)
|
||||
|
||||
def update(self, data):
|
||||
res = self._backend._lib.Cryptography_HMAC_Update(
|
||||
self._ctx, data, len(data)
|
||||
)
|
||||
assert res != 0
|
||||
|
||||
def finalize(self):
|
||||
buf = self._backend._ffi.new("unsigned char[]",
|
||||
self._backend._lib.EVP_MAX_MD_SIZE)
|
||||
outlen = self._backend._ffi.new("unsigned int *")
|
||||
res = self._backend._lib.Cryptography_HMAC_Final(
|
||||
self._ctx, buf, outlen
|
||||
)
|
||||
assert res != 0
|
||||
assert outlen[0] == self.algorithm.digest_size
|
||||
self._backend._lib.HMAC_CTX_cleanup(self._ctx)
|
||||
return self._backend._ffi.buffer(buf)[:outlen[0]]
|
|
@ -1,603 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import math
|
||||
|
||||
from cryptography import utils
|
||||
from cryptography.exceptions import (
|
||||
AlreadyFinalized, InvalidSignature, UnsupportedAlgorithm, _Reasons
|
||||
)
|
||||
from cryptography.hazmat.primitives import hashes, interfaces
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
from cryptography.hazmat.primitives.asymmetric.padding import (
|
||||
MGF1, OAEP, PKCS1v15, PSS
|
||||
)
|
||||
from cryptography.hazmat.primitives.interfaces import (
|
||||
RSAPrivateKeyWithNumbers, RSAPublicKeyWithNumbers
|
||||
)
|
||||
|
||||
|
||||
def _get_rsa_pss_salt_length(pss, key_size, digest_size):
|
||||
salt = pss._salt_length
|
||||
|
||||
if salt is MGF1.MAX_LENGTH or salt is PSS.MAX_LENGTH:
|
||||
# bit length - 1 per RFC 3447
|
||||
emlen = int(math.ceil((key_size - 1) / 8.0))
|
||||
salt_length = emlen - digest_size - 2
|
||||
assert salt_length >= 0
|
||||
return salt_length
|
||||
else:
|
||||
return salt
|
||||
|
||||
|
||||
def _enc_dec_rsa(backend, key, data, padding):
|
||||
if not isinstance(padding, interfaces.AsymmetricPadding):
|
||||
raise TypeError("Padding must be an instance of AsymmetricPadding.")
|
||||
|
||||
if isinstance(padding, PKCS1v15):
|
||||
padding_enum = backend._lib.RSA_PKCS1_PADDING
|
||||
elif isinstance(padding, OAEP):
|
||||
padding_enum = backend._lib.RSA_PKCS1_OAEP_PADDING
|
||||
if not isinstance(padding._mgf, MGF1):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Only MGF1 is supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_MGF
|
||||
)
|
||||
|
||||
if not isinstance(padding._mgf._algorithm, hashes.SHA1):
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend supports only SHA1 inside MGF1 when "
|
||||
"using OAEP.",
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
|
||||
if padding._label is not None and padding._label != b"":
|
||||
raise ValueError("This backend does not support OAEP labels.")
|
||||
|
||||
if not isinstance(padding._algorithm, hashes.SHA1):
|
||||
raise UnsupportedAlgorithm(
|
||||
"This backend only supports SHA1 when using OAEP.",
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
else:
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not supported by this backend.".format(
|
||||
padding.name
|
||||
),
|
||||
_Reasons.UNSUPPORTED_PADDING
|
||||
)
|
||||
|
||||
if backend._lib.Cryptography_HAS_PKEY_CTX:
|
||||
return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum)
|
||||
else:
|
||||
return _enc_dec_rsa_098(backend, key, data, padding_enum)
|
||||
|
||||
|
||||
def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum):
|
||||
if isinstance(key, _RSAPublicKey):
|
||||
init = backend._lib.EVP_PKEY_encrypt_init
|
||||
crypt = backend._lib.Cryptography_EVP_PKEY_encrypt
|
||||
else:
|
||||
init = backend._lib.EVP_PKEY_decrypt_init
|
||||
crypt = backend._lib.Cryptography_EVP_PKEY_decrypt
|
||||
|
||||
pkey_ctx = backend._lib.EVP_PKEY_CTX_new(
|
||||
key._evp_pkey, backend._ffi.NULL
|
||||
)
|
||||
assert pkey_ctx != backend._ffi.NULL
|
||||
pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free)
|
||||
res = init(pkey_ctx)
|
||||
assert res == 1
|
||||
res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(
|
||||
pkey_ctx, padding_enum)
|
||||
assert res > 0
|
||||
buf_size = backend._lib.EVP_PKEY_size(key._evp_pkey)
|
||||
assert buf_size > 0
|
||||
outlen = backend._ffi.new("size_t *", buf_size)
|
||||
buf = backend._ffi.new("char[]", buf_size)
|
||||
res = crypt(pkey_ctx, buf, outlen, data, len(data))
|
||||
if res <= 0:
|
||||
_handle_rsa_enc_dec_error(backend, key)
|
||||
|
||||
return backend._ffi.buffer(buf)[:outlen[0]]
|
||||
|
||||
|
||||
def _enc_dec_rsa_098(backend, key, data, padding_enum):
|
||||
if isinstance(key, _RSAPublicKey):
|
||||
crypt = backend._lib.RSA_public_encrypt
|
||||
else:
|
||||
crypt = backend._lib.RSA_private_decrypt
|
||||
|
||||
key_size = backend._lib.RSA_size(key._rsa_cdata)
|
||||
assert key_size > 0
|
||||
buf = backend._ffi.new("unsigned char[]", key_size)
|
||||
res = crypt(len(data), data, buf, key._rsa_cdata, padding_enum)
|
||||
if res < 0:
|
||||
_handle_rsa_enc_dec_error(backend, key)
|
||||
|
||||
return backend._ffi.buffer(buf)[:res]
|
||||
|
||||
|
||||
def _handle_rsa_enc_dec_error(backend, key):
|
||||
errors = backend._consume_errors()
|
||||
assert errors
|
||||
assert errors[0].lib == backend._lib.ERR_LIB_RSA
|
||||
if isinstance(key, _RSAPublicKey):
|
||||
assert (errors[0].reason ==
|
||||
backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE)
|
||||
raise ValueError(
|
||||
"Data too long for key size. Encrypt less data or use a "
|
||||
"larger key size."
|
||||
)
|
||||
else:
|
||||
assert (
|
||||
errors[0].reason == backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_01 or
|
||||
errors[0].reason == backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_02
|
||||
)
|
||||
raise ValueError("Decryption failed.")
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.AsymmetricSignatureContext)
|
||||
class _RSASignatureContext(object):
|
||||
def __init__(self, backend, private_key, padding, algorithm):
|
||||
self._backend = backend
|
||||
self._private_key = private_key
|
||||
|
||||
if not isinstance(padding, interfaces.AsymmetricPadding):
|
||||
raise TypeError(
|
||||
"Expected provider of interfaces.AsymmetricPadding.")
|
||||
|
||||
self._pkey_size = self._backend._lib.EVP_PKEY_size(
|
||||
self._private_key._evp_pkey
|
||||
)
|
||||
|
||||
if isinstance(padding, PKCS1v15):
|
||||
if self._backend._lib.Cryptography_HAS_PKEY_CTX:
|
||||
self._finalize_method = self._finalize_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PADDING
|
||||
else:
|
||||
self._finalize_method = self._finalize_pkcs1
|
||||
elif isinstance(padding, PSS):
|
||||
if not isinstance(padding._mgf, MGF1):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Only MGF1 is supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_MGF
|
||||
)
|
||||
|
||||
# Size of key in bytes - 2 is the maximum
|
||||
# PSS signature length (salt length is checked later)
|
||||
assert self._pkey_size > 0
|
||||
if self._pkey_size - algorithm.digest_size - 2 < 0:
|
||||
raise ValueError("Digest too large for key size. Use a larger "
|
||||
"key.")
|
||||
|
||||
if not self._backend._mgf1_hash_supported(padding._mgf._algorithm):
|
||||
raise UnsupportedAlgorithm(
|
||||
"When OpenSSL is older than 1.0.1 then only SHA1 is "
|
||||
"supported with MGF1.",
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
|
||||
if self._backend._lib.Cryptography_HAS_PKEY_CTX:
|
||||
self._finalize_method = self._finalize_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PSS_PADDING
|
||||
else:
|
||||
self._finalize_method = self._finalize_pss
|
||||
else:
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not supported by this backend.".format(padding.name),
|
||||
_Reasons.UNSUPPORTED_PADDING
|
||||
)
|
||||
|
||||
self._padding = padding
|
||||
self._algorithm = algorithm
|
||||
self._hash_ctx = hashes.Hash(self._algorithm, self._backend)
|
||||
|
||||
def update(self, data):
|
||||
self._hash_ctx.update(data)
|
||||
|
||||
def finalize(self):
|
||||
evp_md = self._backend._lib.EVP_get_digestbyname(
|
||||
self._algorithm.name.encode("ascii"))
|
||||
assert evp_md != self._backend._ffi.NULL
|
||||
|
||||
return self._finalize_method(evp_md)
|
||||
|
||||
def _finalize_pkey_ctx(self, evp_md):
|
||||
pkey_ctx = self._backend._lib.EVP_PKEY_CTX_new(
|
||||
self._private_key._evp_pkey, self._backend._ffi.NULL
|
||||
)
|
||||
assert pkey_ctx != self._backend._ffi.NULL
|
||||
pkey_ctx = self._backend._ffi.gc(pkey_ctx,
|
||||
self._backend._lib.EVP_PKEY_CTX_free)
|
||||
res = self._backend._lib.EVP_PKEY_sign_init(pkey_ctx)
|
||||
assert res == 1
|
||||
res = self._backend._lib.EVP_PKEY_CTX_set_signature_md(
|
||||
pkey_ctx, evp_md)
|
||||
assert res > 0
|
||||
|
||||
res = self._backend._lib.EVP_PKEY_CTX_set_rsa_padding(
|
||||
pkey_ctx, self._padding_enum)
|
||||
assert res > 0
|
||||
if isinstance(self._padding, PSS):
|
||||
res = self._backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen(
|
||||
pkey_ctx,
|
||||
_get_rsa_pss_salt_length(
|
||||
self._padding,
|
||||
self._private_key.key_size,
|
||||
self._hash_ctx.algorithm.digest_size
|
||||
)
|
||||
)
|
||||
assert res > 0
|
||||
|
||||
if self._backend._lib.Cryptography_HAS_MGF1_MD:
|
||||
# MGF1 MD is configurable in OpenSSL 1.0.1+
|
||||
mgf1_md = self._backend._lib.EVP_get_digestbyname(
|
||||
self._padding._mgf._algorithm.name.encode("ascii"))
|
||||
assert mgf1_md != self._backend._ffi.NULL
|
||||
res = self._backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(
|
||||
pkey_ctx, mgf1_md
|
||||
)
|
||||
assert res > 0
|
||||
data_to_sign = self._hash_ctx.finalize()
|
||||
buflen = self._backend._ffi.new("size_t *")
|
||||
res = self._backend._lib.EVP_PKEY_sign(
|
||||
pkey_ctx,
|
||||
self._backend._ffi.NULL,
|
||||
buflen,
|
||||
data_to_sign,
|
||||
len(data_to_sign)
|
||||
)
|
||||
assert res == 1
|
||||
buf = self._backend._ffi.new("unsigned char[]", buflen[0])
|
||||
res = self._backend._lib.EVP_PKEY_sign(
|
||||
pkey_ctx, buf, buflen, data_to_sign, len(data_to_sign))
|
||||
if res != 1:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors[0].lib == self._backend._lib.ERR_LIB_RSA
|
||||
reason = None
|
||||
if (errors[0].reason ==
|
||||
self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE):
|
||||
reason = ("Salt length too long for key size. Try using "
|
||||
"MAX_LENGTH instead.")
|
||||
elif (errors[0].reason ==
|
||||
self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY):
|
||||
reason = "Digest too large for key size. Use a larger key."
|
||||
assert reason is not None
|
||||
raise ValueError(reason)
|
||||
|
||||
return self._backend._ffi.buffer(buf)[:]
|
||||
|
||||
def _finalize_pkcs1(self, evp_md):
|
||||
if self._hash_ctx._ctx is None:
|
||||
raise AlreadyFinalized("Context has already been finalized.")
|
||||
|
||||
sig_buf = self._backend._ffi.new("char[]", self._pkey_size)
|
||||
sig_len = self._backend._ffi.new("unsigned int *")
|
||||
res = self._backend._lib.EVP_SignFinal(
|
||||
self._hash_ctx._ctx._ctx,
|
||||
sig_buf,
|
||||
sig_len,
|
||||
self._private_key._evp_pkey
|
||||
)
|
||||
self._hash_ctx.finalize()
|
||||
if res == 0:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors[0].lib == self._backend._lib.ERR_LIB_RSA
|
||||
assert (errors[0].reason ==
|
||||
self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY)
|
||||
raise ValueError("Digest too large for key size. Use a larger "
|
||||
"key.")
|
||||
|
||||
return self._backend._ffi.buffer(sig_buf)[:sig_len[0]]
|
||||
|
||||
def _finalize_pss(self, evp_md):
|
||||
data_to_sign = self._hash_ctx.finalize()
|
||||
padded = self._backend._ffi.new("unsigned char[]", self._pkey_size)
|
||||
res = self._backend._lib.RSA_padding_add_PKCS1_PSS(
|
||||
self._private_key._rsa_cdata,
|
||||
padded,
|
||||
data_to_sign,
|
||||
evp_md,
|
||||
_get_rsa_pss_salt_length(
|
||||
self._padding,
|
||||
self._private_key.key_size,
|
||||
len(data_to_sign)
|
||||
)
|
||||
)
|
||||
if res != 1:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors[0].lib == self._backend._lib.ERR_LIB_RSA
|
||||
assert (errors[0].reason ==
|
||||
self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE)
|
||||
raise ValueError("Salt length too long for key size. Try using "
|
||||
"MAX_LENGTH instead.")
|
||||
|
||||
sig_buf = self._backend._ffi.new("char[]", self._pkey_size)
|
||||
sig_len = self._backend._lib.RSA_private_encrypt(
|
||||
self._pkey_size,
|
||||
padded,
|
||||
sig_buf,
|
||||
self._private_key._rsa_cdata,
|
||||
self._backend._lib.RSA_NO_PADDING
|
||||
)
|
||||
assert sig_len != -1
|
||||
return self._backend._ffi.buffer(sig_buf)[:sig_len]
|
||||
|
||||
|
||||
@utils.register_interface(interfaces.AsymmetricVerificationContext)
|
||||
class _RSAVerificationContext(object):
|
||||
def __init__(self, backend, public_key, signature, padding, algorithm):
|
||||
self._backend = backend
|
||||
self._public_key = public_key
|
||||
self._signature = signature
|
||||
|
||||
if not isinstance(padding, interfaces.AsymmetricPadding):
|
||||
raise TypeError(
|
||||
"Expected provider of interfaces.AsymmetricPadding.")
|
||||
|
||||
self._pkey_size = self._backend._lib.EVP_PKEY_size(
|
||||
self._public_key._evp_pkey
|
||||
)
|
||||
|
||||
if isinstance(padding, PKCS1v15):
|
||||
if self._backend._lib.Cryptography_HAS_PKEY_CTX:
|
||||
self._verify_method = self._verify_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PADDING
|
||||
else:
|
||||
self._verify_method = self._verify_pkcs1
|
||||
elif isinstance(padding, PSS):
|
||||
if not isinstance(padding._mgf, MGF1):
|
||||
raise UnsupportedAlgorithm(
|
||||
"Only MGF1 is supported by this backend.",
|
||||
_Reasons.UNSUPPORTED_MGF
|
||||
)
|
||||
|
||||
# Size of key in bytes - 2 is the maximum
|
||||
# PSS signature length (salt length is checked later)
|
||||
assert self._pkey_size > 0
|
||||
if self._pkey_size - algorithm.digest_size - 2 < 0:
|
||||
raise ValueError(
|
||||
"Digest too large for key size. Check that you have the "
|
||||
"correct key and digest algorithm."
|
||||
)
|
||||
|
||||
if not self._backend._mgf1_hash_supported(padding._mgf._algorithm):
|
||||
raise UnsupportedAlgorithm(
|
||||
"When OpenSSL is older than 1.0.1 then only SHA1 is "
|
||||
"supported with MGF1.",
|
||||
_Reasons.UNSUPPORTED_HASH
|
||||
)
|
||||
|
||||
if self._backend._lib.Cryptography_HAS_PKEY_CTX:
|
||||
self._verify_method = self._verify_pkey_ctx
|
||||
self._padding_enum = self._backend._lib.RSA_PKCS1_PSS_PADDING
|
||||
else:
|
||||
self._verify_method = self._verify_pss
|
||||
else:
|
||||
raise UnsupportedAlgorithm(
|
||||
"{0} is not supported by this backend.".format(padding.name),
|
||||
_Reasons.UNSUPPORTED_PADDING
|
||||
)
|
||||
|
||||
self._padding = padding
|
||||
self._algorithm = algorithm
|
||||
self._hash_ctx = hashes.Hash(self._algorithm, self._backend)
|
||||
|
||||
def update(self, data):
|
||||
self._hash_ctx.update(data)
|
||||
|
||||
def verify(self):
|
||||
evp_md = self._backend._lib.EVP_get_digestbyname(
|
||||
self._algorithm.name.encode("ascii"))
|
||||
assert evp_md != self._backend._ffi.NULL
|
||||
|
||||
self._verify_method(evp_md)
|
||||
|
||||
def _verify_pkey_ctx(self, evp_md):
|
||||
pkey_ctx = self._backend._lib.EVP_PKEY_CTX_new(
|
||||
self._public_key._evp_pkey, self._backend._ffi.NULL
|
||||
)
|
||||
assert pkey_ctx != self._backend._ffi.NULL
|
||||
pkey_ctx = self._backend._ffi.gc(pkey_ctx,
|
||||
self._backend._lib.EVP_PKEY_CTX_free)
|
||||
res = self._backend._lib.EVP_PKEY_verify_init(pkey_ctx)
|
||||
assert res == 1
|
||||
res = self._backend._lib.EVP_PKEY_CTX_set_signature_md(
|
||||
pkey_ctx, evp_md)
|
||||
assert res > 0
|
||||
|
||||
res = self._backend._lib.EVP_PKEY_CTX_set_rsa_padding(
|
||||
pkey_ctx, self._padding_enum)
|
||||
assert res > 0
|
||||
if isinstance(self._padding, PSS):
|
||||
res = self._backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen(
|
||||
pkey_ctx,
|
||||
_get_rsa_pss_salt_length(
|
||||
self._padding,
|
||||
self._public_key.key_size,
|
||||
self._hash_ctx.algorithm.digest_size
|
||||
)
|
||||
)
|
||||
assert res > 0
|
||||
if self._backend._lib.Cryptography_HAS_MGF1_MD:
|
||||
# MGF1 MD is configurable in OpenSSL 1.0.1+
|
||||
mgf1_md = self._backend._lib.EVP_get_digestbyname(
|
||||
self._padding._mgf._algorithm.name.encode("ascii"))
|
||||
assert mgf1_md != self._backend._ffi.NULL
|
||||
res = self._backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(
|
||||
pkey_ctx, mgf1_md
|
||||
)
|
||||
assert res > 0
|
||||
|
||||
data_to_verify = self._hash_ctx.finalize()
|
||||
res = self._backend._lib.EVP_PKEY_verify(
|
||||
pkey_ctx,
|
||||
self._signature,
|
||||
len(self._signature),
|
||||
data_to_verify,
|
||||
len(data_to_verify)
|
||||
)
|
||||
# The previous call can return negative numbers in the event of an
|
||||
# error. This is not a signature failure but we need to fail if it
|
||||
# occurs.
|
||||
assert res >= 0
|
||||
if res == 0:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors
|
||||
raise InvalidSignature
|
||||
|
||||
def _verify_pkcs1(self, evp_md):
|
||||
if self._hash_ctx._ctx is None:
|
||||
raise AlreadyFinalized("Context has already been finalized.")
|
||||
|
||||
res = self._backend._lib.EVP_VerifyFinal(
|
||||
self._hash_ctx._ctx._ctx,
|
||||
self._signature,
|
||||
len(self._signature),
|
||||
self._public_key._evp_pkey
|
||||
)
|
||||
self._hash_ctx.finalize()
|
||||
# The previous call can return negative numbers in the event of an
|
||||
# error. This is not a signature failure but we need to fail if it
|
||||
# occurs.
|
||||
assert res >= 0
|
||||
if res == 0:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors
|
||||
raise InvalidSignature
|
||||
|
||||
def _verify_pss(self, evp_md):
|
||||
buf = self._backend._ffi.new("unsigned char[]", self._pkey_size)
|
||||
res = self._backend._lib.RSA_public_decrypt(
|
||||
len(self._signature),
|
||||
self._signature,
|
||||
buf,
|
||||
self._public_key._rsa_cdata,
|
||||
self._backend._lib.RSA_NO_PADDING
|
||||
)
|
||||
if res != self._pkey_size:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors
|
||||
raise InvalidSignature
|
||||
|
||||
data_to_verify = self._hash_ctx.finalize()
|
||||
res = self._backend._lib.RSA_verify_PKCS1_PSS(
|
||||
self._public_key._rsa_cdata,
|
||||
data_to_verify,
|
||||
evp_md,
|
||||
buf,
|
||||
_get_rsa_pss_salt_length(
|
||||
self._padding,
|
||||
self._public_key.key_size,
|
||||
len(data_to_verify)
|
||||
)
|
||||
)
|
||||
if res != 1:
|
||||
errors = self._backend._consume_errors()
|
||||
assert errors
|
||||
raise InvalidSignature
|
||||
|
||||
|
||||
@utils.register_interface(RSAPrivateKeyWithNumbers)
|
||||
class _RSAPrivateKey(object):
|
||||
def __init__(self, backend, rsa_cdata):
|
||||
self._backend = backend
|
||||
self._rsa_cdata = rsa_cdata
|
||||
|
||||
evp_pkey = self._backend._lib.EVP_PKEY_new()
|
||||
assert evp_pkey != self._backend._ffi.NULL
|
||||
evp_pkey = self._backend._ffi.gc(
|
||||
evp_pkey, self._backend._lib.EVP_PKEY_free
|
||||
)
|
||||
res = self._backend._lib.EVP_PKEY_set1_RSA(evp_pkey, rsa_cdata)
|
||||
assert res == 1
|
||||
self._evp_pkey = evp_pkey
|
||||
|
||||
self._key_size = self._backend._lib.BN_num_bits(self._rsa_cdata.n)
|
||||
|
||||
@property
|
||||
def key_size(self):
|
||||
return self._key_size
|
||||
|
||||
def signer(self, padding, algorithm):
|
||||
return _RSASignatureContext(self._backend, self, padding, algorithm)
|
||||
|
||||
def decrypt(self, ciphertext, padding):
|
||||
key_size_bytes = int(math.ceil(self.key_size / 8.0))
|
||||
if key_size_bytes != len(ciphertext):
|
||||
raise ValueError("Ciphertext length must be equal to key size.")
|
||||
|
||||
return _enc_dec_rsa(self._backend, self, ciphertext, padding)
|
||||
|
||||
def public_key(self):
|
||||
ctx = self._backend._lib.RSA_new()
|
||||
assert ctx != self._backend._ffi.NULL
|
||||
ctx = self._backend._ffi.gc(ctx, self._backend._lib.RSA_free)
|
||||
ctx.e = self._backend._lib.BN_dup(self._rsa_cdata.e)
|
||||
ctx.n = self._backend._lib.BN_dup(self._rsa_cdata.n)
|
||||
res = self._backend._lib.RSA_blinding_on(ctx, self._backend._ffi.NULL)
|
||||
assert res == 1
|
||||
return _RSAPublicKey(self._backend, ctx)
|
||||
|
||||
def private_numbers(self):
|
||||
return rsa.RSAPrivateNumbers(
|
||||
p=self._backend._bn_to_int(self._rsa_cdata.p),
|
||||
q=self._backend._bn_to_int(self._rsa_cdata.q),
|
||||
d=self._backend._bn_to_int(self._rsa_cdata.d),
|
||||
dmp1=self._backend._bn_to_int(self._rsa_cdata.dmp1),
|
||||
dmq1=self._backend._bn_to_int(self._rsa_cdata.dmq1),
|
||||
iqmp=self._backend._bn_to_int(self._rsa_cdata.iqmp),
|
||||
public_numbers=rsa.RSAPublicNumbers(
|
||||
e=self._backend._bn_to_int(self._rsa_cdata.e),
|
||||
n=self._backend._bn_to_int(self._rsa_cdata.n),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@utils.register_interface(RSAPublicKeyWithNumbers)
|
||||
class _RSAPublicKey(object):
|
||||
def __init__(self, backend, rsa_cdata):
|
||||
self._backend = backend
|
||||
self._rsa_cdata = rsa_cdata
|
||||
|
||||
evp_pkey = self._backend._lib.EVP_PKEY_new()
|
||||
assert evp_pkey != self._backend._ffi.NULL
|
||||
evp_pkey = self._backend._ffi.gc(
|
||||
evp_pkey, self._backend._lib.EVP_PKEY_free
|
||||
)
|
||||
res = self._backend._lib.EVP_PKEY_set1_RSA(evp_pkey, rsa_cdata)
|
||||
assert res == 1
|
||||
self._evp_pkey = evp_pkey
|
||||
|
||||
self._key_size = self._backend._lib.BN_num_bits(self._rsa_cdata.n)
|
||||
|
||||
@property
|
||||
def key_size(self):
|
||||
return self._key_size
|
||||
|
||||
def verifier(self, signature, padding, algorithm):
|
||||
return _RSAVerificationContext(
|
||||
self._backend, self, signature, padding, algorithm
|
||||
)
|
||||
|
||||
def encrypt(self, plaintext, padding):
|
||||
return _enc_dec_rsa(self._backend, self, plaintext, padding)
|
||||
|
||||
def public_numbers(self):
|
||||
return rsa.RSAPublicNumbers(
|
||||
e=self._backend._bn_to_int(self._rsa_cdata.e),
|
||||
n=self._backend._bn_to_int(self._rsa_cdata.n),
|
||||
)
|
|
@ -1,14 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
|
@ -1,14 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
|
@ -1,54 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from cryptography.hazmat.bindings.utils import build_ffi
|
||||
|
||||
|
||||
class Binding(object):
|
||||
"""
|
||||
CommonCrypto API wrapper.
|
||||
"""
|
||||
_module_prefix = "cryptography.hazmat.bindings.commoncrypto."
|
||||
_modules = [
|
||||
"cf",
|
||||
"common_digest",
|
||||
"common_hmac",
|
||||
"common_key_derivation",
|
||||
"common_cryptor",
|
||||
"secimport",
|
||||
"secitem",
|
||||
"seckey",
|
||||
"seckeychain",
|
||||
"sectransform",
|
||||
]
|
||||
|
||||
ffi = None
|
||||
lib = None
|
||||
|
||||
def __init__(self):
|
||||
self._ensure_ffi_initialized()
|
||||
|
||||
@classmethod
|
||||
def _ensure_ffi_initialized(cls):
|
||||
if cls.ffi is not None and cls.lib is not None:
|
||||
return
|
||||
|
||||
cls.ffi, cls.lib = build_ffi(
|
||||
module_prefix=cls._module_prefix,
|
||||
modules=cls._modules,
|
||||
extra_link_args=[
|
||||
"-framework", "Security", "-framework", "CoreFoundation"
|
||||
]
|
||||
)
|
|
@ -1,114 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef bool Boolean;
|
||||
typedef signed long OSStatus;
|
||||
typedef unsigned char UInt8;
|
||||
typedef uint32_t UInt32;
|
||||
|
||||
typedef const void * CFAllocatorRef;
|
||||
const CFAllocatorRef kCFAllocatorDefault;
|
||||
typedef const void * CFDataRef;
|
||||
typedef signed long long CFIndex;
|
||||
typedef ... *CFStringRef;
|
||||
typedef ... *CFArrayRef;
|
||||
typedef ... *CFBooleanRef;
|
||||
typedef ... *CFErrorRef;
|
||||
typedef ... *CFNumberRef;
|
||||
typedef ... *CFTypeRef;
|
||||
typedef ... *CFDictionaryRef;
|
||||
typedef ... *CFMutableDictionaryRef;
|
||||
typedef struct {
|
||||
...;
|
||||
} CFDictionaryKeyCallBacks;
|
||||
typedef struct {
|
||||
...;
|
||||
} CFDictionaryValueCallBacks;
|
||||
typedef struct {
|
||||
...;
|
||||
} CFRange;
|
||||
|
||||
typedef UInt32 CFStringEncoding;
|
||||
enum {
|
||||
kCFStringEncodingASCII = 0x0600
|
||||
};
|
||||
|
||||
enum {
|
||||
kCFNumberSInt8Type = 1,
|
||||
kCFNumberSInt16Type = 2,
|
||||
kCFNumberSInt32Type = 3,
|
||||
kCFNumberSInt64Type = 4,
|
||||
kCFNumberFloat32Type = 5,
|
||||
kCFNumberFloat64Type = 6,
|
||||
kCFNumberCharType = 7,
|
||||
kCFNumberShortType = 8,
|
||||
kCFNumberIntType = 9,
|
||||
kCFNumberLongType = 10,
|
||||
kCFNumberLongLongType = 11,
|
||||
kCFNumberFloatType = 12,
|
||||
kCFNumberDoubleType = 13,
|
||||
kCFNumberCFIndexType = 14,
|
||||
kCFNumberNSIntegerType = 15,
|
||||
kCFNumberCGFloatType = 16,
|
||||
kCFNumberMaxType = 16
|
||||
};
|
||||
typedef int CFNumberType;
|
||||
|
||||
const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
|
||||
const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
|
||||
|
||||
const CFBooleanRef kCFBooleanTrue;
|
||||
const CFBooleanRef kCFBooleanFalse;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
CFDataRef CFDataCreate(CFAllocatorRef, const UInt8 *, CFIndex);
|
||||
CFStringRef CFStringCreateWithCString(CFAllocatorRef, const char *,
|
||||
CFStringEncoding);
|
||||
CFDictionaryRef CFDictionaryCreate(CFAllocatorRef, const void **,
|
||||
const void **, CFIndex,
|
||||
const CFDictionaryKeyCallBacks *,
|
||||
const CFDictionaryValueCallBacks *);
|
||||
CFMutableDictionaryRef CFDictionaryCreateMutable(
|
||||
CFAllocatorRef,
|
||||
CFIndex,
|
||||
const CFDictionaryKeyCallBacks *,
|
||||
const CFDictionaryValueCallBacks *
|
||||
);
|
||||
void CFDictionarySetValue(CFMutableDictionaryRef, const void *, const void *);
|
||||
CFIndex CFArrayGetCount(CFArrayRef);
|
||||
const void *CFArrayGetValueAtIndex(CFArrayRef, CFIndex);
|
||||
CFIndex CFDataGetLength(CFDataRef);
|
||||
void CFDataGetBytes(CFDataRef, CFRange, UInt8 *);
|
||||
CFRange CFRangeMake(CFIndex, CFIndex);
|
||||
void CFShow(CFTypeRef);
|
||||
Boolean CFBooleanGetValue(CFBooleanRef);
|
||||
CFNumberRef CFNumberCreate(CFAllocatorRef, CFNumberType, const void *);
|
||||
void CFRelease(CFTypeRef);
|
||||
CFTypeRef CFRetain(CFTypeRef);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,110 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <CommonCrypto/CommonCryptor.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
enum {
|
||||
kCCAlgorithmAES128 = 0,
|
||||
kCCAlgorithmDES,
|
||||
kCCAlgorithm3DES,
|
||||
kCCAlgorithmCAST,
|
||||
kCCAlgorithmRC4,
|
||||
kCCAlgorithmRC2,
|
||||
kCCAlgorithmBlowfish
|
||||
};
|
||||
typedef uint32_t CCAlgorithm;
|
||||
enum {
|
||||
kCCSuccess = 0,
|
||||
kCCParamError = -4300,
|
||||
kCCBufferTooSmall = -4301,
|
||||
kCCMemoryFailure = -4302,
|
||||
kCCAlignmentError = -4303,
|
||||
kCCDecodeError = -4304,
|
||||
kCCUnimplemented = -4305
|
||||
};
|
||||
typedef int32_t CCCryptorStatus;
|
||||
typedef uint32_t CCOptions;
|
||||
enum {
|
||||
kCCEncrypt = 0,
|
||||
kCCDecrypt,
|
||||
};
|
||||
typedef uint32_t CCOperation;
|
||||
typedef ... *CCCryptorRef;
|
||||
|
||||
enum {
|
||||
kCCModeOptionCTR_LE = 0x0001,
|
||||
kCCModeOptionCTR_BE = 0x0002
|
||||
};
|
||||
|
||||
typedef uint32_t CCModeOptions;
|
||||
|
||||
enum {
|
||||
kCCModeECB = 1,
|
||||
kCCModeCBC = 2,
|
||||
kCCModeCFB = 3,
|
||||
kCCModeCTR = 4,
|
||||
kCCModeF8 = 5,
|
||||
kCCModeLRW = 6,
|
||||
kCCModeOFB = 7,
|
||||
kCCModeXTS = 8,
|
||||
kCCModeRC4 = 9,
|
||||
kCCModeCFB8 = 10,
|
||||
kCCModeGCM = 11
|
||||
};
|
||||
typedef uint32_t CCMode;
|
||||
enum {
|
||||
ccNoPadding = 0,
|
||||
ccPKCS7Padding = 1,
|
||||
};
|
||||
typedef uint32_t CCPadding;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
CCCryptorStatus CCCryptorCreateWithMode(CCOperation, CCMode, CCAlgorithm,
|
||||
CCPadding, const void *, const void *,
|
||||
size_t, const void *, size_t, int,
|
||||
CCModeOptions, CCCryptorRef *);
|
||||
CCCryptorStatus CCCryptorCreate(CCOperation, CCAlgorithm, CCOptions,
|
||||
const void *, size_t, const void *,
|
||||
CCCryptorRef *);
|
||||
CCCryptorStatus CCCryptorUpdate(CCCryptorRef, const void *, size_t, void *,
|
||||
size_t, size_t *);
|
||||
CCCryptorStatus CCCryptorFinal(CCCryptorRef, void *, size_t, size_t *);
|
||||
CCCryptorStatus CCCryptorRelease(CCCryptorRef);
|
||||
|
||||
CCCryptorStatus CCCryptorGCMAddIV(CCCryptorRef, const void *, size_t);
|
||||
CCCryptorStatus CCCryptorGCMAddAAD(CCCryptorRef, const void *, size_t);
|
||||
CCCryptorStatus CCCryptorGCMEncrypt(CCCryptorRef, const void *, size_t,
|
||||
void *);
|
||||
CCCryptorStatus CCCryptorGCMDecrypt(CCCryptorRef, const void *, size_t,
|
||||
void *);
|
||||
CCCryptorStatus CCCryptorGCMFinal(CCCryptorRef, const void *, size_t *);
|
||||
CCCryptorStatus CCCryptorGCMReset(CCCryptorRef);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
/* Not defined in the public header */
|
||||
enum {
|
||||
kCCModeGCM = 11
|
||||
};
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,69 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef uint32_t CC_LONG;
|
||||
typedef uint64_t CC_LONG64;
|
||||
typedef struct CC_MD5state_st {
|
||||
...;
|
||||
} CC_MD5_CTX;
|
||||
typedef struct CC_SHA1state_st {
|
||||
...;
|
||||
} CC_SHA1_CTX;
|
||||
typedef struct CC_SHA256state_st {
|
||||
...;
|
||||
} CC_SHA256_CTX;
|
||||
typedef struct CC_SHA512state_st {
|
||||
...;
|
||||
} CC_SHA512_CTX;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
int CC_MD5_Init(CC_MD5_CTX *);
|
||||
int CC_MD5_Update(CC_MD5_CTX *, const void *, CC_LONG);
|
||||
int CC_MD5_Final(unsigned char *, CC_MD5_CTX *);
|
||||
|
||||
int CC_SHA1_Init(CC_SHA1_CTX *);
|
||||
int CC_SHA1_Update(CC_SHA1_CTX *, const void *, CC_LONG);
|
||||
int CC_SHA1_Final(unsigned char *, CC_SHA1_CTX *);
|
||||
|
||||
int CC_SHA224_Init(CC_SHA256_CTX *);
|
||||
int CC_SHA224_Update(CC_SHA256_CTX *, const void *, CC_LONG);
|
||||
int CC_SHA224_Final(unsigned char *, CC_SHA256_CTX *);
|
||||
|
||||
int CC_SHA256_Init(CC_SHA256_CTX *);
|
||||
int CC_SHA256_Update(CC_SHA256_CTX *, const void *, CC_LONG);
|
||||
int CC_SHA256_Final(unsigned char *, CC_SHA256_CTX *);
|
||||
|
||||
int CC_SHA384_Init(CC_SHA512_CTX *);
|
||||
int CC_SHA384_Update(CC_SHA512_CTX *, const void *, CC_LONG);
|
||||
int CC_SHA384_Final(unsigned char *, CC_SHA512_CTX *);
|
||||
|
||||
int CC_SHA512_Init(CC_SHA512_CTX *);
|
||||
int CC_SHA512_Update(CC_SHA512_CTX *, const void *, CC_LONG);
|
||||
int CC_SHA512_Final(unsigned char *, CC_SHA512_CTX *);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,48 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <CommonCrypto/CommonHMAC.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef struct {
|
||||
...;
|
||||
} CCHmacContext;
|
||||
enum {
|
||||
kCCHmacAlgSHA1,
|
||||
kCCHmacAlgMD5,
|
||||
kCCHmacAlgSHA256,
|
||||
kCCHmacAlgSHA384,
|
||||
kCCHmacAlgSHA512,
|
||||
kCCHmacAlgSHA224
|
||||
};
|
||||
typedef uint32_t CCHmacAlgorithm;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
void CCHmacInit(CCHmacContext *, CCHmacAlgorithm, const void *, size_t);
|
||||
void CCHmacUpdate(CCHmacContext *, const void *, size_t);
|
||||
void CCHmacFinal(CCHmacContext *, void *);
|
||||
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,50 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <CommonCrypto/CommonKeyDerivation.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
enum {
|
||||
kCCPBKDF2 = 2,
|
||||
};
|
||||
typedef uint32_t CCPBKDFAlgorithm;
|
||||
enum {
|
||||
kCCPRFHmacAlgSHA1 = 1,
|
||||
kCCPRFHmacAlgSHA224 = 2,
|
||||
kCCPRFHmacAlgSHA256 = 3,
|
||||
kCCPRFHmacAlgSHA384 = 4,
|
||||
kCCPRFHmacAlgSHA512 = 5,
|
||||
};
|
||||
typedef uint32_t CCPseudoRandomAlgorithm;
|
||||
typedef unsigned int uint;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
int CCKeyDerivationPBKDF(CCPBKDFAlgorithm, const char *, size_t,
|
||||
const uint8_t *, size_t, CCPseudoRandomAlgorithm,
|
||||
uint, uint8_t *, size_t);
|
||||
uint CCCalibratePBKDF(CCPBKDFAlgorithm, size_t, size_t,
|
||||
CCPseudoRandomAlgorithm, size_t, uint32_t);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,95 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <Security/SecImportExport.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef ... *SecAccessRef;
|
||||
|
||||
CFStringRef kSecImportExportPassphrase;
|
||||
CFStringRef kSecImportExportKeychain;
|
||||
CFStringRef kSecImportExportAccess;
|
||||
|
||||
typedef uint32_t SecExternalItemType;
|
||||
enum {
|
||||
kSecItemTypeUnknown,
|
||||
kSecItemTypePrivateKey,
|
||||
kSecItemTypePublicKey,
|
||||
kSecItemTypeSessionKey,
|
||||
kSecItemTypeCertificate,
|
||||
kSecItemTypeAggregate
|
||||
};
|
||||
|
||||
|
||||
typedef uint32_t SecExternalFormat;
|
||||
enum {
|
||||
kSecFormatUnknown = 0,
|
||||
kSecFormatOpenSSL,
|
||||
kSecFormatSSH,
|
||||
kSecFormatBSAFE,
|
||||
kSecFormatRawKey,
|
||||
kSecFormatWrappedPKCS8,
|
||||
kSecFormatWrappedOpenSSL,
|
||||
kSecFormatWrappedSSH,
|
||||
kSecFormatWrappedLSH,
|
||||
kSecFormatX509Cert,
|
||||
kSecFormatPEMSequence,
|
||||
kSecFormatPKCS7,
|
||||
kSecFormatPKCS12,
|
||||
kSecFormatNetscapeCertSequence,
|
||||
kSecFormatSSHv2
|
||||
};
|
||||
|
||||
typedef uint32_t SecItemImportExportFlags;
|
||||
enum {
|
||||
kSecKeyImportOnlyOne = 0x00000001,
|
||||
kSecKeySecurePassphrase = 0x00000002,
|
||||
kSecKeyNoAccessControl = 0x00000004
|
||||
};
|
||||
typedef uint32_t SecKeyImportExportFlags;
|
||||
|
||||
typedef struct {
|
||||
/* for import and export */
|
||||
uint32_t version;
|
||||
SecKeyImportExportFlags flags;
|
||||
CFTypeRef passphrase;
|
||||
CFStringRef alertTitle;
|
||||
CFStringRef alertPrompt;
|
||||
|
||||
/* for import only */
|
||||
SecAccessRef accessRef;
|
||||
CFArrayRef keyUsage;
|
||||
|
||||
CFArrayRef keyAttributes;
|
||||
} SecItemImportExportKeyParameters;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
OSStatus SecItemImport(CFDataRef, CFStringRef, SecExternalFormat *,
|
||||
SecExternalItemType *, SecItemImportExportFlags,
|
||||
const SecItemImportExportKeyParameters *,
|
||||
SecKeychainRef, CFArrayRef *);
|
||||
OSStatus SecPKCS12Import(CFDataRef, CFDictionaryRef, CFArrayRef *);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,38 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <Security/SecItem.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
const CFTypeRef kSecAttrKeyType;
|
||||
const CFTypeRef kSecAttrKeySizeInBits;
|
||||
const CFTypeRef kSecAttrIsPermanent;
|
||||
const CFTypeRef kSecAttrKeyTypeRSA;
|
||||
const CFTypeRef kSecAttrKeyTypeDSA;
|
||||
const CFTypeRef kSecUseKeychain;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,35 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <Security/SecKey.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef ... *SecKeyRef;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
OSStatus SecKeyGeneratePair(CFDictionaryRef, SecKeyRef *, SecKeyRef *);
|
||||
size_t SecKeyGetBlockSize(SecKeyRef);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,36 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <Security/SecKeychain.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef ... *SecKeychainRef;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
OSStatus SecKeychainCreate(const char *, UInt32, const void *, Boolean,
|
||||
SecAccessRef, SecKeychainRef *);
|
||||
OSStatus SecKeychainDelete(SecKeychainRef);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,79 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <Security/SecDigestTransform.h>
|
||||
#include <Security/SecSignVerifyTransform.h>
|
||||
#include <Security/SecEncryptTransform.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef ... *SecTransformRef;
|
||||
|
||||
CFStringRef kSecImportExportPassphrase;
|
||||
CFStringRef kSecImportExportKeychain;
|
||||
CFStringRef kSecImportExportAccess;
|
||||
|
||||
CFStringRef kSecEncryptionMode;
|
||||
CFStringRef kSecEncryptKey;
|
||||
CFStringRef kSecIVKey;
|
||||
CFStringRef kSecModeCBCKey;
|
||||
CFStringRef kSecModeCFBKey;
|
||||
CFStringRef kSecModeECBKey;
|
||||
CFStringRef kSecModeNoneKey;
|
||||
CFStringRef kSecModeOFBKey;
|
||||
CFStringRef kSecOAEPEncodingParametersAttributeName;
|
||||
CFStringRef kSecPaddingKey;
|
||||
CFStringRef kSecPaddingNoneKey;
|
||||
CFStringRef kSecPaddingOAEPKey;
|
||||
CFStringRef kSecPaddingPKCS1Key;
|
||||
CFStringRef kSecPaddingPKCS5Key;
|
||||
CFStringRef kSecPaddingPKCS7Key;
|
||||
|
||||
const CFStringRef kSecTransformInputAttributeName;
|
||||
const CFStringRef kSecTransformOutputAttributeName;
|
||||
const CFStringRef kSecTransformDebugAttributeName;
|
||||
const CFStringRef kSecTransformTransformName;
|
||||
const CFStringRef kSecTransformAbortAttributeName;
|
||||
|
||||
CFStringRef kSecInputIsAttributeName;
|
||||
CFStringRef kSecInputIsPlainText;
|
||||
CFStringRef kSecInputIsDigest;
|
||||
CFStringRef kSecInputIsRaw;
|
||||
|
||||
const CFStringRef kSecDigestTypeAttribute;
|
||||
const CFStringRef kSecDigestLengthAttribute;
|
||||
const CFStringRef kSecDigestMD5;
|
||||
const CFStringRef kSecDigestSHA1;
|
||||
const CFStringRef kSecDigestSHA2;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
Boolean SecTransformSetAttribute(SecTransformRef, CFStringRef, CFTypeRef,
|
||||
CFErrorRef *);
|
||||
SecTransformRef SecDecryptTransformCreate(SecKeyRef, CFErrorRef *);
|
||||
SecTransformRef SecEncryptTransformCreate(SecKeyRef, CFErrorRef *);
|
||||
SecTransformRef SecVerifyTransformCreate(SecKeyRef, CFDataRef, CFErrorRef *);
|
||||
SecTransformRef SecSignTransformCreate(SecKeyRef, CFErrorRef *) ;
|
||||
CFTypeRef SecTransformExecute(SecTransformRef, CFErrorRef *);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,14 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
|
@ -1,70 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/aes.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
static const int Cryptography_HAS_AES_WRAP;
|
||||
|
||||
struct aes_key_st {
|
||||
...;
|
||||
};
|
||||
typedef struct aes_key_st AES_KEY;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
int AES_set_encrypt_key(const unsigned char *, const int, AES_KEY *);
|
||||
int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
/* these can be moved back to FUNCTIONS once we drop support for 0.9.8h.
|
||||
This should be when we drop RHEL/CentOS 5, which is on 0.9.8e. */
|
||||
int AES_wrap_key(AES_KEY *, const unsigned char *, unsigned char *,
|
||||
const unsigned char *, unsigned int);
|
||||
int AES_unwrap_key(AES_KEY *, const unsigned char *, unsigned char *,
|
||||
const unsigned char *, unsigned int);
|
||||
|
||||
/* The ctr128_encrypt function is only useful in 0.9.8. You should use EVP for
|
||||
this in 1.0.0+. It is defined in macros because the function signature
|
||||
changed after 0.9.8 */
|
||||
void AES_ctr128_encrypt(const unsigned char *, unsigned char *,
|
||||
const size_t, const AES_KEY *,
|
||||
unsigned char[], unsigned char[], unsigned int *);
|
||||
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
/* OpenSSL 0.9.8h+ */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090808fL
|
||||
static const long Cryptography_HAS_AES_WRAP = 1;
|
||||
#else
|
||||
static const long Cryptography_HAS_AES_WRAP = 0;
|
||||
int (*AES_wrap_key)(AES_KEY *, const unsigned char *, unsigned char *,
|
||||
const unsigned char *, unsigned int) = NULL;
|
||||
int (*AES_unwrap_key)(AES_KEY *, const unsigned char *, unsigned char *,
|
||||
const unsigned char *, unsigned int) = NULL;
|
||||
#endif
|
||||
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {
|
||||
"Cryptography_HAS_AES_WRAP": [
|
||||
"AES_wrap_key",
|
||||
"AES_unwrap_key",
|
||||
],
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/asn1.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
/*
|
||||
* TODO: This typedef is wrong.
|
||||
*
|
||||
* This is due to limitations of cffi.
|
||||
* See https://bitbucket.org/cffi/cffi/issue/69
|
||||
*
|
||||
* For another possible work-around (not used here because it involves more
|
||||
* complicated use of the cffi API which falls outside the general pattern used
|
||||
* by this package), see
|
||||
* http://paste.pound-python.org/show/iJcTUMkKeBeS6yXpZWUU/
|
||||
*
|
||||
* The work-around used here is to just be sure to declare a type that is at
|
||||
* least as large as the real type. Maciej explains:
|
||||
*
|
||||
* <fijal> I think you want to declare your value too large (e.g. long)
|
||||
* <fijal> that way you'll never pass garbage
|
||||
*/
|
||||
typedef intptr_t time_t;
|
||||
|
||||
typedef int ASN1_BOOLEAN;
|
||||
typedef ... ASN1_INTEGER;
|
||||
|
||||
struct asn1_string_st {
|
||||
int length;
|
||||
int type;
|
||||
unsigned char *data;
|
||||
long flags;
|
||||
};
|
||||
|
||||
typedef struct asn1_string_st ASN1_OCTET_STRING;
|
||||
typedef struct asn1_string_st ASN1_IA5STRING;
|
||||
typedef ... ASN1_OBJECT;
|
||||
typedef ... ASN1_STRING;
|
||||
typedef ... ASN1_TYPE;
|
||||
typedef ... ASN1_GENERALIZEDTIME;
|
||||
typedef ... ASN1_ENUMERATED;
|
||||
typedef ... ASN1_ITEM;
|
||||
typedef ... ASN1_VALUE;
|
||||
|
||||
typedef struct {
|
||||
...;
|
||||
} ASN1_TIME;
|
||||
typedef ... ASN1_ITEM_EXP;
|
||||
|
||||
typedef ... ASN1_UTCTIME;
|
||||
|
||||
static const int V_ASN1_GENERALIZEDTIME;
|
||||
|
||||
static const int MBSTRING_UTF8;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
ASN1_OBJECT *ASN1_OBJECT_new(void);
|
||||
void ASN1_OBJECT_free(ASN1_OBJECT *);
|
||||
|
||||
/* ASN1 OBJECT IDENTIFIER */
|
||||
ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **, const unsigned char **, long);
|
||||
int i2d_ASN1_OBJECT(ASN1_OBJECT *, unsigned char **);
|
||||
|
||||
/* ASN1 STRING */
|
||||
ASN1_STRING *ASN1_STRING_new(void);
|
||||
ASN1_STRING *ASN1_STRING_type_new(int);
|
||||
void ASN1_STRING_free(ASN1_STRING *);
|
||||
unsigned char *ASN1_STRING_data(ASN1_STRING *);
|
||||
int ASN1_STRING_set(ASN1_STRING *, const void *, int);
|
||||
int ASN1_STRING_type(ASN1_STRING *);
|
||||
int ASN1_STRING_to_UTF8(unsigned char **, ASN1_STRING *);
|
||||
|
||||
/* ASN1 OCTET STRING */
|
||||
ASN1_OCTET_STRING *ASN1_OCTET_STRING_new(void);
|
||||
void ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *);
|
||||
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *, const unsigned char *, int);
|
||||
|
||||
/* ASN1 INTEGER */
|
||||
ASN1_INTEGER *ASN1_INTEGER_new(void);
|
||||
void ASN1_INTEGER_free(ASN1_INTEGER *);
|
||||
int ASN1_INTEGER_set(ASN1_INTEGER *, long);
|
||||
int i2a_ASN1_INTEGER(BIO *, ASN1_INTEGER *);
|
||||
|
||||
/* ASN1 TIME */
|
||||
ASN1_TIME *ASN1_TIME_new(void);
|
||||
void ASN1_TIME_free(ASN1_TIME *);
|
||||
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *,
|
||||
ASN1_GENERALIZEDTIME **);
|
||||
|
||||
/* ASN1 UTCTIME */
|
||||
int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *, time_t);
|
||||
|
||||
/* ASN1 GENERALIZEDTIME */
|
||||
int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *, const char *);
|
||||
void ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *);
|
||||
|
||||
/* ASN1 ENUMERATED */
|
||||
ASN1_ENUMERATED *ASN1_ENUMERATED_new(void);
|
||||
void ASN1_ENUMERATED_free(ASN1_ENUMERATED *);
|
||||
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *, long);
|
||||
|
||||
ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **, const unsigned char **, long,
|
||||
const ASN1_ITEM *);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
ASN1_TIME *M_ASN1_TIME_dup(void *);
|
||||
const ASN1_ITEM *ASN1_ITEM_ptr(ASN1_ITEM_EXP *);
|
||||
|
||||
/* These aren't macros these arguments are all const X on openssl > 1.0.x */
|
||||
|
||||
int ASN1_STRING_length(ASN1_STRING *);
|
||||
ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *);
|
||||
int ASN1_STRING_cmp(ASN1_STRING *, ASN1_STRING *);
|
||||
|
||||
ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *);
|
||||
int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *, ASN1_OCTET_STRING *);
|
||||
|
||||
ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *);
|
||||
int ASN1_INTEGER_cmp(ASN1_INTEGER *, ASN1_INTEGER *);
|
||||
long ASN1_INTEGER_get(ASN1_INTEGER *);
|
||||
|
||||
BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *, BIGNUM *);
|
||||
ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *, ASN1_INTEGER *);
|
||||
|
||||
/* These isn't a macro the arg is const on openssl 1.0.2+ */
|
||||
int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *);
|
||||
|
||||
/* Not a macro, const on openssl 1.0 */
|
||||
int ASN1_STRING_set_default_mask_asc(char *);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,114 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/bn.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef ... BN_CTX;
|
||||
typedef ... BIGNUM;
|
||||
/*
|
||||
* TODO: This typedef is wrong.
|
||||
*
|
||||
* This is due to limitations of cffi.
|
||||
* See https://bitbucket.org/cffi/cffi/issue/69
|
||||
*
|
||||
* For another possible work-around (not used here because it involves more
|
||||
* complicated use of the cffi API which falls outside the general pattern used
|
||||
* by this package), see
|
||||
* http://paste.pound-python.org/show/iJcTUMkKeBeS6yXpZWUU/
|
||||
*
|
||||
* The work-around used here is to just be sure to declare a type that is at
|
||||
* least as large as the real type. Maciej explains:
|
||||
*
|
||||
* <fijal> I think you want to declare your value too large (e.g. long)
|
||||
* <fijal> that way you'll never pass garbage
|
||||
*/
|
||||
typedef uintptr_t BN_ULONG;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
BIGNUM *BN_new(void);
|
||||
void BN_free(BIGNUM *);
|
||||
|
||||
BN_CTX *BN_CTX_new(void);
|
||||
void BN_CTX_free(BN_CTX *);
|
||||
|
||||
void BN_CTX_start(BN_CTX *);
|
||||
BIGNUM *BN_CTX_get(BN_CTX *);
|
||||
void BN_CTX_end(BN_CTX *);
|
||||
|
||||
BIGNUM *BN_copy(BIGNUM *, const BIGNUM *);
|
||||
BIGNUM *BN_dup(const BIGNUM *);
|
||||
|
||||
int BN_set_word(BIGNUM *, BN_ULONG);
|
||||
BN_ULONG BN_get_word(const BIGNUM *);
|
||||
|
||||
const BIGNUM *BN_value_one(void);
|
||||
|
||||
char *BN_bn2hex(const BIGNUM *);
|
||||
int BN_hex2bn(BIGNUM **, const char *);
|
||||
int BN_dec2bn(BIGNUM **, const char *);
|
||||
|
||||
int BN_bn2bin(const BIGNUM *, unsigned char *);
|
||||
BIGNUM *BN_bin2bn(const unsigned char *, int, BIGNUM *);
|
||||
|
||||
int BN_num_bits(const BIGNUM *);
|
||||
|
||||
int BN_cmp(const BIGNUM *, const BIGNUM *);
|
||||
int BN_add(BIGNUM *, const BIGNUM *, const BIGNUM *);
|
||||
int BN_sub(BIGNUM *, const BIGNUM *, const BIGNUM *);
|
||||
int BN_mul(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
int BN_sqr(BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
int BN_div(BIGNUM *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
int BN_nnmod(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
int BN_mod_add(BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
|
||||
BN_CTX *);
|
||||
int BN_mod_sub(BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
|
||||
BN_CTX *);
|
||||
int BN_mod_mul(BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
|
||||
BN_CTX *);
|
||||
int BN_mod_sqr(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
int BN_exp(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
int BN_mod_exp(BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
|
||||
BN_CTX *);
|
||||
int BN_gcd(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
BIGNUM *BN_mod_inverse(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
|
||||
int BN_set_bit(BIGNUM *, int);
|
||||
int BN_clear_bit(BIGNUM *, int);
|
||||
|
||||
int BN_is_bit_set(const BIGNUM *, int);
|
||||
|
||||
int BN_mask_bits(BIGNUM *, int);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
int BN_zero(BIGNUM *);
|
||||
int BN_one(BIGNUM *);
|
||||
int BN_mod(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
|
||||
int BN_lshift(BIGNUM *, const BIGNUM *, int);
|
||||
int BN_lshift1(BIGNUM *, BIGNUM *);
|
||||
|
||||
int BN_rshift(BIGNUM *, BIGNUM *, int);
|
||||
int BN_rshift1(BIGNUM *, BIGNUM *);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,168 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
|
||||
from cryptography.hazmat.bindings.utils import build_ffi
|
||||
|
||||
|
||||
_OSX_PRE_INCLUDE = """
|
||||
#ifdef __APPLE__
|
||||
#include <AvailabilityMacros.h>
|
||||
#define __ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
|
||||
DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
#endif
|
||||
"""
|
||||
|
||||
_OSX_POST_INCLUDE = """
|
||||
#ifdef __APPLE__
|
||||
#undef DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER \
|
||||
__ORIG_DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
#endif
|
||||
"""
|
||||
|
||||
|
||||
class Binding(object):
|
||||
"""
|
||||
OpenSSL API wrapper.
|
||||
"""
|
||||
_module_prefix = "cryptography.hazmat.bindings.openssl."
|
||||
_modules = [
|
||||
"aes",
|
||||
"asn1",
|
||||
"bignum",
|
||||
"bio",
|
||||
"cmac",
|
||||
"cms",
|
||||
"conf",
|
||||
"crypto",
|
||||
"dh",
|
||||
"dsa",
|
||||
"ec",
|
||||
"ecdh",
|
||||
"ecdsa",
|
||||
"engine",
|
||||
"err",
|
||||
"evp",
|
||||
"hmac",
|
||||
"nid",
|
||||
"objects",
|
||||
"opensslv",
|
||||
"osrandom_engine",
|
||||
"pem",
|
||||
"pkcs7",
|
||||
"pkcs12",
|
||||
"rand",
|
||||
"rsa",
|
||||
"ssl",
|
||||
"x509",
|
||||
"x509name",
|
||||
"x509v3",
|
||||
"x509_vfy"
|
||||
]
|
||||
|
||||
_locks = None
|
||||
_lock_cb_handle = None
|
||||
_lock_init_lock = threading.Lock()
|
||||
|
||||
ffi = None
|
||||
lib = None
|
||||
|
||||
def __init__(self):
|
||||
self._ensure_ffi_initialized()
|
||||
|
||||
@classmethod
|
||||
def _ensure_ffi_initialized(cls):
|
||||
if cls.ffi is not None and cls.lib is not None:
|
||||
return
|
||||
|
||||
# OpenSSL goes by a different library name on different operating
|
||||
# systems.
|
||||
if sys.platform != "win32":
|
||||
# In some circumstances, the order in which these libs are
|
||||
# specified on the linker command-line is significant;
|
||||
# libssl must come before libcrypto
|
||||
# (http://marc.info/?l=openssl-users&m=135361825921871)
|
||||
libraries = ["ssl", "crypto"]
|
||||
else: # pragma: no cover
|
||||
link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static")
|
||||
libraries = _get_windows_libraries(link_type)
|
||||
|
||||
cls.ffi, cls.lib = build_ffi(
|
||||
module_prefix=cls._module_prefix,
|
||||
modules=cls._modules,
|
||||
pre_include=_OSX_PRE_INCLUDE,
|
||||
post_include=_OSX_POST_INCLUDE,
|
||||
libraries=libraries,
|
||||
)
|
||||
res = cls.lib.Cryptography_add_osrandom_engine()
|
||||
assert res != 0
|
||||
|
||||
@classmethod
|
||||
def init_static_locks(cls):
|
||||
with cls._lock_init_lock:
|
||||
cls._ensure_ffi_initialized()
|
||||
|
||||
if not cls._lock_cb_handle:
|
||||
cls._lock_cb_handle = cls.ffi.callback(
|
||||
"void(int, int, const char *, int)",
|
||||
cls._lock_cb
|
||||
)
|
||||
|
||||
# Use Python's implementation if available, importing _ssl triggers
|
||||
# the setup for this.
|
||||
__import__("_ssl")
|
||||
|
||||
if cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL:
|
||||
return
|
||||
|
||||
# If nothing else has setup a locking callback already, we set up
|
||||
# our own
|
||||
num_locks = cls.lib.CRYPTO_num_locks()
|
||||
cls._locks = [threading.Lock() for n in range(num_locks)]
|
||||
|
||||
cls.lib.CRYPTO_set_locking_callback(cls._lock_cb_handle)
|
||||
|
||||
@classmethod
|
||||
def _lock_cb(cls, mode, n, file, line):
|
||||
lock = cls._locks[n]
|
||||
|
||||
if mode & cls.lib.CRYPTO_LOCK:
|
||||
lock.acquire()
|
||||
elif mode & cls.lib.CRYPTO_UNLOCK:
|
||||
lock.release()
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"Unknown lock mode {0}: lock={1}, file={2}, line={3}.".format(
|
||||
mode, n, file, line
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _get_windows_libraries(link_type):
|
||||
if link_type == "dynamic":
|
||||
return ["libeay32", "ssleay32", "advapi32"]
|
||||
elif link_type == "static" or link_type == "":
|
||||
return ["libeay32mt", "ssleay32mt", "advapi32",
|
||||
"crypt32", "gdi32", "user32", "ws2_32"]
|
||||
else:
|
||||
raise ValueError(
|
||||
"PYCA_WINDOWS_LINK_TYPE must be 'static' or 'dynamic'"
|
||||
)
|
|
@ -1,181 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/bio.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef struct bio_st BIO;
|
||||
typedef void bio_info_cb(BIO *, int, const char *, int, long, long);
|
||||
struct bio_method_st {
|
||||
int type;
|
||||
const char *name;
|
||||
int (*bwrite)(BIO *, const char *, int);
|
||||
int (*bread)(BIO *, char *, int);
|
||||
int (*bputs)(BIO *, const char *);
|
||||
int (*bgets)(BIO *, char*, int);
|
||||
long (*ctrl)(BIO *, int, long, void *);
|
||||
int (*create)(BIO *);
|
||||
int (*destroy)(BIO *);
|
||||
long (*callback_ctrl)(BIO *, int, bio_info_cb *);
|
||||
...;
|
||||
};
|
||||
typedef struct bio_method_st BIO_METHOD;
|
||||
struct bio_st {
|
||||
BIO_METHOD *method;
|
||||
long (*callback)(struct bio_st*, int, const char*, int, long, long);
|
||||
char *cb_arg;
|
||||
int init;
|
||||
int shutdown;
|
||||
int flags;
|
||||
int retry_reason;
|
||||
int num;
|
||||
void *ptr;
|
||||
struct bio_st *next_bio;
|
||||
struct bio_st *prev_bio;
|
||||
int references;
|
||||
unsigned long num_read;
|
||||
unsigned long num_write;
|
||||
...;
|
||||
};
|
||||
typedef ... BUF_MEM;
|
||||
|
||||
static const int BIO_TYPE_MEM;
|
||||
static const int BIO_TYPE_FILE;
|
||||
static const int BIO_TYPE_FD;
|
||||
static const int BIO_TYPE_SOCKET;
|
||||
static const int BIO_TYPE_CONNECT;
|
||||
static const int BIO_TYPE_ACCEPT;
|
||||
static const int BIO_TYPE_NULL;
|
||||
static const int BIO_CLOSE;
|
||||
static const int BIO_NOCLOSE;
|
||||
static const int BIO_TYPE_SOURCE_SINK;
|
||||
static const int BIO_CTRL_RESET;
|
||||
static const int BIO_CTRL_EOF;
|
||||
static const int BIO_CTRL_SET;
|
||||
static const int BIO_CTRL_SET_CLOSE;
|
||||
static const int BIO_CTRL_FLUSH;
|
||||
static const int BIO_CTRL_DUP;
|
||||
static const int BIO_CTRL_GET_CLOSE;
|
||||
static const int BIO_CTRL_INFO;
|
||||
static const int BIO_CTRL_GET;
|
||||
static const int BIO_CTRL_PENDING;
|
||||
static const int BIO_CTRL_WPENDING;
|
||||
static const int BIO_C_FILE_SEEK;
|
||||
static const int BIO_C_FILE_TELL;
|
||||
static const int BIO_TYPE_NONE;
|
||||
static const int BIO_TYPE_PROXY_CLIENT;
|
||||
static const int BIO_TYPE_PROXY_SERVER;
|
||||
static const int BIO_TYPE_NBIO_TEST;
|
||||
static const int BIO_TYPE_BER;
|
||||
static const int BIO_TYPE_BIO;
|
||||
static const int BIO_TYPE_DESCRIPTOR;
|
||||
static const int BIO_FLAGS_READ;
|
||||
static const int BIO_FLAGS_WRITE;
|
||||
static const int BIO_FLAGS_IO_SPECIAL;
|
||||
static const int BIO_FLAGS_RWS;
|
||||
static const int BIO_FLAGS_SHOULD_RETRY;
|
||||
static const int BIO_TYPE_NULL_FILTER;
|
||||
static const int BIO_TYPE_SSL;
|
||||
static const int BIO_TYPE_MD;
|
||||
static const int BIO_TYPE_BUFFER;
|
||||
static const int BIO_TYPE_CIPHER;
|
||||
static const int BIO_TYPE_BASE64;
|
||||
static const int BIO_TYPE_FILTER;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
BIO* BIO_new(BIO_METHOD *);
|
||||
int BIO_set(BIO *, BIO_METHOD *);
|
||||
int BIO_free(BIO *);
|
||||
void BIO_vfree(BIO *);
|
||||
void BIO_free_all(BIO *);
|
||||
BIO *BIO_push(BIO *, BIO *);
|
||||
BIO *BIO_pop(BIO *);
|
||||
BIO *BIO_next(BIO *);
|
||||
BIO *BIO_find_type(BIO *, int);
|
||||
BIO_METHOD *BIO_s_mem(void);
|
||||
BIO *BIO_new_mem_buf(void *, int);
|
||||
BIO_METHOD *BIO_s_file(void);
|
||||
BIO *BIO_new_file(const char *, const char *);
|
||||
BIO *BIO_new_fp(FILE *, int);
|
||||
BIO_METHOD *BIO_s_fd(void);
|
||||
BIO *BIO_new_fd(int, int);
|
||||
BIO_METHOD *BIO_s_socket(void);
|
||||
BIO *BIO_new_socket(int, int);
|
||||
BIO_METHOD *BIO_s_null(void);
|
||||
long BIO_ctrl(BIO *, int, long, void *);
|
||||
long BIO_callback_ctrl(
|
||||
BIO *,
|
||||
int,
|
||||
void (*)(struct bio_st *, int, const char *, int, long, long)
|
||||
);
|
||||
char *BIO_ptr_ctrl(BIO *, int, long);
|
||||
long BIO_int_ctrl(BIO *, int, long, int);
|
||||
size_t BIO_ctrl_pending(BIO *);
|
||||
size_t BIO_ctrl_wpending(BIO *);
|
||||
int BIO_read(BIO *, void *, int);
|
||||
int BIO_gets(BIO *, char *, int);
|
||||
int BIO_write(BIO *, const void *, int);
|
||||
int BIO_puts(BIO *, const char *);
|
||||
BIO_METHOD *BIO_f_null(void);
|
||||
BIO_METHOD *BIO_f_buffer(void);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
long BIO_set_fd(BIO *, long, int);
|
||||
long BIO_get_fd(BIO *, char *);
|
||||
long BIO_set_mem_eof_return(BIO *, int);
|
||||
long BIO_get_mem_data(BIO *, char **);
|
||||
long BIO_set_mem_buf(BIO *, BUF_MEM *, int);
|
||||
long BIO_get_mem_ptr(BIO *, BUF_MEM **);
|
||||
long BIO_set_fp(BIO *, FILE *, int);
|
||||
long BIO_get_fp(BIO *, FILE **);
|
||||
long BIO_read_filename(BIO *, char *);
|
||||
long BIO_write_filename(BIO *, char *);
|
||||
long BIO_append_filename(BIO *, char *);
|
||||
long BIO_rw_filename(BIO *, char *);
|
||||
int BIO_should_read(BIO *);
|
||||
int BIO_should_write(BIO *);
|
||||
int BIO_should_io_special(BIO *);
|
||||
int BIO_retry_type(BIO *);
|
||||
int BIO_should_retry(BIO *);
|
||||
int BIO_reset(BIO *);
|
||||
int BIO_seek(BIO *, int);
|
||||
int BIO_tell(BIO *);
|
||||
int BIO_flush(BIO *);
|
||||
int BIO_eof(BIO *);
|
||||
int BIO_set_close(BIO *,long);
|
||||
int BIO_get_close(BIO *);
|
||||
int BIO_pending(BIO *);
|
||||
int BIO_wpending(BIO *);
|
||||
int BIO_get_info_callback(BIO *, bio_info_cb **);
|
||||
int BIO_set_info_callback(BIO *, bio_info_cb *);
|
||||
long BIO_get_buffer_num_lines(BIO *);
|
||||
long BIO_set_read_buffer_size(BIO *, long);
|
||||
long BIO_set_write_buffer_size(BIO *, long);
|
||||
long BIO_set_buffer_size(BIO *, long);
|
||||
long BIO_set_buffer_read_data(BIO *, void *, long);
|
||||
|
||||
/* The following was a macro in 0.9.8e. Once we drop support for RHEL/CentOS 5
|
||||
we should move this back to FUNCTIONS. */
|
||||
int BIO_method_type(const BIO *);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,65 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
|
||||
#include <openssl/cmac.h>
|
||||
#endif
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
static const int Cryptography_HAS_CMAC;
|
||||
typedef ... CMAC_CTX;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
CMAC_CTX *CMAC_CTX_new(void);
|
||||
int CMAC_Init(CMAC_CTX *, const void *, size_t, const EVP_CIPHER *, ENGINE *);
|
||||
int CMAC_Update(CMAC_CTX *, const void *, size_t);
|
||||
int CMAC_Final(CMAC_CTX *, unsigned char *, size_t *);
|
||||
int CMAC_CTX_copy(CMAC_CTX *, const CMAC_CTX *);
|
||||
void CMAC_CTX_free(CMAC_CTX *);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10001000L
|
||||
|
||||
static const long Cryptography_HAS_CMAC = 0;
|
||||
typedef void CMAC_CTX;
|
||||
CMAC_CTX *(*CMAC_CTX_new)(void) = NULL;
|
||||
int (*CMAC_Init)(CMAC_CTX *, const void *, size_t, const EVP_CIPHER *,
|
||||
ENGINE *) = NULL;
|
||||
int (*CMAC_Update)(CMAC_CTX *, const void *, size_t) = NULL;
|
||||
int (*CMAC_Final)(CMAC_CTX *, unsigned char *, size_t *) = NULL;
|
||||
int (*CMAC_CTX_copy)(CMAC_CTX *, const CMAC_CTX *) = NULL;
|
||||
void (*CMAC_CTX_free)(CMAC_CTX *) = NULL;
|
||||
#else
|
||||
static const long Cryptography_HAS_CMAC = 1;
|
||||
#endif
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {
|
||||
"Cryptography_HAS_CMAC": [
|
||||
"CMAC_CTX_new",
|
||||
"CMAC_Init",
|
||||
"CMAC_Update",
|
||||
"CMAC_Final",
|
||||
"CMAC_CTX_copy",
|
||||
"CMAC_CTX_free",
|
||||
],
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#if !defined(OPENSSL_NO_CMS) && OPENSSL_VERSION_NUMBER >= 0x0090808fL
|
||||
/* The next define should really be in the OpenSSL header, but it is missing.
|
||||
Failing to include this on Windows causes compilation failures. */
|
||||
#if defined(OPENSSL_SYS_WINDOWS)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <openssl/cms.h>
|
||||
#endif
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
static const long Cryptography_HAS_CMS;
|
||||
|
||||
typedef ... CMS_ContentInfo;
|
||||
typedef ... CMS_SignerInfo;
|
||||
typedef ... CMS_CertificateChoices;
|
||||
typedef ... CMS_RevocationInfoChoice;
|
||||
typedef ... CMS_RecipientInfo;
|
||||
typedef ... CMS_ReceiptRequest;
|
||||
typedef ... CMS_Receipt;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
BIO *BIO_new_CMS(BIO *, CMS_ContentInfo *);
|
||||
int i2d_CMS_bio_stream(BIO *, CMS_ContentInfo *, BIO *, int);
|
||||
int PEM_write_bio_CMS_stream(BIO *, CMS_ContentInfo *, BIO *, int);
|
||||
int CMS_final(CMS_ContentInfo *, BIO *, BIO *, unsigned int);
|
||||
CMS_ContentInfo *CMS_sign(X509 *, EVP_PKEY *, Cryptography_STACK_OF_X509 *,
|
||||
BIO *, unsigned int);
|
||||
int CMS_verify(CMS_ContentInfo *, Cryptography_STACK_OF_X509 *, X509_STORE *,
|
||||
BIO *, BIO *, unsigned int);
|
||||
CMS_ContentInfo *CMS_encrypt(Cryptography_STACK_OF_X509 *, BIO *,
|
||||
const EVP_CIPHER *, unsigned int);
|
||||
int CMS_decrypt(CMS_ContentInfo *, EVP_PKEY *, X509 *, BIO *, BIO *,
|
||||
unsigned int);
|
||||
CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *, X509 *, EVP_PKEY *,
|
||||
const EVP_MD *, unsigned int);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
#if !defined(OPENSSL_NO_CMS) && OPENSSL_VERSION_NUMBER >= 0x0090808fL
|
||||
static const long Cryptography_HAS_CMS = 1;
|
||||
#else
|
||||
static const long Cryptography_HAS_CMS = 0;
|
||||
typedef void CMS_ContentInfo;
|
||||
typedef void CMS_SignerInfo;
|
||||
typedef void CMS_CertificateChoices;
|
||||
typedef void CMS_RevocationInfoChoice;
|
||||
typedef void CMS_RecipientInfo;
|
||||
typedef void CMS_ReceiptRequest;
|
||||
typedef void CMS_Receipt;
|
||||
BIO *(*BIO_new_CMS)(BIO *, CMS_ContentInfo *) = NULL;
|
||||
int (*i2d_CMS_bio_stream)(BIO *, CMS_ContentInfo *, BIO *, int) = NULL;
|
||||
int (*PEM_write_bio_CMS_stream)(BIO *, CMS_ContentInfo *, BIO *, int) = NULL;
|
||||
int (*CMS_final)(CMS_ContentInfo *, BIO *, BIO *, unsigned int) = NULL;
|
||||
CMS_ContentInfo *(*CMS_sign)(X509 *, EVP_PKEY *, Cryptography_STACK_OF_X509 *,
|
||||
BIO *, unsigned int) = NULL;
|
||||
int (*CMS_verify)(CMS_ContentInfo *, Cryptography_STACK_OF_X509 *,
|
||||
X509_STORE *, BIO *, BIO *, unsigned int) = NULL;
|
||||
CMS_ContentInfo *(*CMS_encrypt)(Cryptography_STACK_OF_X509 *, BIO *,
|
||||
const EVP_CIPHER *, unsigned int) = NULL;
|
||||
int (*CMS_decrypt)(CMS_ContentInfo *, EVP_PKEY *, X509 *, BIO *, BIO *,
|
||||
unsigned int) = NULL;
|
||||
CMS_SignerInfo *(*CMS_add1_signer)(CMS_ContentInfo *, X509 *, EVP_PKEY *,
|
||||
const EVP_MD *, unsigned int) = NULL;
|
||||
#endif
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {
|
||||
"Cryptography_HAS_CMS": [
|
||||
"BIO_new_CMS",
|
||||
"i2d_CMS_bio_stream",
|
||||
"PEM_write_bio_CMS_stream",
|
||||
"CMS_final",
|
||||
"CMS_sign",
|
||||
"CMS_verify",
|
||||
"CMS_encrypt",
|
||||
"CMS_decrypt",
|
||||
"CMS_add1_signer",
|
||||
]
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/conf.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef ... CONF;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
void OPENSSL_config(const char *);
|
||||
void OPENSSL_no_config(void);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,67 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/crypto.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef ... CRYPTO_THREADID;
|
||||
|
||||
static const int SSLEAY_VERSION;
|
||||
static const int SSLEAY_CFLAGS;
|
||||
static const int SSLEAY_PLATFORM;
|
||||
static const int SSLEAY_DIR;
|
||||
static const int SSLEAY_BUILT_ON;
|
||||
static const int CRYPTO_MEM_CHECK_ON;
|
||||
static const int CRYPTO_MEM_CHECK_OFF;
|
||||
static const int CRYPTO_MEM_CHECK_ENABLE;
|
||||
static const int CRYPTO_MEM_CHECK_DISABLE;
|
||||
static const int CRYPTO_LOCK;
|
||||
static const int CRYPTO_UNLOCK;
|
||||
static const int CRYPTO_READ;
|
||||
static const int CRYPTO_WRITE;
|
||||
static const int CRYPTO_LOCK_SSL;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
unsigned long SSLeay(void);
|
||||
const char *SSLeay_version(int);
|
||||
|
||||
void CRYPTO_free(void *);
|
||||
int CRYPTO_mem_ctrl(int);
|
||||
int CRYPTO_is_mem_check_on(void);
|
||||
void CRYPTO_mem_leaks(struct bio_st *);
|
||||
void CRYPTO_cleanup_all_ex_data(void);
|
||||
int CRYPTO_num_locks(void);
|
||||
void CRYPTO_set_locking_callback(void(*)(int, int, const char *, int));
|
||||
void CRYPTO_set_id_callback(unsigned long (*)(void));
|
||||
unsigned long (*CRYPTO_get_id_callback(void))(void);
|
||||
void (*CRYPTO_get_locking_callback(void))(int, int, const char *, int);
|
||||
void CRYPTO_lock(int, int, const char *, int);
|
||||
|
||||
void OPENSSL_free(void *);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
void CRYPTO_add(int *, int, int);
|
||||
void CRYPTO_malloc_init(void);
|
||||
void CRYPTO_malloc_debug_init(void);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,57 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/dh.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef struct dh_st {
|
||||
/* Prime number (shared) */
|
||||
BIGNUM *p;
|
||||
/* Generator of Z_p (shared) */
|
||||
BIGNUM *g;
|
||||
/* Private DH value x */
|
||||
BIGNUM *priv_key;
|
||||
/* Public DH value g^x */
|
||||
BIGNUM *pub_key;
|
||||
...;
|
||||
} DH;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
DH *DH_new(void);
|
||||
void DH_free(DH *);
|
||||
int DH_size(const DH *);
|
||||
DH *DH_generate_parameters(int, int, void (*)(int, int, void *), void *);
|
||||
int DH_check(const DH *, int *);
|
||||
int DH_generate_key(DH *);
|
||||
int DH_compute_key(unsigned char *, const BIGNUM *, DH *);
|
||||
int DH_set_ex_data(DH *, int, void *);
|
||||
void *DH_get_ex_data(DH *, int);
|
||||
DH *d2i_DHparams(DH **, const unsigned char **, long);
|
||||
int i2d_DHparams(const DH *, unsigned char **);
|
||||
int DHparams_print_fp(FILE *, const DH *);
|
||||
int DHparams_print(BIO *, const DH *);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
int DH_generate_parameters_ex(DH *, int, int, BN_GENCB *);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,65 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/dsa.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef struct dsa_st {
|
||||
/* Prime number (public) */
|
||||
BIGNUM *p;
|
||||
/* Subprime (160-bit, q | p-1, public) */
|
||||
BIGNUM *q;
|
||||
/* Generator of subgroup (public) */
|
||||
BIGNUM *g;
|
||||
/* Private key x */
|
||||
BIGNUM *priv_key;
|
||||
/* Public key y = g^x */
|
||||
BIGNUM *pub_key;
|
||||
...;
|
||||
} DSA;
|
||||
typedef struct {
|
||||
BIGNUM *r;
|
||||
BIGNUM *s;
|
||||
} DSA_SIG;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
DSA *DSA_generate_parameters(int, unsigned char *, int, int *, unsigned long *,
|
||||
void (*)(int, int, void *), void *);
|
||||
int DSA_generate_key(DSA *);
|
||||
DSA *DSA_new(void);
|
||||
void DSA_free(DSA *);
|
||||
DSA_SIG *DSA_SIG_new(void);
|
||||
void DSA_SIG_free(DSA_SIG *);
|
||||
int i2d_DSA_SIG(const DSA_SIG *, unsigned char **);
|
||||
DSA_SIG *d2i_DSA_SIG(DSA_SIG **, const unsigned char **, long);
|
||||
int DSA_size(const DSA *);
|
||||
int DSA_sign(int, const unsigned char *, int, unsigned char *, unsigned int *,
|
||||
DSA *);
|
||||
int DSA_verify(int, const unsigned char *, int, const unsigned char *, int,
|
||||
DSA *);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
int DSA_generate_parameters_ex(DSA *, int, unsigned char *, int,
|
||||
int *, unsigned long *, BN_GENCB *);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,490 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#ifndef OPENSSL_NO_EC
|
||||
#include <openssl/ec.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/obj_mac.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
static const int Cryptography_HAS_EC;
|
||||
static const int Cryptography_HAS_EC_1_0_1;
|
||||
static const int Cryptography_HAS_EC_NISTP_64_GCC_128;
|
||||
static const int Cryptography_HAS_EC2M;
|
||||
|
||||
static const int OPENSSL_EC_NAMED_CURVE;
|
||||
|
||||
typedef ... EC_KEY;
|
||||
typedef ... EC_GROUP;
|
||||
typedef ... EC_POINT;
|
||||
typedef ... EC_METHOD;
|
||||
typedef struct {
|
||||
int nid;
|
||||
const char *comment;
|
||||
} EC_builtin_curve;
|
||||
typedef enum { ... } point_conversion_form_t;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
EC_GROUP *EC_GROUP_new(const EC_METHOD *);
|
||||
void EC_GROUP_free(EC_GROUP *);
|
||||
void EC_GROUP_clear_free(EC_GROUP *);
|
||||
|
||||
EC_GROUP *EC_GROUP_new_curve_GFp(
|
||||
const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
EC_GROUP *EC_GROUP_new_curve_GF2m(
|
||||
const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
EC_GROUP *EC_GROUP_new_by_curve_name(int);
|
||||
|
||||
int EC_GROUP_set_curve_GFp(
|
||||
EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
int EC_GROUP_get_curve_GFp(
|
||||
const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *);
|
||||
int EC_GROUP_set_curve_GF2m(
|
||||
EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
int EC_GROUP_get_curve_GF2m(
|
||||
const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *);
|
||||
|
||||
int EC_GROUP_get_degree(const EC_GROUP *);
|
||||
|
||||
const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *);
|
||||
const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
|
||||
int EC_GROUP_get_curve_name(const EC_GROUP *);
|
||||
|
||||
size_t EC_get_builtin_curves(EC_builtin_curve *, size_t);
|
||||
|
||||
void EC_KEY_free(EC_KEY *);
|
||||
|
||||
int EC_KEY_get_flags(const EC_KEY *);
|
||||
void EC_KEY_set_flags(EC_KEY *, int);
|
||||
void EC_KEY_clear_flags(EC_KEY *, int);
|
||||
EC_KEY *EC_KEY_new_by_curve_name(int);
|
||||
EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *);
|
||||
EC_KEY *EC_KEY_dup(const EC_KEY *);
|
||||
int EC_KEY_up_ref(EC_KEY *);
|
||||
const EC_GROUP *EC_KEY_get0_group(const EC_KEY *);
|
||||
int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *, BN_CTX *);
|
||||
int EC_KEY_set_group(EC_KEY *, const EC_GROUP *);
|
||||
const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *);
|
||||
int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *);
|
||||
const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *);
|
||||
int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *);
|
||||
unsigned int EC_KEY_get_enc_flags(const EC_KEY *);
|
||||
void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int);
|
||||
point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
|
||||
void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
|
||||
void *EC_KEY_get_key_method_data(
|
||||
EC_KEY *,
|
||||
void *(*)(void *),
|
||||
void (*)(void *),
|
||||
void (*)(void *)
|
||||
);
|
||||
void EC_KEY_insert_key_method_data(
|
||||
EC_KEY *,
|
||||
void *,
|
||||
void *(*)(void *),
|
||||
void (*)(void *),
|
||||
void (*)(void *)
|
||||
);
|
||||
void EC_KEY_set_asn1_flag(EC_KEY *, int);
|
||||
int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *);
|
||||
int EC_KEY_generate_key(EC_KEY *);
|
||||
int EC_KEY_check_key(const EC_KEY *);
|
||||
int EC_KEY_set_public_key_affine_coordinates(EC_KEY *, BIGNUM *, BIGNUM *);
|
||||
|
||||
EC_POINT *EC_POINT_new(const EC_GROUP *);
|
||||
void EC_POINT_free(EC_POINT *);
|
||||
void EC_POINT_clear_free(EC_POINT *);
|
||||
int EC_POINT_copy(EC_POINT *, const EC_POINT *);
|
||||
EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *);
|
||||
const EC_METHOD *EC_POINT_method_of(const EC_POINT *);
|
||||
|
||||
int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *);
|
||||
|
||||
int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
|
||||
int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *,
|
||||
const EC_POINT *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *);
|
||||
|
||||
int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
|
||||
int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *,
|
||||
const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *);
|
||||
|
||||
int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *, int, BN_CTX *);
|
||||
|
||||
int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
|
||||
int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *,
|
||||
const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *);
|
||||
|
||||
int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *, int, BN_CTX *);
|
||||
|
||||
size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *,
|
||||
point_conversion_form_t,
|
||||
unsigned char *, size_t, BN_CTX *);
|
||||
|
||||
int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *,
|
||||
const unsigned char *, size_t, BN_CTX *);
|
||||
|
||||
BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
|
||||
point_conversion_form_t form, BIGNUM *, BN_CTX *);
|
||||
|
||||
EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
|
||||
EC_POINT *, BN_CTX *);
|
||||
|
||||
char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
|
||||
point_conversion_form_t form, BN_CTX *);
|
||||
|
||||
EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
|
||||
EC_POINT *, BN_CTX *);
|
||||
|
||||
int EC_POINT_add(const EC_GROUP *, EC_POINT *, const EC_POINT *,
|
||||
const EC_POINT *, BN_CTX *);
|
||||
|
||||
int EC_POINT_dbl(const EC_GROUP *, EC_POINT *, const EC_POINT *, BN_CTX *);
|
||||
int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
|
||||
int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *);
|
||||
int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
|
||||
|
||||
int EC_POINT_cmp(
|
||||
const EC_GROUP *, const EC_POINT *, const EC_POINT *, BN_CTX *);
|
||||
|
||||
int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
|
||||
int EC_POINTs_make_affine(const EC_GROUP *, size_t, EC_POINT *[], BN_CTX *);
|
||||
|
||||
int EC_POINTs_mul(
|
||||
const EC_GROUP *, EC_POINT *, const BIGNUM *,
|
||||
size_t, const EC_POINT *[], const BIGNUM *[], BN_CTX *);
|
||||
|
||||
int EC_POINT_mul(const EC_GROUP *, EC_POINT *, const BIGNUM *,
|
||||
const EC_POINT *, const BIGNUM *, BN_CTX *);
|
||||
|
||||
int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *);
|
||||
int EC_GROUP_have_precompute_mult(const EC_GROUP *);
|
||||
|
||||
const EC_METHOD *EC_GFp_simple_method();
|
||||
const EC_METHOD *EC_GFp_mont_method();
|
||||
const EC_METHOD *EC_GFp_nist_method();
|
||||
|
||||
const EC_METHOD *EC_GFp_nistp224_method();
|
||||
const EC_METHOD *EC_GFp_nistp256_method();
|
||||
const EC_METHOD *EC_GFp_nistp521_method();
|
||||
|
||||
const EC_METHOD *EC_GF2m_simple_method();
|
||||
|
||||
int EC_METHOD_get_field_type(const EC_METHOD *);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
#ifdef OPENSSL_NO_EC
|
||||
static const long Cryptography_HAS_EC = 0;
|
||||
|
||||
typedef void EC_KEY;
|
||||
typedef void EC_GROUP;
|
||||
typedef void EC_POINT;
|
||||
typedef void EC_METHOD;
|
||||
typedef struct {
|
||||
int nid;
|
||||
const char *comment;
|
||||
} EC_builtin_curve;
|
||||
typedef long point_conversion_form_t;
|
||||
|
||||
static const int OPENSSL_EC_NAMED_CURVE = 0;
|
||||
|
||||
void (*EC_KEY_free)(EC_KEY *) = NULL;
|
||||
size_t (*EC_get_builtin_curves)(EC_builtin_curve *, size_t) = NULL;
|
||||
EC_KEY *(*EC_KEY_new_by_curve_name)(int) = NULL;
|
||||
EC_KEY *(*EC_KEY_copy)(EC_KEY *, const EC_KEY *) = NULL;
|
||||
EC_KEY *(*EC_KEY_dup)(const EC_KEY *) = NULL;
|
||||
int (*EC_KEY_up_ref)(EC_KEY *) = NULL;
|
||||
const EC_GROUP *(*EC_KEY_get0_group)(const EC_KEY *) = NULL;
|
||||
int (*EC_GROUP_get_order)(const EC_GROUP *, BIGNUM *, BN_CTX *) = NULL;
|
||||
int (*EC_KEY_set_group)(EC_KEY *, const EC_GROUP *) = NULL;
|
||||
const BIGNUM *(*EC_KEY_get0_private_key)(const EC_KEY *) = NULL;
|
||||
int (*EC_KEY_set_private_key)(EC_KEY *, const BIGNUM *) = NULL;
|
||||
const EC_POINT *(*EC_KEY_get0_public_key)(const EC_KEY *) = NULL;
|
||||
int (*EC_KEY_set_public_key)(EC_KEY *, const EC_POINT *) = NULL;
|
||||
unsigned int (*EC_KEY_get_enc_flags)(const EC_KEY *) = NULL;
|
||||
void (*EC_KEY_set_enc_flags)(EC_KEY *eckey, unsigned int) = NULL;
|
||||
point_conversion_form_t (*EC_KEY_get_conv_form)(const EC_KEY *) = NULL;
|
||||
void (*EC_KEY_set_conv_form)(EC_KEY *, point_conversion_form_t) = NULL;
|
||||
void *(*EC_KEY_get_key_method_data)(
|
||||
EC_KEY *, void *(*)(void *), void (*)(void *), void (*)(void *)) = NULL;
|
||||
void (*EC_KEY_insert_key_method_data)(
|
||||
EC_KEY *, void *,
|
||||
void *(*)(void *), void (*)(void *), void (*)(void *)) = NULL;
|
||||
void (*EC_KEY_set_asn1_flag)(EC_KEY *, int) = NULL;
|
||||
int (*EC_KEY_precompute_mult)(EC_KEY *, BN_CTX *) = NULL;
|
||||
int (*EC_KEY_generate_key)(EC_KEY *) = NULL;
|
||||
int (*EC_KEY_check_key)(const EC_KEY *) = NULL;
|
||||
|
||||
EC_GROUP *(*EC_GROUP_new)(const EC_METHOD *);
|
||||
void (*EC_GROUP_free)(EC_GROUP *);
|
||||
void (*EC_GROUP_clear_free)(EC_GROUP *);
|
||||
|
||||
EC_GROUP *(*EC_GROUP_new_curve_GFp)(
|
||||
const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
|
||||
EC_GROUP *(*EC_GROUP_new_by_curve_name)(int);
|
||||
|
||||
int (*EC_GROUP_set_curve_GFp)(
|
||||
EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
|
||||
int (*EC_GROUP_get_curve_GFp)(
|
||||
const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *);
|
||||
|
||||
int (*EC_GROUP_get_degree)(const EC_GROUP *) = NULL;
|
||||
|
||||
const EC_METHOD *(*EC_GROUP_method_of)(const EC_GROUP *) = NULL;
|
||||
const EC_POINT *(*EC_GROUP_get0_generator)(const EC_GROUP *) = NULL;
|
||||
int (*EC_GROUP_get_curve_name)(const EC_GROUP *) = NULL;
|
||||
|
||||
EC_POINT *(*EC_POINT_new)(const EC_GROUP *) = NULL;
|
||||
void (*EC_POINT_free)(EC_POINT *) = NULL;
|
||||
void (*EC_POINT_clear_free)(EC_POINT *) = NULL;
|
||||
int (*EC_POINT_copy)(EC_POINT *, const EC_POINT *) = NULL;
|
||||
EC_POINT *(*EC_POINT_dup)(const EC_POINT *, const EC_GROUP *) = NULL;
|
||||
const EC_METHOD *(*EC_POINT_method_of)(const EC_POINT *) = NULL;
|
||||
int (*EC_POINT_set_to_infinity)(const EC_GROUP *, EC_POINT *) = NULL;
|
||||
int (*EC_POINT_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_get_Jprojective_coordinates_GFp)(const EC_GROUP *,
|
||||
const EC_POINT *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_set_affine_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_get_affine_coordinates_GFp)(const EC_GROUP *,
|
||||
const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_set_compressed_coordinates_GFp)(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *, int, BN_CTX *) = NULL;
|
||||
|
||||
size_t (*EC_POINT_point2oct)(const EC_GROUP *, const EC_POINT *,
|
||||
point_conversion_form_t,
|
||||
unsigned char *, size_t, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_oct2point)(const EC_GROUP *, EC_POINT *,
|
||||
const unsigned char *, size_t, BN_CTX *) = NULL;
|
||||
|
||||
BIGNUM *(*EC_POINT_point2bn)(const EC_GROUP *, const EC_POINT *,
|
||||
point_conversion_form_t form, BIGNUM *, BN_CTX *) = NULL;
|
||||
|
||||
EC_POINT *(*EC_POINT_bn2point)(const EC_GROUP *, const BIGNUM *,
|
||||
EC_POINT *, BN_CTX *) = NULL;
|
||||
|
||||
char *(*EC_POINT_point2hex)(const EC_GROUP *, const EC_POINT *,
|
||||
point_conversion_form_t form, BN_CTX *) = NULL;
|
||||
|
||||
EC_POINT *(*EC_POINT_hex2point)(const EC_GROUP *, const char *,
|
||||
EC_POINT *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_add)(const EC_GROUP *, EC_POINT *, const EC_POINT *,
|
||||
const EC_POINT *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_dbl)(const EC_GROUP *, EC_POINT *, const EC_POINT *,
|
||||
BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_invert)(const EC_GROUP *, EC_POINT *, BN_CTX *) = NULL;
|
||||
int (*EC_POINT_is_at_infinity)(const EC_GROUP *, const EC_POINT *) = NULL;
|
||||
|
||||
int (*EC_POINT_is_on_curve)(const EC_GROUP *, const EC_POINT *,
|
||||
BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_cmp)(
|
||||
const EC_GROUP *, const EC_POINT *, const EC_POINT *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINTs_make_affine)(const EC_GROUP *, size_t, EC_POINT *[],
|
||||
BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINTs_mul)(
|
||||
const EC_GROUP *, EC_POINT *, const BIGNUM *,
|
||||
size_t, const EC_POINT *[], const BIGNUM *[], BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_mul)(const EC_GROUP *, EC_POINT *, const BIGNUM *,
|
||||
const EC_POINT *, const BIGNUM *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_GROUP_precompute_mult)(EC_GROUP *, BN_CTX *) = NULL;
|
||||
int (*EC_GROUP_have_precompute_mult)(const EC_GROUP *) = NULL;
|
||||
|
||||
const EC_METHOD *(*EC_GFp_simple_method)() = NULL;
|
||||
const EC_METHOD *(*EC_GFp_mont_method)() = NULL;
|
||||
const EC_METHOD *(*EC_GFp_nist_method)() = NULL;
|
||||
|
||||
int (*EC_METHOD_get_field_type)(const EC_METHOD *) = NULL;
|
||||
|
||||
#else
|
||||
static const long Cryptography_HAS_EC = 1;
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_NO_EC) || OPENSSL_VERSION_NUMBER < 0x1000100f
|
||||
static const long Cryptography_HAS_EC_1_0_1 = 0;
|
||||
|
||||
int (*EC_KEY_get_flags)(const EC_KEY *) = NULL;
|
||||
void (*EC_KEY_set_flags)(EC_KEY *, int) = NULL;
|
||||
void (*EC_KEY_clear_flags)(EC_KEY *, int) = NULL;
|
||||
|
||||
int (*EC_KEY_set_public_key_affine_coordinates)(
|
||||
EC_KEY *, BIGNUM *, BIGNUM *) = NULL;
|
||||
#else
|
||||
static const long Cryptography_HAS_EC_1_0_1 = 1;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(OPENSSL_NO_EC) || OPENSSL_VERSION_NUMBER < 0x1000100f || \
|
||||
defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
|
||||
static const long Cryptography_HAS_EC_NISTP_64_GCC_128 = 0;
|
||||
|
||||
const EC_METHOD *(*EC_GFp_nistp224_method)(void) = NULL;
|
||||
const EC_METHOD *(*EC_GFp_nistp256_method)(void) = NULL;
|
||||
const EC_METHOD *(*EC_GFp_nistp521_method)(void) = NULL;
|
||||
#else
|
||||
static const long Cryptography_HAS_EC_NISTP_64_GCC_128 = 1;
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_NO_EC) || defined(OPENSSL_NO_EC2M)
|
||||
static const long Cryptography_HAS_EC2M = 0;
|
||||
|
||||
const EC_METHOD *(*EC_GF2m_simple_method)() = NULL;
|
||||
|
||||
int (*EC_POINT_set_affine_coordinates_GF2m)(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_get_affine_coordinates_GF2m)(const EC_GROUP *,
|
||||
const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_POINT_set_compressed_coordinates_GF2m)(const EC_GROUP *, EC_POINT *,
|
||||
const BIGNUM *, int, BN_CTX *) = NULL;
|
||||
|
||||
int (*EC_GROUP_set_curve_GF2m)(
|
||||
EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
|
||||
int (*EC_GROUP_get_curve_GF2m)(
|
||||
const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *);
|
||||
|
||||
EC_GROUP *(*EC_GROUP_new_curve_GF2m)(
|
||||
const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||
#else
|
||||
static const long Cryptography_HAS_EC2M = 1;
|
||||
#endif
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {
|
||||
"Cryptography_HAS_EC": [
|
||||
"OPENSSL_EC_NAMED_CURVE",
|
||||
"EC_GROUP_new",
|
||||
"EC_GROUP_free",
|
||||
"EC_GROUP_clear_free",
|
||||
"EC_GROUP_new_curve_GFp",
|
||||
"EC_GROUP_new_by_curve_name",
|
||||
"EC_GROUP_set_curve_GFp",
|
||||
"EC_GROUP_get_curve_GFp",
|
||||
"EC_GROUP_method_of",
|
||||
"EC_GROUP_get0_generator",
|
||||
"EC_GROUP_get_curve_name",
|
||||
"EC_GROUP_get_degree",
|
||||
"EC_KEY_free",
|
||||
"EC_get_builtin_curves",
|
||||
"EC_KEY_new_by_curve_name",
|
||||
"EC_KEY_copy",
|
||||
"EC_KEY_dup",
|
||||
"EC_KEY_up_ref",
|
||||
"EC_KEY_set_group",
|
||||
"EC_KEY_get0_private_key",
|
||||
"EC_KEY_set_private_key",
|
||||
"EC_KEY_set_public_key",
|
||||
"EC_KEY_get_enc_flags",
|
||||
"EC_KEY_set_enc_flags",
|
||||
"EC_KEY_set_conv_form",
|
||||
"EC_KEY_get_key_method_data",
|
||||
"EC_KEY_insert_key_method_data",
|
||||
"EC_KEY_set_asn1_flag",
|
||||
"EC_KEY_precompute_mult",
|
||||
"EC_KEY_generate_key",
|
||||
"EC_KEY_check_key",
|
||||
"EC_POINT_new",
|
||||
"EC_POINT_free",
|
||||
"EC_POINT_clear_free",
|
||||
"EC_POINT_copy",
|
||||
"EC_POINT_dup",
|
||||
"EC_POINT_method_of",
|
||||
"EC_POINT_set_to_infinity",
|
||||
"EC_POINT_set_Jprojective_coordinates_GFp",
|
||||
"EC_POINT_get_Jprojective_coordinates_GFp",
|
||||
"EC_POINT_set_affine_coordinates_GFp",
|
||||
"EC_POINT_get_affine_coordinates_GFp",
|
||||
"EC_POINT_set_compressed_coordinates_GFp",
|
||||
"EC_POINT_point2oct",
|
||||
"EC_POINT_oct2point",
|
||||
"EC_POINT_point2bn",
|
||||
"EC_POINT_bn2point",
|
||||
"EC_POINT_point2hex",
|
||||
"EC_POINT_hex2point",
|
||||
"EC_POINT_add",
|
||||
"EC_POINT_dbl",
|
||||
"EC_POINT_invert",
|
||||
"EC_POINT_is_at_infinity",
|
||||
"EC_POINT_is_on_curve",
|
||||
"EC_POINT_cmp",
|
||||
"EC_POINT_make_affine",
|
||||
"EC_POINTs_make_affine",
|
||||
"EC_POINTs_mul",
|
||||
"EC_POINT_mul",
|
||||
"EC_GROUP_precompute_mult",
|
||||
"EC_GROUP_have_precompute_mult",
|
||||
"EC_GFp_simple_method",
|
||||
"EC_GFp_mont_method",
|
||||
"EC_GFp_nist_method",
|
||||
"EC_METHOD_get_field_type",
|
||||
],
|
||||
|
||||
"Cryptography_HAS_EC_1_0_1": [
|
||||
"EC_KEY_get_flags",
|
||||
"EC_KEY_set_flags",
|
||||
"EC_KEY_clear_flags",
|
||||
"EC_KEY_set_public_key_affine_coordinates",
|
||||
],
|
||||
|
||||
"Cryptography_HAS_EC_NISTP_64_GCC_128": [
|
||||
"EC_GFp_nistp224_method",
|
||||
"EC_GFp_nistp256_method",
|
||||
"EC_GFp_nistp521_method",
|
||||
],
|
||||
|
||||
"Cryptography_HAS_EC2M": [
|
||||
"EC_GF2m_simple_method",
|
||||
"EC_POINT_set_affine_coordinates_GF2m",
|
||||
"EC_POINT_get_affine_coordinates_GF2m",
|
||||
"EC_POINT_set_compressed_coordinates_GF2m",
|
||||
"EC_GROUP_set_curve_GF2m",
|
||||
"EC_GROUP_get_curve_GF2m",
|
||||
"EC_GROUP_new_curve_GF2m",
|
||||
],
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#ifndef OPENSSL_NO_ECDH
|
||||
#include <openssl/ecdh.h>
|
||||
#endif
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
static const int Cryptography_HAS_ECDH;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
int ECDH_compute_key(void *, size_t, const EC_POINT *, EC_KEY *,
|
||||
void *(*)(const void *, size_t, void *, size_t *));
|
||||
|
||||
int ECDH_get_ex_new_index(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *,
|
||||
CRYPTO_EX_free *);
|
||||
|
||||
int ECDH_set_ex_data(EC_KEY *, int, void *);
|
||||
|
||||
void *ECDH_get_ex_data(EC_KEY *, int);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
#ifdef OPENSSL_NO_ECDH
|
||||
static const long Cryptography_HAS_ECDH = 0;
|
||||
|
||||
int (*ECDH_compute_key)(void *, size_t, const EC_POINT *, EC_KEY *,
|
||||
void *(*)(const void *, size_t, void *,
|
||||
size_t *)) = NULL;
|
||||
|
||||
int (*ECDH_get_ex_new_index)(long, void *, CRYPTO_EX_new *, CRYPTO_EX_dup *,
|
||||
CRYPTO_EX_free *) = NULL;
|
||||
|
||||
int (*ECDH_set_ex_data)(EC_KEY *, int, void *) = NULL;
|
||||
|
||||
void *(*ECDH_get_ex_data)(EC_KEY *, int) = NULL;
|
||||
|
||||
#else
|
||||
static const long Cryptography_HAS_ECDH = 1;
|
||||
#endif
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {
|
||||
"Cryptography_HAS_ECDH": [
|
||||
"ECDH_compute_key",
|
||||
"ECDH_get_ex_new_index",
|
||||
"ECDH_set_ex_data",
|
||||
"ECDH_get_ex_data",
|
||||
],
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#ifndef OPENSSL_NO_ECDSA
|
||||
#include <openssl/ecdsa.h>
|
||||
#endif
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
static const int Cryptography_HAS_ECDSA;
|
||||
|
||||
typedef struct {
|
||||
BIGNUM *r;
|
||||
BIGNUM *s;
|
||||
} ECDSA_SIG;
|
||||
|
||||
typedef ... CRYPTO_EX_new;
|
||||
typedef ... CRYPTO_EX_dup;
|
||||
typedef ... CRYPTO_EX_free;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
ECDSA_SIG *ECDSA_SIG_new();
|
||||
void ECDSA_SIG_free(ECDSA_SIG *);
|
||||
int i2d_ECDSA_SIG(const ECDSA_SIG *, unsigned char **);
|
||||
ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **s, const unsigned char **, long);
|
||||
ECDSA_SIG *ECDSA_do_sign(const unsigned char *, int, EC_KEY *);
|
||||
ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *, int, const BIGNUM *,
|
||||
const BIGNUM *, EC_KEY *);
|
||||
int ECDSA_do_verify(const unsigned char *, int, const ECDSA_SIG *, EC_KEY*);
|
||||
int ECDSA_sign_setup(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **);
|
||||
int ECDSA_sign(int, const unsigned char *, int, unsigned char *,
|
||||
unsigned int *, EC_KEY *);
|
||||
int ECDSA_sign_ex(int, const unsigned char *, int dgstlen, unsigned char *,
|
||||
unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *);
|
||||
int ECDSA_verify(int, const unsigned char *, int, const unsigned char *, int,
|
||||
EC_KEY *);
|
||||
int ECDSA_size(const EC_KEY *);
|
||||
|
||||
const ECDSA_METHOD* ECDSA_OpenSSL();
|
||||
void ECDSA_set_default_method(const ECDSA_METHOD *);
|
||||
const ECDSA_METHOD* ECDSA_get_default_method();
|
||||
int ECDSA_get_ex_new_index(long, void *, CRYPTO_EX_new *,
|
||||
CRYPTO_EX_dup *, CRYPTO_EX_free *);
|
||||
int ECDSA_set_method(EC_KEY *, const ECDSA_METHOD *);
|
||||
int ECDSA_set_ex_data(EC_KEY *, int, void *);
|
||||
void *ECDSA_get_ex_data(EC_KEY *, int);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
#ifdef OPENSSL_NO_ECDSA
|
||||
static const long Cryptography_HAS_ECDSA = 0;
|
||||
|
||||
typedef struct {
|
||||
BIGNUM *r;
|
||||
BIGNUM *s;
|
||||
} ECDSA_SIG;
|
||||
|
||||
ECDSA_SIG* (*ECDSA_SIG_new)() = NULL;
|
||||
void (*ECDSA_SIG_free)(ECDSA_SIG *) = NULL;
|
||||
int (*i2d_ECDSA_SIG)(const ECDSA_SIG *, unsigned char **) = NULL;
|
||||
ECDSA_SIG* (*d2i_ECDSA_SIG)(ECDSA_SIG **s, const unsigned char **,
|
||||
long) = NULL;
|
||||
ECDSA_SIG* (*ECDSA_do_sign)(const unsigned char *, int, EC_KEY *eckey) = NULL;
|
||||
ECDSA_SIG* (*ECDSA_do_sign_ex)(const unsigned char *, int, const BIGNUM *,
|
||||
const BIGNUM *, EC_KEY *) = NULL;
|
||||
int (*ECDSA_do_verify)(const unsigned char *, int, const ECDSA_SIG *,
|
||||
EC_KEY*) = NULL;
|
||||
int (*ECDSA_sign_setup)(EC_KEY *, BN_CTX *, BIGNUM **, BIGNUM **) = NULL;
|
||||
int (*ECDSA_sign)(int, const unsigned char *, int, unsigned char *,
|
||||
unsigned int *, EC_KEY *) = NULL;
|
||||
int (*ECDSA_sign_ex)(int, const unsigned char *, int dgstlen, unsigned char *,
|
||||
unsigned int *, const BIGNUM *, const BIGNUM *,
|
||||
EC_KEY *) = NULL;
|
||||
int (*ECDSA_verify)(int, const unsigned char *, int, const unsigned char *,
|
||||
int, EC_KEY *) = NULL;
|
||||
int (*ECDSA_size)(const EC_KEY *) = NULL;
|
||||
|
||||
const ECDSA_METHOD* (*ECDSA_OpenSSL)() = NULL;
|
||||
void (*ECDSA_set_default_method)(const ECDSA_METHOD *) = NULL;
|
||||
const ECDSA_METHOD* (*ECDSA_get_default_method)() = NULL;
|
||||
int (*ECDSA_set_method)(EC_KEY *, const ECDSA_METHOD *) = NULL;
|
||||
int (*ECDSA_get_ex_new_index)(long, void *, CRYPTO_EX_new *,
|
||||
CRYPTO_EX_dup *, CRYPTO_EX_free *) = NULL;
|
||||
int (*ECDSA_set_ex_data)(EC_KEY *, int, void *) = NULL;
|
||||
void* (*ECDSA_get_ex_data)(EC_KEY *, int) = NULL;
|
||||
#else
|
||||
static const long Cryptography_HAS_ECDSA = 1;
|
||||
#endif
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {
|
||||
"Cryptography_HAS_ECDSA": [
|
||||
"ECDSA_SIG_new",
|
||||
"ECDSA_SIG_free",
|
||||
"i2d_ECDSA_SIG",
|
||||
"d2i_ECDSA_SIG",
|
||||
"ECDSA_do_sign",
|
||||
"ECDSA_do_sign_ex",
|
||||
"ECDSA_do_verify",
|
||||
"ECDSA_sign_setup",
|
||||
"ECDSA_sign",
|
||||
"ECDSA_sign_ex",
|
||||
"ECDSA_verify",
|
||||
"ECDSA_size",
|
||||
"ECDSA_OpenSSL",
|
||||
"ECDSA_set_default_method",
|
||||
"ECDSA_get_default_method",
|
||||
"ECDSA_set_method",
|
||||
"ECDSA_get_ex_new_index",
|
||||
"ECDSA_set_ex_data",
|
||||
"ECDSA_get_ex_data",
|
||||
],
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/engine.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef ... ENGINE;
|
||||
typedef ... RSA_METHOD;
|
||||
typedef ... DSA_METHOD;
|
||||
typedef ... ECDH_METHOD;
|
||||
typedef ... ECDSA_METHOD;
|
||||
typedef ... DH_METHOD;
|
||||
typedef ... RAND_METHOD;
|
||||
typedef ... STORE_METHOD;
|
||||
typedef ... *ENGINE_GEN_INT_FUNC_PTR;
|
||||
typedef ... *ENGINE_CTRL_FUNC_PTR;
|
||||
typedef ... *ENGINE_LOAD_KEY_PTR;
|
||||
typedef ... *ENGINE_CIPHERS_PTR;
|
||||
typedef ... *ENGINE_DIGESTS_PTR;
|
||||
typedef ... ENGINE_CMD_DEFN;
|
||||
typedef ... UI_METHOD;
|
||||
|
||||
static const unsigned int ENGINE_METHOD_RSA;
|
||||
static const unsigned int ENGINE_METHOD_DSA;
|
||||
static const unsigned int ENGINE_METHOD_RAND;
|
||||
static const unsigned int ENGINE_METHOD_ECDH;
|
||||
static const unsigned int ENGINE_METHOD_ECDSA;
|
||||
static const unsigned int ENGINE_METHOD_CIPHERS;
|
||||
static const unsigned int ENGINE_METHOD_DIGESTS;
|
||||
static const unsigned int ENGINE_METHOD_STORE;
|
||||
static const unsigned int ENGINE_METHOD_ALL;
|
||||
static const unsigned int ENGINE_METHOD_NONE;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
ENGINE *ENGINE_get_first(void);
|
||||
ENGINE *ENGINE_get_last(void);
|
||||
ENGINE *ENGINE_get_next(ENGINE *);
|
||||
ENGINE *ENGINE_get_prev(ENGINE *);
|
||||
int ENGINE_add(ENGINE *);
|
||||
int ENGINE_remove(ENGINE *);
|
||||
ENGINE *ENGINE_by_id(const char *);
|
||||
int ENGINE_init(ENGINE *);
|
||||
int ENGINE_finish(ENGINE *);
|
||||
void ENGINE_load_openssl(void);
|
||||
void ENGINE_load_dynamic(void);
|
||||
void ENGINE_load_cryptodev(void);
|
||||
void ENGINE_load_builtin_engines(void);
|
||||
void ENGINE_cleanup(void);
|
||||
ENGINE *ENGINE_get_default_RSA(void);
|
||||
ENGINE *ENGINE_get_default_DSA(void);
|
||||
ENGINE *ENGINE_get_default_ECDH(void);
|
||||
ENGINE *ENGINE_get_default_ECDSA(void);
|
||||
ENGINE *ENGINE_get_default_DH(void);
|
||||
ENGINE *ENGINE_get_default_RAND(void);
|
||||
ENGINE *ENGINE_get_cipher_engine(int);
|
||||
ENGINE *ENGINE_get_digest_engine(int);
|
||||
int ENGINE_set_default_RSA(ENGINE *);
|
||||
int ENGINE_set_default_DSA(ENGINE *);
|
||||
int ENGINE_set_default_ECDH(ENGINE *);
|
||||
int ENGINE_set_default_ECDSA(ENGINE *);
|
||||
int ENGINE_set_default_DH(ENGINE *);
|
||||
int ENGINE_set_default_RAND(ENGINE *);
|
||||
int ENGINE_set_default_ciphers(ENGINE *);
|
||||
int ENGINE_set_default_digests(ENGINE *);
|
||||
int ENGINE_set_default_string(ENGINE *, const char *);
|
||||
int ENGINE_set_default(ENGINE *, unsigned int);
|
||||
unsigned int ENGINE_get_table_flags(void);
|
||||
void ENGINE_set_table_flags(unsigned int);
|
||||
int ENGINE_register_RSA(ENGINE *);
|
||||
void ENGINE_unregister_RSA(ENGINE *);
|
||||
void ENGINE_register_all_RSA(void);
|
||||
int ENGINE_register_DSA(ENGINE *);
|
||||
void ENGINE_unregister_DSA(ENGINE *);
|
||||
void ENGINE_register_all_DSA(void);
|
||||
int ENGINE_register_ECDH(ENGINE *);
|
||||
void ENGINE_unregister_ECDH(ENGINE *);
|
||||
void ENGINE_register_all_ECDH(void);
|
||||
int ENGINE_register_ECDSA(ENGINE *);
|
||||
void ENGINE_unregister_ECDSA(ENGINE *);
|
||||
void ENGINE_register_all_ECDSA(void);
|
||||
int ENGINE_register_DH(ENGINE *);
|
||||
void ENGINE_unregister_DH(ENGINE *);
|
||||
void ENGINE_register_all_DH(void);
|
||||
int ENGINE_register_RAND(ENGINE *);
|
||||
void ENGINE_unregister_RAND(ENGINE *);
|
||||
void ENGINE_register_all_RAND(void);
|
||||
int ENGINE_register_STORE(ENGINE *);
|
||||
void ENGINE_unregister_STORE(ENGINE *);
|
||||
void ENGINE_register_all_STORE(void);
|
||||
int ENGINE_register_ciphers(ENGINE *);
|
||||
void ENGINE_unregister_ciphers(ENGINE *);
|
||||
void ENGINE_register_all_ciphers(void);
|
||||
int ENGINE_register_digests(ENGINE *);
|
||||
void ENGINE_unregister_digests(ENGINE *);
|
||||
void ENGINE_register_all_digests(void);
|
||||
int ENGINE_register_complete(ENGINE *);
|
||||
int ENGINE_register_all_complete(void);
|
||||
int ENGINE_ctrl(ENGINE *, int, long, void *, void (*)(void));
|
||||
int ENGINE_cmd_is_executable(ENGINE *, int);
|
||||
int ENGINE_ctrl_cmd(ENGINE *, const char *, long, void *, void (*)(void), int);
|
||||
int ENGINE_ctrl_cmd_string(ENGINE *, const char *, const char *, int);
|
||||
|
||||
ENGINE *ENGINE_new(void);
|
||||
int ENGINE_free(ENGINE *);
|
||||
int ENGINE_up_ref(ENGINE *);
|
||||
int ENGINE_set_id(ENGINE *, const char *);
|
||||
int ENGINE_set_name(ENGINE *, const char *);
|
||||
int ENGINE_set_RSA(ENGINE *, const RSA_METHOD *);
|
||||
int ENGINE_set_DSA(ENGINE *, const DSA_METHOD *);
|
||||
int ENGINE_set_ECDH(ENGINE *, const ECDH_METHOD *);
|
||||
int ENGINE_set_ECDSA(ENGINE *, const ECDSA_METHOD *);
|
||||
int ENGINE_set_DH(ENGINE *, const DH_METHOD *);
|
||||
int ENGINE_set_RAND(ENGINE *, const RAND_METHOD *);
|
||||
int ENGINE_set_STORE(ENGINE *, const STORE_METHOD *);
|
||||
int ENGINE_set_destroy_function(ENGINE *, ENGINE_GEN_INT_FUNC_PTR);
|
||||
int ENGINE_set_init_function(ENGINE *, ENGINE_GEN_INT_FUNC_PTR);
|
||||
int ENGINE_set_finish_function(ENGINE *, ENGINE_GEN_INT_FUNC_PTR);
|
||||
int ENGINE_set_ctrl_function(ENGINE *, ENGINE_CTRL_FUNC_PTR);
|
||||
int ENGINE_set_load_privkey_function(ENGINE *, ENGINE_LOAD_KEY_PTR);
|
||||
int ENGINE_set_load_pubkey_function(ENGINE *, ENGINE_LOAD_KEY_PTR);
|
||||
int ENGINE_set_ciphers(ENGINE *, ENGINE_CIPHERS_PTR);
|
||||
int ENGINE_set_digests(ENGINE *, ENGINE_DIGESTS_PTR);
|
||||
int ENGINE_set_flags(ENGINE *, int);
|
||||
int ENGINE_set_cmd_defns(ENGINE *, const ENGINE_CMD_DEFN *);
|
||||
const char *ENGINE_get_id(const ENGINE *);
|
||||
const char *ENGINE_get_name(const ENGINE *);
|
||||
const RSA_METHOD *ENGINE_get_RSA(const ENGINE *);
|
||||
const DSA_METHOD *ENGINE_get_DSA(const ENGINE *);
|
||||
const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *);
|
||||
const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *);
|
||||
const DH_METHOD *ENGINE_get_DH(const ENGINE *);
|
||||
const RAND_METHOD *ENGINE_get_RAND(const ENGINE *);
|
||||
const STORE_METHOD *ENGINE_get_STORE(const ENGINE *);
|
||||
|
||||
const EVP_CIPHER *ENGINE_get_cipher(ENGINE *, int);
|
||||
const EVP_MD *ENGINE_get_digest(ENGINE *, int);
|
||||
int ENGINE_get_flags(const ENGINE *);
|
||||
const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *);
|
||||
EVP_PKEY *ENGINE_load_private_key(ENGINE *, const char *, UI_METHOD *, void *);
|
||||
EVP_PKEY *ENGINE_load_public_key(ENGINE *, const char *, UI_METHOD *, void *);
|
||||
void ENGINE_add_conf_module(void);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,347 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/err.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
static const int Cryptography_HAS_REMOVE_THREAD_STATE;
|
||||
static const int Cryptography_HAS_098H_ERROR_CODES;
|
||||
static const int Cryptography_HAS_098C_CAMELLIA_CODES;
|
||||
static const int Cryptography_HAS_EC_CODES;
|
||||
|
||||
struct ERR_string_data_st {
|
||||
unsigned long error;
|
||||
const char *string;
|
||||
};
|
||||
typedef struct ERR_string_data_st ERR_STRING_DATA;
|
||||
|
||||
static const int ERR_LIB_EVP;
|
||||
static const int ERR_LIB_EC;
|
||||
static const int ERR_LIB_PEM;
|
||||
static const int ERR_LIB_ASN1;
|
||||
static const int ERR_LIB_RSA;
|
||||
|
||||
static const int ASN1_F_ASN1_ENUMERATED_TO_BN;
|
||||
static const int ASN1_F_ASN1_EX_C2I;
|
||||
static const int ASN1_F_ASN1_FIND_END;
|
||||
static const int ASN1_F_ASN1_GENERALIZEDTIME_SET;
|
||||
static const int ASN1_F_ASN1_GENERATE_V3;
|
||||
static const int ASN1_F_ASN1_GET_OBJECT;
|
||||
static const int ASN1_F_ASN1_ITEM_I2D_FP;
|
||||
static const int ASN1_F_ASN1_ITEM_PACK;
|
||||
static const int ASN1_F_ASN1_ITEM_SIGN;
|
||||
static const int ASN1_F_ASN1_ITEM_UNPACK;
|
||||
static const int ASN1_F_ASN1_ITEM_VERIFY;
|
||||
static const int ASN1_F_ASN1_MBSTRING_NCOPY;
|
||||
static const int ASN1_F_ASN1_TEMPLATE_EX_D2I;
|
||||
static const int ASN1_F_ASN1_TEMPLATE_NEW;
|
||||
static const int ASN1_F_ASN1_TEMPLATE_NOEXP_D2I;
|
||||
static const int ASN1_F_ASN1_TIME_SET;
|
||||
static const int ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING;
|
||||
static const int ASN1_F_ASN1_TYPE_GET_OCTETSTRING;
|
||||
static const int ASN1_F_ASN1_UNPACK_STRING;
|
||||
static const int ASN1_F_ASN1_UTCTIME_SET;
|
||||
static const int ASN1_F_ASN1_VERIFY;
|
||||
static const int ASN1_F_BITSTR_CB;
|
||||
static const int ASN1_F_BN_TO_ASN1_ENUMERATED;
|
||||
static const int ASN1_F_BN_TO_ASN1_INTEGER;
|
||||
static const int ASN1_F_D2I_ASN1_TYPE_BYTES;
|
||||
static const int ASN1_F_D2I_ASN1_UINTEGER;
|
||||
static const int ASN1_F_D2I_ASN1_UTCTIME;
|
||||
static const int ASN1_F_D2I_NETSCAPE_RSA;
|
||||
static const int ASN1_F_D2I_NETSCAPE_RSA_2;
|
||||
static const int ASN1_F_D2I_PRIVATEKEY;
|
||||
static const int ASN1_F_D2I_X509;
|
||||
static const int ASN1_F_D2I_X509_CINF;
|
||||
static const int ASN1_F_D2I_X509_PKEY;
|
||||
static const int ASN1_F_I2D_ASN1_SET;
|
||||
static const int ASN1_F_I2D_ASN1_TIME;
|
||||
static const int ASN1_F_I2D_DSA_PUBKEY;
|
||||
static const int ASN1_F_LONG_C2I;
|
||||
static const int ASN1_F_OID_MODULE_INIT;
|
||||
static const int ASN1_F_PARSE_TAGGING;
|
||||
static const int ASN1_F_PKCS5_PBE_SET;
|
||||
static const int ASN1_F_X509_CINF_NEW;
|
||||
static const int ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
|
||||
static const int ASN1_R_BUFFER_TOO_SMALL;
|
||||
static const int ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER;
|
||||
static const int ASN1_R_DATA_IS_WRONG;
|
||||
static const int ASN1_R_DECODE_ERROR;
|
||||
static const int ASN1_R_DECODING_ERROR;
|
||||
static const int ASN1_R_DEPTH_EXCEEDED;
|
||||
static const int ASN1_R_ENCODE_ERROR;
|
||||
static const int ASN1_R_ERROR_GETTING_TIME;
|
||||
static const int ASN1_R_ERROR_LOADING_SECTION;
|
||||
static const int ASN1_R_MSTRING_WRONG_TAG;
|
||||
static const int ASN1_R_NESTED_ASN1_STRING;
|
||||
static const int ASN1_R_NO_MATCHING_CHOICE_TYPE;
|
||||
static const int ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM;
|
||||
static const int ASN1_R_UNKNOWN_OBJECT_TYPE;
|
||||
static const int ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE;
|
||||
static const int ASN1_R_UNKNOWN_TAG;
|
||||
static const int ASN1_R_UNKOWN_FORMAT;
|
||||
static const int ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE;
|
||||
static const int ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM;
|
||||
static const int ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE;
|
||||
static const int ASN1_R_UNSUPPORTED_TYPE;
|
||||
static const int ASN1_R_WRONG_TAG;
|
||||
static const int ASN1_R_WRONG_TYPE;
|
||||
|
||||
static const int EVP_F_AES_INIT_KEY;
|
||||
static const int EVP_F_D2I_PKEY;
|
||||
static const int EVP_F_DSA_PKEY2PKCS8;
|
||||
static const int EVP_F_DSAPKEY2PKCS8;
|
||||
static const int EVP_F_ECDSA_PKEY2PKCS8;
|
||||
static const int EVP_F_ECKEY_PKEY2PKCS8;
|
||||
static const int EVP_F_EVP_CIPHER_CTX_CTRL;
|
||||
static const int EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH;
|
||||
static const int EVP_F_EVP_CIPHERINIT_EX;
|
||||
static const int EVP_F_EVP_DECRYPTFINAL_EX;
|
||||
static const int EVP_F_EVP_DIGESTINIT_EX;
|
||||
static const int EVP_F_EVP_ENCRYPTFINAL_EX;
|
||||
static const int EVP_F_EVP_MD_CTX_COPY_EX;
|
||||
static const int EVP_F_EVP_OPENINIT;
|
||||
static const int EVP_F_EVP_PBE_ALG_ADD;
|
||||
static const int EVP_F_EVP_PBE_CIPHERINIT;
|
||||
static const int EVP_F_EVP_PKCS82PKEY;
|
||||
static const int EVP_F_EVP_PKEY2PKCS8_BROKEN;
|
||||
static const int EVP_F_EVP_PKEY_COPY_PARAMETERS;
|
||||
static const int EVP_F_EVP_PKEY_DECRYPT;
|
||||
static const int EVP_F_EVP_PKEY_ENCRYPT;
|
||||
static const int EVP_F_EVP_PKEY_GET1_DH;
|
||||
static const int EVP_F_EVP_PKEY_GET1_DSA;
|
||||
static const int EVP_F_EVP_PKEY_GET1_ECDSA;
|
||||
static const int EVP_F_EVP_PKEY_GET1_EC_KEY;
|
||||
static const int EVP_F_EVP_PKEY_GET1_RSA;
|
||||
static const int EVP_F_EVP_PKEY_NEW;
|
||||
static const int EVP_F_EVP_RIJNDAEL;
|
||||
static const int EVP_F_EVP_SIGNFINAL;
|
||||
static const int EVP_F_EVP_VERIFYFINAL;
|
||||
static const int EVP_F_PKCS5_PBE_KEYIVGEN;
|
||||
static const int EVP_F_PKCS5_V2_PBE_KEYIVGEN;
|
||||
static const int EVP_F_PKCS8_SET_BROKEN;
|
||||
static const int EVP_F_RC2_MAGIC_TO_METH;
|
||||
static const int EVP_F_RC5_CTRL;
|
||||
|
||||
static const int EVP_R_AES_KEY_SETUP_FAILED;
|
||||
static const int EVP_R_ASN1_LIB;
|
||||
static const int EVP_R_BAD_BLOCK_LENGTH;
|
||||
static const int EVP_R_BAD_DECRYPT;
|
||||
static const int EVP_R_BAD_KEY_LENGTH;
|
||||
static const int EVP_R_BN_DECODE_ERROR;
|
||||
static const int EVP_R_BN_PUBKEY_ERROR;
|
||||
static const int EVP_R_CIPHER_PARAMETER_ERROR;
|
||||
static const int EVP_R_CTRL_NOT_IMPLEMENTED;
|
||||
static const int EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED;
|
||||
static const int EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH;
|
||||
static const int EVP_R_DECODE_ERROR;
|
||||
static const int EVP_R_DIFFERENT_KEY_TYPES;
|
||||
static const int EVP_R_ENCODE_ERROR;
|
||||
static const int EVP_R_INITIALIZATION_ERROR;
|
||||
static const int EVP_R_INPUT_NOT_INITIALIZED;
|
||||
static const int EVP_R_INVALID_KEY_LENGTH;
|
||||
static const int EVP_R_IV_TOO_LARGE;
|
||||
static const int EVP_R_KEYGEN_FAILURE;
|
||||
static const int EVP_R_MISSING_PARAMETERS;
|
||||
static const int EVP_R_NO_CIPHER_SET;
|
||||
static const int EVP_R_NO_DIGEST_SET;
|
||||
static const int EVP_R_NO_DSA_PARAMETERS;
|
||||
static const int EVP_R_NO_SIGN_FUNCTION_CONFIGURED;
|
||||
static const int EVP_R_NO_VERIFY_FUNCTION_CONFIGURED;
|
||||
static const int EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE;
|
||||
static const int EVP_R_PUBLIC_KEY_NOT_RSA;
|
||||
static const int EVP_R_UNKNOWN_PBE_ALGORITHM;
|
||||
static const int EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS;
|
||||
static const int EVP_R_UNSUPPORTED_CIPHER;
|
||||
static const int EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION;
|
||||
static const int EVP_R_UNSUPPORTED_KEYLENGTH;
|
||||
static const int EVP_R_UNSUPPORTED_SALT_TYPE;
|
||||
static const int EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM;
|
||||
static const int EVP_R_WRONG_FINAL_BLOCK_LENGTH;
|
||||
static const int EVP_R_WRONG_PUBLIC_KEY_TYPE;
|
||||
|
||||
static const int EC_F_EC_GROUP_NEW_BY_CURVE_NAME;
|
||||
|
||||
static const int EC_R_UNKNOWN_GROUP;
|
||||
|
||||
static const int PEM_F_D2I_PKCS8PRIVATEKEY_BIO;
|
||||
static const int PEM_F_D2I_PKCS8PRIVATEKEY_FP;
|
||||
static const int PEM_F_DO_PK8PKEY;
|
||||
static const int PEM_F_DO_PK8PKEY_FP;
|
||||
static const int PEM_F_LOAD_IV;
|
||||
static const int PEM_F_PEM_ASN1_READ;
|
||||
static const int PEM_F_PEM_ASN1_READ_BIO;
|
||||
static const int PEM_F_PEM_ASN1_WRITE;
|
||||
static const int PEM_F_PEM_ASN1_WRITE_BIO;
|
||||
static const int PEM_F_PEM_DEF_CALLBACK;
|
||||
static const int PEM_F_PEM_DO_HEADER;
|
||||
static const int PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY;
|
||||
static const int PEM_F_PEM_GET_EVP_CIPHER_INFO;
|
||||
static const int PEM_F_PEM_PK8PKEY;
|
||||
static const int PEM_F_PEM_READ;
|
||||
static const int PEM_F_PEM_READ_BIO;
|
||||
static const int PEM_F_PEM_READ_BIO_PRIVATEKEY;
|
||||
static const int PEM_F_PEM_READ_PRIVATEKEY;
|
||||
static const int PEM_F_PEM_SEALFINAL;
|
||||
static const int PEM_F_PEM_SEALINIT;
|
||||
static const int PEM_F_PEM_SIGNFINAL;
|
||||
static const int PEM_F_PEM_WRITE;
|
||||
static const int PEM_F_PEM_WRITE_BIO;
|
||||
static const int PEM_F_PEM_X509_INFO_READ;
|
||||
static const int PEM_F_PEM_X509_INFO_READ_BIO;
|
||||
static const int PEM_F_PEM_X509_INFO_WRITE_BIO;
|
||||
|
||||
static const int PEM_R_BAD_BASE64_DECODE;
|
||||
static const int PEM_R_BAD_DECRYPT;
|
||||
static const int PEM_R_BAD_END_LINE;
|
||||
static const int PEM_R_BAD_IV_CHARS;
|
||||
static const int PEM_R_BAD_PASSWORD_READ;
|
||||
static const int PEM_R_ERROR_CONVERTING_PRIVATE_KEY;
|
||||
static const int PEM_R_NO_START_LINE;
|
||||
static const int PEM_R_NOT_DEK_INFO;
|
||||
static const int PEM_R_NOT_ENCRYPTED;
|
||||
static const int PEM_R_NOT_PROC_TYPE;
|
||||
static const int PEM_R_PROBLEMS_GETTING_PASSWORD;
|
||||
static const int PEM_R_PUBLIC_KEY_NO_RSA;
|
||||
static const int PEM_R_READ_KEY;
|
||||
static const int PEM_R_SHORT_HEADER;
|
||||
static const int PEM_R_UNSUPPORTED_CIPHER;
|
||||
static const int PEM_R_UNSUPPORTED_ENCRYPTION;
|
||||
|
||||
static const int RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
|
||||
static const int RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY;
|
||||
static const int RSA_R_BLOCK_TYPE_IS_NOT_01;
|
||||
static const int RSA_R_BLOCK_TYPE_IS_NOT_02;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
void ERR_load_crypto_strings(void);
|
||||
void ERR_load_SSL_strings(void);
|
||||
void ERR_free_strings(void);
|
||||
char* ERR_error_string(unsigned long, char *);
|
||||
void ERR_error_string_n(unsigned long, char *, size_t);
|
||||
const char* ERR_lib_error_string(unsigned long);
|
||||
const char* ERR_func_error_string(unsigned long);
|
||||
const char* ERR_reason_error_string(unsigned long);
|
||||
void ERR_print_errors(BIO *);
|
||||
void ERR_print_errors_fp(FILE *);
|
||||
unsigned long ERR_get_error(void);
|
||||
unsigned long ERR_peek_error(void);
|
||||
unsigned long ERR_peek_last_error(void);
|
||||
unsigned long ERR_get_error_line(const char **, int *);
|
||||
unsigned long ERR_peek_error_line(const char **, int *);
|
||||
unsigned long ERR_peek_last_error_line(const char **, int *);
|
||||
unsigned long ERR_get_error_line_data(const char **, int *,
|
||||
const char **, int *);
|
||||
unsigned long ERR_peek_error_line_data(const char **,
|
||||
int *, const char **, int *);
|
||||
unsigned long ERR_peek_last_error_line_data(const char **,
|
||||
int *, const char **, int *);
|
||||
void ERR_put_error(int, int, int, const char *, int);
|
||||
void ERR_add_error_data(int, ...);
|
||||
int ERR_get_next_error_library(void);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
unsigned long ERR_PACK(int, int, int);
|
||||
int ERR_GET_LIB(unsigned long);
|
||||
int ERR_GET_FUNC(unsigned long);
|
||||
int ERR_GET_REASON(unsigned long);
|
||||
int ERR_FATAL_ERROR(unsigned long);
|
||||
/* introduced in 1.0.0 so we have to handle this specially to continue
|
||||
* supporting 0.9.8
|
||||
*/
|
||||
void ERR_remove_thread_state(const CRYPTO_THREADID *);
|
||||
|
||||
/* These were added in OpenSSL 0.9.8h. When we drop support for RHEL/CentOS 5
|
||||
we should be able to move these back to TYPES. */
|
||||
static const int ASN1_F_B64_READ_ASN1;
|
||||
static const int ASN1_F_B64_WRITE_ASN1;
|
||||
static const int ASN1_F_SMIME_READ_ASN1;
|
||||
static const int ASN1_F_SMIME_TEXT;
|
||||
static const int ASN1_R_NO_CONTENT_TYPE;
|
||||
static const int ASN1_R_NO_MULTIPART_BODY_FAILURE;
|
||||
static const int ASN1_R_NO_MULTIPART_BOUNDARY;
|
||||
/* These were added in OpenSSL 0.9.8c. */
|
||||
static const int EVP_F_CAMELLIA_INIT_KEY;
|
||||
static const int EVP_R_CAMELLIA_KEY_SETUP_FAILED;
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
static const long Cryptography_HAS_REMOVE_THREAD_STATE = 1;
|
||||
#else
|
||||
static const long Cryptography_HAS_REMOVE_THREAD_STATE = 0;
|
||||
typedef uint32_t CRYPTO_THREADID;
|
||||
void (*ERR_remove_thread_state)(const CRYPTO_THREADID *) = NULL;
|
||||
#endif
|
||||
|
||||
/* OpenSSL 0.9.8h+ */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090808fL
|
||||
static const long Cryptography_HAS_098H_ERROR_CODES = 1;
|
||||
#else
|
||||
static const long Cryptography_HAS_098H_ERROR_CODES = 0;
|
||||
static const int ASN1_F_B64_READ_ASN1 = 0;
|
||||
static const int ASN1_F_B64_WRITE_ASN1 = 0;
|
||||
static const int ASN1_F_SMIME_READ_ASN1 = 0;
|
||||
static const int ASN1_F_SMIME_TEXT = 0;
|
||||
static const int ASN1_R_NO_CONTENT_TYPE = 0;
|
||||
static const int ASN1_R_NO_MULTIPART_BODY_FAILURE = 0;
|
||||
static const int ASN1_R_NO_MULTIPART_BOUNDARY = 0;
|
||||
#endif
|
||||
|
||||
/* OpenSSL 0.9.8c+ */
|
||||
#ifdef EVP_F_CAMELLIA_INIT_KEY
|
||||
static const long Cryptography_HAS_098C_CAMELLIA_CODES = 1;
|
||||
#else
|
||||
static const long Cryptography_HAS_098C_CAMELLIA_CODES = 0;
|
||||
static const int EVP_F_CAMELLIA_INIT_KEY = 0;
|
||||
static const int EVP_R_CAMELLIA_KEY_SETUP_FAILED = 0;
|
||||
#endif
|
||||
|
||||
// OpenSSL without EC. e.g. RHEL
|
||||
#ifndef OPENSSL_NO_EC
|
||||
static const long Cryptography_HAS_EC_CODES = 1;
|
||||
#else
|
||||
static const long Cryptography_HAS_EC_CODES = 0;
|
||||
static const int EC_R_UNKNOWN_GROUP = 0;
|
||||
static const int EC_F_EC_GROUP_NEW_BY_CURVE_NAME = 0;
|
||||
#endif
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {
|
||||
"Cryptography_HAS_REMOVE_THREAD_STATE": [
|
||||
"ERR_remove_thread_state"
|
||||
],
|
||||
"Cryptography_HAS_098H_ERROR_CODES": [
|
||||
"ASN1_F_B64_READ_ASN1",
|
||||
"ASN1_F_B64_WRITE_ASN1",
|
||||
"ASN1_F_SMIME_READ_ASN1",
|
||||
"ASN1_F_SMIME_TEXT",
|
||||
"ASN1_R_NO_CONTENT_TYPE",
|
||||
"ASN1_R_NO_MULTIPART_BODY_FAILURE",
|
||||
"ASN1_R_NO_MULTIPART_BOUNDARY",
|
||||
],
|
||||
"Cryptography_HAS_098C_CAMELLIA_CODES": [
|
||||
"EVP_F_CAMELLIA_INIT_KEY",
|
||||
"EVP_R_CAMELLIA_KEY_SETUP_FAILED"
|
||||
],
|
||||
"Cryptography_HAS_EC_CODES": [
|
||||
"EC_R_UNKNOWN_GROUP",
|
||||
"EC_F_EC_GROUP_NEW_BY_CURVE_NAME"
|
||||
]
|
||||
}
|
|
@ -1,261 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/evp.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef ... EVP_CIPHER;
|
||||
typedef struct {
|
||||
const EVP_CIPHER *cipher;
|
||||
ENGINE *engine;
|
||||
int encrypt;
|
||||
...;
|
||||
} EVP_CIPHER_CTX;
|
||||
typedef ... EVP_MD;
|
||||
typedef struct env_md_ctx_st {
|
||||
...;
|
||||
} EVP_MD_CTX;
|
||||
|
||||
typedef struct evp_pkey_st {
|
||||
int type;
|
||||
...;
|
||||
} EVP_PKEY;
|
||||
typedef ... EVP_PKEY_CTX;
|
||||
static const int EVP_PKEY_RSA;
|
||||
static const int EVP_PKEY_DSA;
|
||||
static const int EVP_PKEY_EC;
|
||||
static const int EVP_MAX_MD_SIZE;
|
||||
static const int EVP_CTRL_GCM_SET_IVLEN;
|
||||
static const int EVP_CTRL_GCM_GET_TAG;
|
||||
static const int EVP_CTRL_GCM_SET_TAG;
|
||||
|
||||
static const int Cryptography_HAS_GCM;
|
||||
static const int Cryptography_HAS_PBKDF2_HMAC;
|
||||
static const int Cryptography_HAS_PKEY_CTX;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
const EVP_CIPHER *EVP_get_cipherbyname(const char *);
|
||||
int EVP_EncryptInit_ex(EVP_CIPHER_CTX *, const EVP_CIPHER *, ENGINE *,
|
||||
const unsigned char *, const unsigned char *);
|
||||
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *, int);
|
||||
int EVP_EncryptUpdate(EVP_CIPHER_CTX *, unsigned char *, int *,
|
||||
const unsigned char *, int);
|
||||
int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *, unsigned char *, int *);
|
||||
int EVP_DecryptInit_ex(EVP_CIPHER_CTX *, const EVP_CIPHER *, ENGINE *,
|
||||
const unsigned char *, const unsigned char *);
|
||||
int EVP_DecryptUpdate(EVP_CIPHER_CTX *, unsigned char *, int *,
|
||||
const unsigned char *, int);
|
||||
int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *, unsigned char *, int *);
|
||||
int EVP_CipherInit_ex(EVP_CIPHER_CTX *, const EVP_CIPHER *, ENGINE *,
|
||||
const unsigned char *, const unsigned char *, int);
|
||||
int EVP_CipherUpdate(EVP_CIPHER_CTX *, unsigned char *, int *,
|
||||
const unsigned char *, int);
|
||||
int EVP_CipherFinal_ex(EVP_CIPHER_CTX *, unsigned char *, int *);
|
||||
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *);
|
||||
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *);
|
||||
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
|
||||
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *);
|
||||
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *, int);
|
||||
|
||||
EVP_MD_CTX *EVP_MD_CTX_create(void);
|
||||
int EVP_MD_CTX_copy_ex(EVP_MD_CTX *, const EVP_MD_CTX *);
|
||||
int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *);
|
||||
int EVP_DigestUpdate(EVP_MD_CTX *, const void *, size_t);
|
||||
int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *);
|
||||
int EVP_MD_CTX_cleanup(EVP_MD_CTX *);
|
||||
void EVP_MD_CTX_destroy(EVP_MD_CTX *);
|
||||
const EVP_MD *EVP_get_digestbyname(const char *);
|
||||
|
||||
EVP_PKEY *EVP_PKEY_new(void);
|
||||
void EVP_PKEY_free(EVP_PKEY *);
|
||||
int EVP_PKEY_type(int);
|
||||
int EVP_PKEY_bits(EVP_PKEY *);
|
||||
int EVP_PKEY_size(EVP_PKEY *);
|
||||
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *);
|
||||
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *);
|
||||
DH *EVP_PKEY_get1_DH(EVP_PKEY *);
|
||||
|
||||
int EVP_SignInit(EVP_MD_CTX *, const EVP_MD *);
|
||||
int EVP_SignUpdate(EVP_MD_CTX *, const void *, size_t);
|
||||
int EVP_SignFinal(EVP_MD_CTX *, unsigned char *, unsigned int *, EVP_PKEY *);
|
||||
|
||||
int EVP_VerifyInit(EVP_MD_CTX *, const EVP_MD *);
|
||||
int EVP_VerifyUpdate(EVP_MD_CTX *, const void *, size_t);
|
||||
int EVP_VerifyFinal(EVP_MD_CTX *, const unsigned char *, unsigned int,
|
||||
EVP_PKEY *);
|
||||
|
||||
const EVP_MD *EVP_md5(void);
|
||||
|
||||
int PKCS5_PBKDF2_HMAC_SHA1(const char *, int, const unsigned char *, int, int,
|
||||
int, unsigned char *);
|
||||
|
||||
int EVP_PKEY_set1_RSA(EVP_PKEY *, struct rsa_st *);
|
||||
int EVP_PKEY_set1_DSA(EVP_PKEY *, struct dsa_st *);
|
||||
int EVP_PKEY_set1_DH(EVP_PKEY *, DH *);
|
||||
|
||||
int EVP_PKEY_get_attr_count(const EVP_PKEY *);
|
||||
int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *, int, int);
|
||||
int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *, ASN1_OBJECT *, int);
|
||||
X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *, int);
|
||||
X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *, int);
|
||||
int EVP_PKEY_add1_attr(EVP_PKEY *, X509_ATTRIBUTE *);
|
||||
int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *, const ASN1_OBJECT *, int,
|
||||
const unsigned char *, int);
|
||||
int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *, int, int,
|
||||
const unsigned char *, int);
|
||||
int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *, const char *, int,
|
||||
const unsigned char *, int);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
void OpenSSL_add_all_algorithms(void);
|
||||
int EVP_PKEY_assign_RSA(EVP_PKEY *, RSA *);
|
||||
int EVP_PKEY_assign_DSA(EVP_PKEY *, DSA *);
|
||||
|
||||
int EVP_PKEY_assign_EC_KEY(EVP_PKEY *, EC_KEY *);
|
||||
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *);
|
||||
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *, EC_KEY *);
|
||||
|
||||
int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *);
|
||||
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *, int, int, void *);
|
||||
|
||||
int PKCS5_PBKDF2_HMAC(const char *, int, const unsigned char *, int, int,
|
||||
const EVP_MD *, int, unsigned char *);
|
||||
|
||||
int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *, const EVP_MD *);
|
||||
|
||||
/* These aren't macros, but must be in this section because they're not
|
||||
available in 0.9.8. */
|
||||
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *, ENGINE *);
|
||||
EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int, ENGINE *);
|
||||
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *);
|
||||
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *);
|
||||
int EVP_PKEY_sign_init(EVP_PKEY_CTX *);
|
||||
int EVP_PKEY_sign(EVP_PKEY_CTX *, unsigned char *, size_t *,
|
||||
const unsigned char *, size_t);
|
||||
int EVP_PKEY_verify_init(EVP_PKEY_CTX *);
|
||||
int EVP_PKEY_verify(EVP_PKEY_CTX *, const unsigned char *, size_t,
|
||||
const unsigned char *, size_t);
|
||||
int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *);
|
||||
int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *);
|
||||
|
||||
/* The following were macros in 0.9.8e. Once we drop support for RHEL/CentOS 5
|
||||
we should move these back to FUNCTIONS. */
|
||||
const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *);
|
||||
int EVP_CIPHER_block_size(const EVP_CIPHER *);
|
||||
const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *);
|
||||
int EVP_MD_size(const EVP_MD *);
|
||||
|
||||
/* Must be in macros because EVP_PKEY_CTX is undefined in 0.9.8 */
|
||||
int Cryptography_EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
|
||||
size_t *outlen, const unsigned char *in,
|
||||
size_t inlen);
|
||||
int Cryptography_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
|
||||
size_t *outlen, const unsigned char *in,
|
||||
size_t inlen);
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
#ifdef EVP_CTRL_GCM_SET_TAG
|
||||
const long Cryptography_HAS_GCM = 1;
|
||||
#else
|
||||
const long Cryptography_HAS_GCM = 0;
|
||||
const long EVP_CTRL_GCM_GET_TAG = -1;
|
||||
const long EVP_CTRL_GCM_SET_TAG = -1;
|
||||
const long EVP_CTRL_GCM_SET_IVLEN = -1;
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
const long Cryptography_HAS_PBKDF2_HMAC = 1;
|
||||
const long Cryptography_HAS_PKEY_CTX = 1;
|
||||
|
||||
/* OpenSSL 0.9.8 defines EVP_PKEY_encrypt and EVP_PKEY_decrypt functions,
|
||||
but they are a completely different signature from the ones in 1.0.0+.
|
||||
These wrapper functions allows us to safely declare them on any version and
|
||||
conditionally remove them on 0.9.8. */
|
||||
int Cryptography_EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
|
||||
size_t *outlen, const unsigned char *in,
|
||||
size_t inlen) {
|
||||
return EVP_PKEY_encrypt(ctx, out, outlen, in, inlen);
|
||||
}
|
||||
int Cryptography_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
|
||||
size_t *outlen, const unsigned char *in,
|
||||
size_t inlen) {
|
||||
return EVP_PKEY_decrypt(ctx, out, outlen, in, inlen);
|
||||
}
|
||||
#else
|
||||
const long Cryptography_HAS_PBKDF2_HMAC = 0;
|
||||
int (*PKCS5_PBKDF2_HMAC)(const char *, int, const unsigned char *, int, int,
|
||||
const EVP_MD *, int, unsigned char *) = NULL;
|
||||
const long Cryptography_HAS_PKEY_CTX = 0;
|
||||
typedef void EVP_PKEY_CTX;
|
||||
int (*EVP_PKEY_CTX_set_signature_md)(EVP_PKEY_CTX *, const EVP_MD *) = NULL;
|
||||
int (*EVP_PKEY_sign_init)(EVP_PKEY_CTX *) = NULL;
|
||||
int (*EVP_PKEY_sign)(EVP_PKEY_CTX *, unsigned char *, size_t *,
|
||||
const unsigned char *, size_t) = NULL;
|
||||
int (*EVP_PKEY_verify_init)(EVP_PKEY_CTX *) = NULL;
|
||||
int (*EVP_PKEY_verify)(EVP_PKEY_CTX *, const unsigned char *, size_t,
|
||||
const unsigned char *, size_t) = NULL;
|
||||
EVP_PKEY_CTX *(*EVP_PKEY_CTX_new)(EVP_PKEY *, ENGINE *) = NULL;
|
||||
EVP_PKEY_CTX *(*EVP_PKEY_CTX_new_id)(int, ENGINE *) = NULL;
|
||||
EVP_PKEY_CTX *(*EVP_PKEY_CTX_dup)(EVP_PKEY_CTX *) = NULL;
|
||||
void (*EVP_PKEY_CTX_free)(EVP_PKEY_CTX *) = NULL;
|
||||
int (*EVP_PKEY_encrypt_init)(EVP_PKEY_CTX *) = NULL;
|
||||
int (*EVP_PKEY_decrypt_init)(EVP_PKEY_CTX *) = NULL;
|
||||
int (*Cryptography_EVP_PKEY_encrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *,
|
||||
const unsigned char *, size_t) = NULL;
|
||||
int (*Cryptography_EVP_PKEY_decrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *,
|
||||
const unsigned char *, size_t) = NULL;
|
||||
#endif
|
||||
#ifdef OPENSSL_NO_EC
|
||||
int (*EVP_PKEY_assign_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL;
|
||||
EC_KEY *(*EVP_PKEY_get1_EC_KEY)(EVP_PKEY *) = NULL;
|
||||
int (*EVP_PKEY_set1_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL;
|
||||
#endif
|
||||
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {
|
||||
"Cryptography_HAS_GCM": [
|
||||
"EVP_CTRL_GCM_GET_TAG",
|
||||
"EVP_CTRL_GCM_SET_TAG",
|
||||
"EVP_CTRL_GCM_SET_IVLEN",
|
||||
],
|
||||
"Cryptography_HAS_PBKDF2_HMAC": [
|
||||
"PKCS5_PBKDF2_HMAC"
|
||||
],
|
||||
"Cryptography_HAS_PKEY_CTX": [
|
||||
"EVP_PKEY_CTX_new",
|
||||
"EVP_PKEY_CTX_new_id",
|
||||
"EVP_PKEY_CTX_dup",
|
||||
"EVP_PKEY_CTX_free",
|
||||
"EVP_PKEY_sign",
|
||||
"EVP_PKEY_sign_init",
|
||||
"EVP_PKEY_verify",
|
||||
"EVP_PKEY_verify_init",
|
||||
"Cryptography_EVP_PKEY_encrypt",
|
||||
"EVP_PKEY_encrypt_init",
|
||||
"Cryptography_EVP_PKEY_decrypt",
|
||||
"EVP_PKEY_decrypt_init",
|
||||
"EVP_PKEY_CTX_set_signature_md",
|
||||
],
|
||||
"Cryptography_HAS_EC": [
|
||||
"EVP_PKEY_assign_EC_KEY",
|
||||
"EVP_PKEY_get1_EC_KEY",
|
||||
"EVP_PKEY_set1_EC_KEY",
|
||||
]
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/hmac.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
typedef struct { ...; } HMAC_CTX;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
void HMAC_CTX_init(HMAC_CTX *);
|
||||
void HMAC_CTX_cleanup(HMAC_CTX *);
|
||||
|
||||
int Cryptography_HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *,
|
||||
ENGINE *);
|
||||
int Cryptography_HMAC_Update(HMAC_CTX *, const unsigned char *, size_t);
|
||||
int Cryptography_HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *);
|
||||
int Cryptography_HMAC_CTX_copy(HMAC_CTX *, HMAC_CTX *);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
int Cryptography_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len,
|
||||
const EVP_MD *md, ENGINE *impl) {
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010000000
|
||||
return HMAC_Init_ex(ctx, key, key_len, md, impl);
|
||||
#else
|
||||
HMAC_Init_ex(ctx, key, key_len, md, impl);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int Cryptography_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data,
|
||||
size_t data_len) {
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010000000
|
||||
return HMAC_Update(ctx, data, data_len);
|
||||
#else
|
||||
HMAC_Update(ctx, data, data_len);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int Cryptography_HMAC_Final(HMAC_CTX *ctx, unsigned char *digest,
|
||||
unsigned int *outlen) {
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010000000
|
||||
return HMAC_Final(ctx, digest, outlen);
|
||||
#else
|
||||
HMAC_Final(ctx, digest, outlen);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int Cryptography_HMAC_CTX_copy(HMAC_CTX *dst_ctx, HMAC_CTX *src_ctx) {
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x010000000
|
||||
return HMAC_CTX_copy(dst_ctx, src_ctx);
|
||||
#else
|
||||
HMAC_CTX_init(dst_ctx);
|
||||
if (!EVP_MD_CTX_copy_ex(&dst_ctx->i_ctx, &src_ctx->i_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_MD_CTX_copy_ex(&dst_ctx->o_ctx, &src_ctx->o_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_MD_CTX_copy_ex(&dst_ctx->md_ctx, &src_ctx->md_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
memcpy(dst_ctx->key, src_ctx->key, HMAC_MAX_MD_CBLOCK);
|
||||
dst_ctx->key_length = src_ctx->key_length;
|
||||
dst_ctx->md = src_ctx->md;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,216 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = ""
|
||||
|
||||
TYPES = """
|
||||
static const int Cryptography_HAS_ECDSA_SHA2_NIDS;
|
||||
|
||||
static const int NID_undef;
|
||||
static const int NID_dsa;
|
||||
static const int NID_dsaWithSHA;
|
||||
static const int NID_dsaWithSHA1;
|
||||
static const int NID_md2;
|
||||
static const int NID_md4;
|
||||
static const int NID_md5;
|
||||
static const int NID_mdc2;
|
||||
static const int NID_ripemd160;
|
||||
static const int NID_sha;
|
||||
static const int NID_sha1;
|
||||
static const int NID_sha256;
|
||||
static const int NID_sha384;
|
||||
static const int NID_sha512;
|
||||
static const int NID_sha224;
|
||||
static const int NID_sha;
|
||||
static const int NID_ecdsa_with_SHA1;
|
||||
static const int NID_ecdsa_with_SHA224;
|
||||
static const int NID_ecdsa_with_SHA256;
|
||||
static const int NID_ecdsa_with_SHA384;
|
||||
static const int NID_ecdsa_with_SHA512;
|
||||
static const int NID_crl_reason;
|
||||
static const int NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
|
||||
static const int NID_subject_alt_name;
|
||||
static const int NID_issuer_alt_name;
|
||||
static const int NID_X9_62_c2pnb163v1;
|
||||
static const int NID_X9_62_c2pnb163v2;
|
||||
static const int NID_X9_62_c2pnb163v3;
|
||||
static const int NID_X9_62_c2pnb176v1;
|
||||
static const int NID_X9_62_c2tnb191v1;
|
||||
static const int NID_X9_62_c2tnb191v2;
|
||||
static const int NID_X9_62_c2tnb191v3;
|
||||
static const int NID_X9_62_c2onb191v4;
|
||||
static const int NID_X9_62_c2onb191v5;
|
||||
static const int NID_X9_62_c2pnb208w1;
|
||||
static const int NID_X9_62_c2tnb239v1;
|
||||
static const int NID_X9_62_c2tnb239v2;
|
||||
static const int NID_X9_62_c2tnb239v3;
|
||||
static const int NID_X9_62_c2onb239v4;
|
||||
static const int NID_X9_62_c2onb239v5;
|
||||
static const int NID_X9_62_c2pnb272w1;
|
||||
static const int NID_X9_62_c2pnb304w1;
|
||||
static const int NID_X9_62_c2tnb359v1;
|
||||
static const int NID_X9_62_c2pnb368w1;
|
||||
static const int NID_X9_62_c2tnb431r1;
|
||||
static const int NID_X9_62_prime192v1;
|
||||
static const int NID_X9_62_prime192v2;
|
||||
static const int NID_X9_62_prime192v3;
|
||||
static const int NID_X9_62_prime239v1;
|
||||
static const int NID_X9_62_prime239v2;
|
||||
static const int NID_X9_62_prime239v3;
|
||||
static const int NID_X9_62_prime256v1;
|
||||
static const int NID_secp112r1;
|
||||
static const int NID_secp112r2;
|
||||
static const int NID_secp128r1;
|
||||
static const int NID_secp128r2;
|
||||
static const int NID_secp160k1;
|
||||
static const int NID_secp160r1;
|
||||
static const int NID_secp160r2;
|
||||
static const int NID_sect163k1;
|
||||
static const int NID_sect163r1;
|
||||
static const int NID_sect163r2;
|
||||
static const int NID_secp192k1;
|
||||
static const int NID_secp224k1;
|
||||
static const int NID_secp224r1;
|
||||
static const int NID_secp256k1;
|
||||
static const int NID_secp384r1;
|
||||
static const int NID_secp521r1;
|
||||
static const int NID_sect113r1;
|
||||
static const int NID_sect113r2;
|
||||
static const int NID_sect131r1;
|
||||
static const int NID_sect131r2;
|
||||
static const int NID_sect193r1;
|
||||
static const int NID_sect193r2;
|
||||
static const int NID_sect233k1;
|
||||
static const int NID_sect233r1;
|
||||
static const int NID_sect239k1;
|
||||
static const int NID_sect283k1;
|
||||
static const int NID_sect283r1;
|
||||
static const int NID_sect409k1;
|
||||
static const int NID_sect409r1;
|
||||
static const int NID_sect571k1;
|
||||
static const int NID_sect571r1;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls1;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls3;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls4;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls5;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls6;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls7;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls8;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls9;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls10;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls11;
|
||||
static const int NID_wap_wsg_idm_ecid_wtls12;
|
||||
static const int NID_ipsec3;
|
||||
static const int NID_ipsec4;
|
||||
static const char *const SN_X9_62_c2pnb163v1;
|
||||
static const char *const SN_X9_62_c2pnb163v2;
|
||||
static const char *const SN_X9_62_c2pnb163v3;
|
||||
static const char *const SN_X9_62_c2pnb176v1;
|
||||
static const char *const SN_X9_62_c2tnb191v1;
|
||||
static const char *const SN_X9_62_c2tnb191v2;
|
||||
static const char *const SN_X9_62_c2tnb191v3;
|
||||
static const char *const SN_X9_62_c2onb191v4;
|
||||
static const char *const SN_X9_62_c2onb191v5;
|
||||
static const char *const SN_X9_62_c2pnb208w1;
|
||||
static const char *const SN_X9_62_c2tnb239v1;
|
||||
static const char *const SN_X9_62_c2tnb239v2;
|
||||
static const char *const SN_X9_62_c2tnb239v3;
|
||||
static const char *const SN_X9_62_c2onb239v4;
|
||||
static const char *const SN_X9_62_c2onb239v5;
|
||||
static const char *const SN_X9_62_c2pnb272w1;
|
||||
static const char *const SN_X9_62_c2pnb304w1;
|
||||
static const char *const SN_X9_62_c2tnb359v1;
|
||||
static const char *const SN_X9_62_c2pnb368w1;
|
||||
static const char *const SN_X9_62_c2tnb431r1;
|
||||
static const char *const SN_X9_62_prime192v1;
|
||||
static const char *const SN_X9_62_prime192v2;
|
||||
static const char *const SN_X9_62_prime192v3;
|
||||
static const char *const SN_X9_62_prime239v1;
|
||||
static const char *const SN_X9_62_prime239v2;
|
||||
static const char *const SN_X9_62_prime239v3;
|
||||
static const char *const SN_X9_62_prime256v1;
|
||||
static const char *const SN_secp112r1;
|
||||
static const char *const SN_secp112r2;
|
||||
static const char *const SN_secp128r1;
|
||||
static const char *const SN_secp128r2;
|
||||
static const char *const SN_secp160k1;
|
||||
static const char *const SN_secp160r1;
|
||||
static const char *const SN_secp160r2;
|
||||
static const char *const SN_sect163k1;
|
||||
static const char *const SN_sect163r1;
|
||||
static const char *const SN_sect163r2;
|
||||
static const char *const SN_secp192k1;
|
||||
static const char *const SN_secp224k1;
|
||||
static const char *const SN_secp224r1;
|
||||
static const char *const SN_secp256k1;
|
||||
static const char *const SN_secp384r1;
|
||||
static const char *const SN_secp521r1;
|
||||
static const char *const SN_sect113r1;
|
||||
static const char *const SN_sect113r2;
|
||||
static const char *const SN_sect131r1;
|
||||
static const char *const SN_sect131r2;
|
||||
static const char *const SN_sect193r1;
|
||||
static const char *const SN_sect193r2;
|
||||
static const char *const SN_sect233k1;
|
||||
static const char *const SN_sect233r1;
|
||||
static const char *const SN_sect239k1;
|
||||
static const char *const SN_sect283k1;
|
||||
static const char *const SN_sect283r1;
|
||||
static const char *const SN_sect409k1;
|
||||
static const char *const SN_sect409r1;
|
||||
static const char *const SN_sect571k1;
|
||||
static const char *const SN_sect571r1;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls1;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls3;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls4;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls5;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls6;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls7;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls8;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls9;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls10;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls11;
|
||||
static const char *const SN_wap_wsg_idm_ecid_wtls12;
|
||||
static const char *const SN_ipsec3;
|
||||
static const char *const SN_ipsec4;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
/* OpenSSL 0.9.8g+ */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090807fL
|
||||
static const long Cryptography_HAS_ECDSA_SHA2_NIDS = 1;
|
||||
#else
|
||||
static const long Cryptography_HAS_ECDSA_SHA2_NIDS = 0;
|
||||
static const int NID_ecdsa_with_SHA224 = 0;
|
||||
static const int NID_ecdsa_with_SHA256 = 0;
|
||||
static const int NID_ecdsa_with_SHA384 = 0;
|
||||
static const int NID_ecdsa_with_SHA512 = 0;
|
||||
#endif
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {
|
||||
"Cryptography_HAS_ECDSA_SHA2_NIDS": [
|
||||
"NID_ecdsa_with_SHA224",
|
||||
"NID_ecdsa_with_SHA256",
|
||||
"NID_ecdsa_with_SHA384",
|
||||
"NID_ecdsa_with_SHA512",
|
||||
],
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/objects.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
ASN1_OBJECT *OBJ_nid2obj(int);
|
||||
const char *OBJ_nid2ln(int);
|
||||
const char *OBJ_nid2sn(int);
|
||||
int OBJ_obj2nid(const ASN1_OBJECT *);
|
||||
int OBJ_ln2nid(const char *);
|
||||
int OBJ_sn2nid(const char *);
|
||||
int OBJ_txt2nid(const char *);
|
||||
ASN1_OBJECT *OBJ_txt2obj(const char *, int);
|
||||
int OBJ_obj2txt(char *, int, const ASN1_OBJECT *, int);
|
||||
int OBJ_cmp(const ASN1_OBJECT *, const ASN1_OBJECT *);
|
||||
ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *);
|
||||
int OBJ_create(const char *, const char *, const char *);
|
||||
void OBJ_cleanup(void);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,36 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#include <openssl/opensslv.h>
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
/* Note that these will be resolved when cryptography is compiled and are NOT
|
||||
guaranteed to be the version that it actually loads. */
|
||||
static const int OPENSSL_VERSION_NUMBER;
|
||||
static const char *const OPENSSL_VERSION_TEXT;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
"""
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
|
@ -1,218 +0,0 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
INCLUDES = """
|
||||
#ifdef _WIN32
|
||||
#include <Wincrypt.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
"""
|
||||
|
||||
TYPES = """
|
||||
static const char *const Cryptography_osrandom_engine_name;
|
||||
static const char *const Cryptography_osrandom_engine_id;
|
||||
"""
|
||||
|
||||
FUNCTIONS = """
|
||||
int Cryptography_add_osrandom_engine(void);
|
||||
"""
|
||||
|
||||
MACROS = """
|
||||
"""
|
||||
|
||||
WIN32_CUSTOMIZATIONS = """
|
||||
static HCRYPTPROV hCryptProv = 0;
|
||||
|
||||
static int osrandom_init(ENGINE *e) {
|
||||
if (hCryptProv > 0) {
|
||||
return 1;
|
||||
}
|
||||
if (CryptAcquireContext(&hCryptProv, NULL, NULL,
|
||||
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int osrandom_rand_bytes(unsigned char *buffer, int size) {
|
||||
if (hCryptProv == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CryptGenRandom(hCryptProv, (DWORD)size, buffer)) {
|
||||
ERR_put_error(
|
||||
ERR_LIB_RAND, 0, ERR_R_RAND_LIB, "osrandom_engine.py", 0
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int osrandom_finish(ENGINE *e) {
|
||||
if (CryptReleaseContext(hCryptProv, 0)) {
|
||||
hCryptProv = 0;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int osrandom_rand_status(void) {
|
||||
if (hCryptProv == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
POSIX_CUSTOMIZATIONS = """
|
||||
static int urandom_fd = -1;
|
||||
|
||||
static int osrandom_finish(ENGINE *e);
|
||||
|
||||
static int osrandom_init(ENGINE *e) {
|
||||
if (urandom_fd > -1) {
|
||||
return 1;
|
||||
}
|
||||
urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||
if (urandom_fd > -1) {
|
||||
int flags = fcntl(urandom_fd, F_GETFD);
|
||||
if (flags == -1) {
|
||||
osrandom_finish(e);
|
||||
return 0;
|
||||
} else if (fcntl(urandom_fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
|
||||
osrandom_finish(e);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int osrandom_rand_bytes(unsigned char *buffer, int size) {
|
||||
ssize_t n;
|
||||
while (size > 0) {
|
||||
do {
|
||||
n = read(urandom_fd, buffer, (size_t)size);
|
||||
} while (n < 0 && errno == EINTR);
|
||||
if (n <= 0) {
|
||||
ERR_put_error(
|
||||
ERR_LIB_RAND, 0, ERR_R_RAND_LIB, "osrandom_engine.py", 0
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
buffer += n;
|
||||
size -= n;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int osrandom_finish(ENGINE *e) {
|
||||
int n;
|
||||
do {
|
||||
n = close(urandom_fd);
|
||||
} while (n < 0 && errno == EINTR);
|
||||
urandom_fd = -1;
|
||||
if (n < 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int osrandom_rand_status(void) {
|
||||
if (urandom_fd == -1) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
CUSTOMIZATIONS = """
|
||||
static const char *Cryptography_osrandom_engine_id = "osrandom";
|
||||
static const char *Cryptography_osrandom_engine_name = "osrandom_engine";
|
||||
|
||||
#if defined(_WIN32)
|
||||
%(WIN32_CUSTOMIZATIONS)s
|
||||
#else
|
||||
%(POSIX_CUSTOMIZATIONS)s
|
||||
#endif
|
||||
|
||||
/* This replicates the behavior of the OpenSSL FIPS RNG, which returns a
|
||||
-1 in the event that there is an error when calling RAND_pseudo_bytes. */
|
||||
static int osrandom_pseudo_rand_bytes(unsigned char *buffer, int size) {
|
||||
int res = osrandom_rand_bytes(buffer, size);
|
||||
if (res == 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
static RAND_METHOD osrandom_rand = {
|
||||
NULL,
|
||||
osrandom_rand_bytes,
|
||||
NULL,
|
||||
NULL,
|
||||
osrandom_pseudo_rand_bytes,
|
||||
osrandom_rand_status,
|
||||
};
|
||||
|
||||
/* Returns 1 if successfully added, 2 if engine has previously been added,
|
||||
and 0 for error. */
|
||||
int Cryptography_add_osrandom_engine(void) {
|
||||
ENGINE *e;
|
||||
e = ENGINE_by_id(Cryptography_osrandom_engine_id);
|
||||
if (e != NULL) {
|
||||
ENGINE_free(e);
|
||||
return 2;
|
||||
} else {
|
||||
ERR_clear_error();
|
||||
}
|
||||
|
||||
e = ENGINE_new();
|
||||
if (e == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if(!ENGINE_set_id(e, Cryptography_osrandom_engine_id) ||
|
||||
!ENGINE_set_name(e, Cryptography_osrandom_engine_name) ||
|
||||
!ENGINE_set_RAND(e, &osrandom_rand) ||
|
||||
!ENGINE_set_init_function(e, osrandom_init) ||
|
||||
!ENGINE_set_finish_function(e, osrandom_finish)) {
|
||||
ENGINE_free(e);
|
||||
return 0;
|
||||
}
|
||||
if (!ENGINE_add(e)) {
|
||||
ENGINE_free(e);
|
||||
return 0;
|
||||
}
|
||||
if (!ENGINE_free(e)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
""" % {
|
||||
"WIN32_CUSTOMIZATIONS": WIN32_CUSTOMIZATIONS,
|
||||
"POSIX_CUSTOMIZATIONS": POSIX_CUSTOMIZATIONS,
|
||||
}
|
||||
|
||||
CONDITIONAL_NAMES = {}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue