add 64/32bit linux split

This commit is contained in:
j 2014-05-17 20:03:47 +02:00
commit 75f9a2fcbc
1825 changed files with 1 additions and 0 deletions

View file

@ -0,0 +1,31 @@
# 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.4"
__author__ = "The cryptography developers"
__email__ = "cryptography-dev@python.org"
__license__ = "Apache License, Version 2.0"
__copyright__ = "Copyright 2013-2014 %s" % __author__

View file

@ -0,0 +1,25 @@
# 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__",
]

View file

@ -0,0 +1,61 @@
# 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()
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

View file

@ -0,0 +1,133 @@
# 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 isinstance(data, six.text_type):
raise TypeError(
"Unicode-objects must be encoded before encryption"
)
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 isinstance(token, six.text_type):
raise TypeError(
"Unicode-objects must be encoded before decryption"
)
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

View file

@ -0,0 +1,14 @@
# 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

View file

@ -0,0 +1,54 @@
# 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.multibackend import MultiBackend
from cryptography.hazmat.bindings.commoncrypto.binding import (
Binding as CommonCryptoBinding
)
from cryptography.hazmat.bindings.openssl.binding import (
Binding as OpenSSLBinding
)
_available_backends_list = None
def _available_backends():
global _available_backends_list
if _available_backends_list is None:
_available_backends_list = []
if CommonCryptoBinding.is_available():
from cryptography.hazmat.backends import commoncrypto
_available_backends_list.append(commoncrypto.backend)
if OpenSSLBinding.is_available():
from cryptography.hazmat.backends import openssl
_available_backends_list.append(openssl.backend)
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

View file

@ -0,0 +1,19 @@
# 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"]

View file

@ -0,0 +1,499 @@
# 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, InvalidTag, UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.interfaces import (
CipherBackend, HMACBackend, HashBackend, PBKDF2HMACBackend
)
from cryptography.hazmat.bindings.commoncrypto.binding import Binding
from cryptography.hazmat.primitives import constant_time, interfaces
from cryptography.hazmat.primitives.ciphers.algorithms import (
AES, ARC4, Blowfish, CAST5, TripleDES
)
from cryptography.hazmat.primitives.ciphers.modes import (
CBC, CFB, 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_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),
(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),
(CFB, self._lib.kCCModeCFB),
(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_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(ctx):
"""
Called by the garbage collector and used to safely dereference and
release the context.
"""
if ctx[0] != backend._ffi.NULL:
res = backend._lib.CCCryptorRelease(ctx[0])
backend._check_response(res)
ctx[0] = backend._ffi.NULL
@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, 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, _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_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_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_response(res)
_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, _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_response(res)
res = self._backend._lib.CCCryptorGCMAddIV(
self._ctx[0],
mode.initialization_vector,
len(mode.initialization_vector)
)
self._backend._check_response(res)
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_response(res)
return self._backend._ffi.buffer(buf)[:]
def finalize(self):
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 = backend._lib.CCCryptorGCMFinal(self._ctx[0], tag_buf, tag_len)
self._backend._check_response(res)
_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_response(res)
@property
def tag(self):
return self._tag
@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)[:]
@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)[:]
backend = Backend()

View file

@ -0,0 +1,197 @@
# 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 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.
"""
@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 an DSAPrivateKey instance with parameters as
a DSAParameters object.
"""
@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.
"""
@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 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.
"""

View file

@ -0,0 +1,199 @@
# 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.backends.interfaces import (
CMACBackend, CipherBackend, DSABackend, HMACBackend, HashBackend,
PBKDF2HMACBackend, RSABackend
)
@utils.register_interface(CMACBackend)
@utils.register_interface(CipherBackend)
@utils.register_interface(HashBackend)
@utils.register_interface(HMACBackend)
@utils.register_interface(PBKDF2HMACBackend)
@utils.register_interface(RSABackend)
@utils.register_interface(DSABackend)
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 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 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 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 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)

View file

@ -0,0 +1,19 @@
# 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"]

View file

@ -0,0 +1,14 @@
# 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

View file

@ -0,0 +1,14 @@
# 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

View file

@ -0,0 +1,53 @@
# 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 platform
import sys
from cryptography.hazmat.bindings.utils import build_ffi
class Binding(object):
"""
CommonCrypto API wrapper.
"""
_module_prefix = "cryptography.hazmat.bindings.commoncrypto."
_modules = [
"common_digest",
"common_hmac",
"common_key_derivation",
"common_cryptor",
]
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,
)
@classmethod
def is_available(cls):
return sys.platform == "darwin" and list(map(
int, platform.mac_ver()[0].split("."))) >= [10, 8, 0]

View file

@ -0,0 +1,110 @@
# 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 = {}

View file

@ -0,0 +1,69 @@
# 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 = {}

View file

@ -0,0 +1,48 @@
# 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 = {}

View file

@ -0,0 +1,50 @@
# 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 = {}

View file

@ -0,0 +1,14 @@
# 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

View file

@ -0,0 +1,62 @@
# 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);
"""
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",
],
}

View file

@ -0,0 +1,149 @@
# 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 *);
"""
CUSTOMIZATIONS = """
"""
CONDITIONAL_NAMES = {}

View file

@ -0,0 +1,114 @@
# 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 = {}

View file

@ -0,0 +1,155 @@
# 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 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",
]
_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":
libraries = ["crypto", "ssl"]
else: # pragma: no cover
libraries = ["libeay32", "ssleay32", "advapi32"]
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 is_available(cls):
# For now, OpenSSL is considered our "default" binding, so we treat it
# as always available.
return True
@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
)
)

View file

@ -0,0 +1,181 @@
# 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 = {}

View file

@ -0,0 +1,65 @@
# 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",
],
}

View file

@ -0,0 +1,100 @@
# 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",
]
}

View file

@ -0,0 +1,33 @@
# 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 = """
"""
MACROS = """
"""
CUSTOMIZATIONS = """
"""
CONDITIONAL_NAMES = {}

View file

@ -0,0 +1,67 @@
# 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 = {}

View file

@ -0,0 +1,57 @@
# 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 = {}

View file

@ -0,0 +1,65 @@
# 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;
// 160-bit subprime, 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 = {}

View file

@ -0,0 +1,479 @@
# 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;
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 *);
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;
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 *);
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": [
"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_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",
],
}

View file

@ -0,0 +1,68 @@
# 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",
],
}

View file

@ -0,0 +1,130 @@
# 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",
],
}

View file

@ -0,0 +1,165 @@
# 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 = {}

View file

@ -0,0 +1,328 @@
# 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;
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_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_WRONG_FINAL_BLOCK_LENGTH;
static const int EVP_R_WRONG_PUBLIC_KEY_TYPE;
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
"""
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"
]
}

View file

@ -0,0 +1,260 @@
# 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 *);
// not macros but must be in this section since 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",
]
}

View file

@ -0,0 +1,94 @@
# 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 = {}

View file

@ -0,0 +1,215 @@
# 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_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",
],
}

View file

@ -0,0 +1,45 @@
# 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 = {}

View file

@ -0,0 +1,34 @@
# 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 = """
static const int OPENSSL_VERSION_NUMBER;
static const char *const OPENSSL_VERSION_TEXT;
"""
FUNCTIONS = """
"""
MACROS = """
"""
CUSTOMIZATIONS = """
"""
CONDITIONAL_NAMES = {}

View file

@ -0,0 +1,218 @@
# 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 = {}

View file

@ -0,0 +1,88 @@
# 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/pem.h>
"""
TYPES = """
typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
"""
FUNCTIONS = """
X509 *PEM_read_bio_X509(BIO *, X509 **, pem_password_cb *, void *);
int PEM_write_bio_X509(BIO *, X509 *);
int PEM_write_bio_PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
unsigned char *, int, pem_password_cb *, void *);
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *, EVP_PKEY **, pem_password_cb *,
void *);
int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
char *, int, pem_password_cb *, void *);
int PEM_write_bio_PKCS8PrivateKey_nid(BIO *, EVP_PKEY *, int, char *, int,
pem_password_cb *, void *);
int i2d_PKCS8PrivateKey_bio(BIO *, EVP_PKEY *, const EVP_CIPHER *,
char *, int, pem_password_cb *, void *);
int i2d_PKCS8PrivateKey_nid_bio(BIO *, EVP_PKEY *, int,
char *, int, pem_password_cb *, void *);
EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *, EVP_PKEY **, pem_password_cb *,
void *);
int PEM_write_bio_X509_REQ(BIO *, X509_REQ *);
X509_REQ *PEM_read_bio_X509_REQ(BIO *, X509_REQ **, pem_password_cb *, void *);
X509_CRL *PEM_read_bio_X509_CRL(BIO *, X509_CRL **, pem_password_cb *, void *);
int PEM_write_bio_X509_CRL(BIO *, X509_CRL *);
PKCS7 *PEM_read_bio_PKCS7(BIO *, PKCS7 **, pem_password_cb *, void *);
DH *PEM_read_bio_DHparams(BIO *, DH **, pem_password_cb *, void *);
DSA *PEM_read_bio_DSAPrivateKey(BIO *, DSA **, pem_password_cb *, void *);
RSA *PEM_read_bio_RSAPrivateKey(BIO *, RSA **, pem_password_cb *, void *);
int PEM_write_bio_DSAPrivateKey(BIO *, DSA *, const EVP_CIPHER *,
unsigned char *, int,
pem_password_cb *, void *);
int PEM_write_bio_RSAPrivateKey(BIO *, RSA *, const EVP_CIPHER *,
unsigned char *, int,
pem_password_cb *, void *);
DSA *PEM_read_bio_DSA_PUBKEY(BIO *, DSA **, pem_password_cb *, void *);
RSA *PEM_read_bio_RSAPublicKey(BIO *, RSA **, pem_password_cb *, void *);
int PEM_write_bio_DSA_PUBKEY(BIO *, DSA *);
int PEM_write_bio_RSAPublicKey(BIO *, const RSA *);
EVP_PKEY *PEM_read_bio_PUBKEY(BIO *, EVP_PKEY **, pem_password_cb *, void *);
int PEM_write_bio_PUBKEY(BIO *, EVP_PKEY *);
"""
MACROS = """
"""
CUSTOMIZATIONS = """
"""
CONDITIONAL_NAMES = {}

View file

@ -0,0 +1,41 @@
# 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/pkcs12.h>
"""
TYPES = """
typedef ... PKCS12;
"""
FUNCTIONS = """
void PKCS12_free(PKCS12 *);
PKCS12 *d2i_PKCS12_bio(BIO *, PKCS12 **);
int i2d_PKCS12_bio(BIO *, PKCS12 *);
"""
MACROS = """
int PKCS12_parse(PKCS12 *, const char *, EVP_PKEY **, X509 **,
Cryptography_STACK_OF_X509 **);
PKCS12 *PKCS12_create(char *, char *, EVP_PKEY *, X509 *,
Cryptography_STACK_OF_X509 *, int, int, int, int, int);
"""
CUSTOMIZATIONS = """
"""
CONDITIONAL_NAMES = {}

View file

@ -0,0 +1,41 @@
# 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/pkcs7.h>
"""
TYPES = """
typedef struct {
ASN1_OBJECT *type;
...;
} PKCS7;
"""
FUNCTIONS = """
void PKCS7_free(PKCS7 *);
"""
MACROS = """
int PKCS7_type_is_signed(PKCS7 *);
int PKCS7_type_is_enveloped(PKCS7 *);
int PKCS7_type_is_signedAndEnveloped(PKCS7 *);
int PKCS7_type_is_data(PKCS7 *);
"""
CUSTOMIZATIONS = """
"""
CONDITIONAL_NAMES = {}

View file

@ -0,0 +1,45 @@
# 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/rand.h>
"""
TYPES = """
"""
FUNCTIONS = """
void ERR_load_RAND_strings(void);
void RAND_seed(const void *, int);
void RAND_add(const void *, int, double);
int RAND_status(void);
int RAND_egd(const char *);
int RAND_egd_bytes(const char *, int);
int RAND_query_egd_bytes(const char *, unsigned char *, int);
const char *RAND_file_name(char *, size_t);
int RAND_load_file(const char *, long);
int RAND_write_file(const char *);
void RAND_cleanup(void);
int RAND_bytes(unsigned char *, int);
int RAND_pseudo_bytes(unsigned char *, int);
"""
MACROS = """
"""
CUSTOMIZATIONS = """
"""
CONDITIONAL_NAMES = {}

View file

@ -0,0 +1,108 @@
# 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/rsa.h>
"""
TYPES = """
typedef struct rsa_st {
BIGNUM *n;
BIGNUM *e;
BIGNUM *d;
BIGNUM *p;
BIGNUM *q;
BIGNUM *dmp1;
BIGNUM *dmq1;
BIGNUM *iqmp;
...;
} RSA;
typedef ... BN_GENCB;
static const int RSA_PKCS1_PADDING;
static const int RSA_SSLV23_PADDING;
static const int RSA_NO_PADDING;
static const int RSA_PKCS1_OAEP_PADDING;
static const int RSA_X931_PADDING;
static const int RSA_PKCS1_PSS_PADDING;
static const int RSA_F4;
static const int Cryptography_HAS_PSS_PADDING;
static const int Cryptography_HAS_MGF1_MD;
"""
FUNCTIONS = """
RSA *RSA_new(void);
void RSA_free(RSA *);
int RSA_size(const RSA *);
int RSA_generate_key_ex(RSA *, int, BIGNUM *, BN_GENCB *);
int RSA_check_key(const RSA *);
RSA *RSAPublicKey_dup(RSA *);
int RSA_blinding_on(RSA *, BN_CTX *);
void RSA_blinding_off(RSA *);
int RSA_public_encrypt(int, const unsigned char *, unsigned char *,
RSA *, int);
int RSA_private_encrypt(int, const unsigned char *, unsigned char *,
RSA *, int);
int RSA_public_decrypt(int, const unsigned char *, unsigned char *,
RSA *, int);
int RSA_private_decrypt(int, const unsigned char *, unsigned char *,
RSA *, int);
int RSA_print(BIO *, const RSA *, int);
int RSA_verify_PKCS1_PSS(RSA *, const unsigned char *, const EVP_MD *,
const unsigned char *, int);
int RSA_padding_add_PKCS1_PSS(RSA *, unsigned char *, const unsigned char *,
const EVP_MD *, int);
int RSA_padding_add_PKCS1_OAEP(unsigned char *, int, const unsigned char *,
int, const unsigned char *, int);
int RSA_padding_check_PKCS1_OAEP(unsigned char *, int, const unsigned char *,
int, int, const unsigned char *, int);
"""
MACROS = """
int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *, int);
int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *, int);
int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *, EVP_MD *);
"""
CUSTOMIZATIONS = """
#if OPENSSL_VERSION_NUMBER >= 0x10000000
static const long Cryptography_HAS_PSS_PADDING = 1;
#else
// see evp.py for the definition of Cryptography_HAS_PKEY_CTX
static const long Cryptography_HAS_PSS_PADDING = 0;
int (*EVP_PKEY_CTX_set_rsa_padding)(EVP_PKEY_CTX *, int) = NULL;
int (*EVP_PKEY_CTX_set_rsa_pss_saltlen)(EVP_PKEY_CTX *, int) = NULL;
static const long RSA_PKCS1_PSS_PADDING = 0;
#endif
#if OPENSSL_VERSION_NUMBER >= 0x1000100f
static const long Cryptography_HAS_MGF1_MD = 1;
#else
static const long Cryptography_HAS_MGF1_MD = 0;
int (*EVP_PKEY_CTX_set_rsa_mgf1_md)(EVP_PKEY_CTX *, EVP_MD *) = NULL;
#endif
"""
CONDITIONAL_NAMES = {
"Cryptography_HAS_PKEY_CTX": [
"EVP_PKEY_CTX_set_rsa_padding",
"EVP_PKEY_CTX_set_rsa_pss_saltlen",
],
"Cryptography_HAS_PSS_PADDING": [
"RSA_PKCS1_PSS_PADDING",
],
"Cryptography_HAS_MGF1_MD": [
"EVP_PKEY_CTX_set_rsa_mgf1_md",
],
}

View file

@ -0,0 +1,555 @@
# 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/ssl.h>
"""
TYPES = """
/*
* Internally invented symbols to tell which versions of SSL/TLS are supported.
*/
static const long Cryptography_HAS_SSL2;
static const long Cryptography_HAS_TLSv1_1;
static const long Cryptography_HAS_TLSv1_2;
/* Internally invented symbol to tell us if SNI is supported */
static const long Cryptography_HAS_TLSEXT_HOSTNAME;
/* Internally invented symbol to tell us if SSL_MODE_RELEASE_BUFFERS is
* supported
*/
static const long Cryptography_HAS_RELEASE_BUFFERS;
/* Internally invented symbol to tell us if SSL_OP_NO_COMPRESSION is
* supported
*/
static const long Cryptography_HAS_OP_NO_COMPRESSION;
static const long Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING;
static const long Cryptography_HAS_SSL_SET_SSL_CTX;
static const long Cryptography_HAS_SSL_OP_NO_TICKET;
static const long Cryptography_HAS_NETBSD_D1_METH;
static const long Cryptography_HAS_NEXTPROTONEG;
static const long SSL_FILETYPE_PEM;
static const long SSL_FILETYPE_ASN1;
static const long SSL_ERROR_NONE;
static const long SSL_ERROR_ZERO_RETURN;
static const long SSL_ERROR_WANT_READ;
static const long SSL_ERROR_WANT_WRITE;
static const long SSL_ERROR_WANT_X509_LOOKUP;
static const long SSL_ERROR_SYSCALL;
static const long SSL_ERROR_SSL;
static const long SSL_SENT_SHUTDOWN;
static const long SSL_RECEIVED_SHUTDOWN;
static const long SSL_OP_NO_SSLv2;
static const long SSL_OP_NO_SSLv3;
static const long SSL_OP_NO_TLSv1;
static const long SSL_OP_NO_TLSv1_1;
static const long SSL_OP_NO_TLSv1_2;
static const long SSL_OP_NO_COMPRESSION;
static const long SSL_OP_SINGLE_DH_USE;
static const long SSL_OP_EPHEMERAL_RSA;
static const long SSL_OP_MICROSOFT_SESS_ID_BUG;
static const long SSL_OP_NETSCAPE_CHALLENGE_BUG;
static const long SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
static const long SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG;
static const long SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER;
static const long SSL_OP_MSIE_SSLV2_RSA_PADDING;
static const long SSL_OP_SSLEAY_080_CLIENT_DH_BUG;
static const long SSL_OP_TLS_D5_BUG;
static const long SSL_OP_TLS_BLOCK_PADDING_BUG;
static const long SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
static const long SSL_OP_CIPHER_SERVER_PREFERENCE;
static const long SSL_OP_TLS_ROLLBACK_BUG;
static const long SSL_OP_PKCS1_CHECK_1;
static const long SSL_OP_PKCS1_CHECK_2;
static const long SSL_OP_NETSCAPE_CA_DN_BUG;
static const long SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG;
static const long SSL_OP_NO_QUERY_MTU;
static const long SSL_OP_COOKIE_EXCHANGE;
static const long SSL_OP_NO_TICKET;
static const long SSL_OP_ALL;
static const long SSL_OP_SINGLE_ECDH_USE;
static const long SSL_VERIFY_PEER;
static const long SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
static const long SSL_VERIFY_CLIENT_ONCE;
static const long SSL_VERIFY_NONE;
static const long SSL_SESS_CACHE_OFF;
static const long SSL_SESS_CACHE_CLIENT;
static const long SSL_SESS_CACHE_SERVER;
static const long SSL_SESS_CACHE_BOTH;
static const long SSL_SESS_CACHE_NO_AUTO_CLEAR;
static const long SSL_SESS_CACHE_NO_INTERNAL_LOOKUP;
static const long SSL_SESS_CACHE_NO_INTERNAL_STORE;
static const long SSL_SESS_CACHE_NO_INTERNAL;
static const long SSL_ST_CONNECT;
static const long SSL_ST_ACCEPT;
static const long SSL_ST_MASK;
static const long SSL_ST_INIT;
static const long SSL_ST_BEFORE;
static const long SSL_ST_OK;
static const long SSL_ST_RENEGOTIATE;
static const long SSL_CB_LOOP;
static const long SSL_CB_EXIT;
static const long SSL_CB_READ;
static const long SSL_CB_WRITE;
static const long SSL_CB_ALERT;
static const long SSL_CB_READ_ALERT;
static const long SSL_CB_WRITE_ALERT;
static const long SSL_CB_ACCEPT_LOOP;
static const long SSL_CB_ACCEPT_EXIT;
static const long SSL_CB_CONNECT_LOOP;
static const long SSL_CB_CONNECT_EXIT;
static const long SSL_CB_HANDSHAKE_START;
static const long SSL_CB_HANDSHAKE_DONE;
static const long SSL_MODE_RELEASE_BUFFERS;
static const long SSL_MODE_ENABLE_PARTIAL_WRITE;
static const long SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER;
static const long SSL_MODE_AUTO_RETRY;
static const long SSL3_RANDOM_SIZE;
typedef ... X509_STORE_CTX;
static const long X509_V_OK;
static const long X509_V_ERR_APPLICATION_VERIFICATION;
typedef ... SSL_METHOD;
typedef struct ssl_st {
int version;
int type;
...;
} SSL_CTX;
typedef struct {
int master_key_length;
unsigned char master_key[...];
...;
} SSL_SESSION;
typedef struct {
unsigned char server_random[...];
unsigned char client_random[...];
...;
} SSL3_STATE;
typedef struct {
SSL3_STATE *s3;
SSL_SESSION *session;
int type;
...;
} SSL;
static const long TLSEXT_NAMETYPE_host_name;
typedef ... SSL_CIPHER;
"""
FUNCTIONS = """
void SSL_load_error_strings(void);
int SSL_library_init(void);
/* SSL */
const char *SSL_state_string_long(const SSL *);
SSL_SESSION *SSL_get1_session(SSL *);
int SSL_set_session(SSL *, SSL_SESSION *);
int SSL_get_verify_mode(const SSL *);
void SSL_set_verify_depth(SSL *, int);
int SSL_get_verify_depth(const SSL *);
int (*SSL_get_verify_callback(const SSL *))(int, X509_STORE_CTX *);
void SSL_set_info_callback(SSL *ssl, void (*)(const SSL *, int, int));
void (*SSL_get_info_callback(const SSL *))(const SSL *, int, int);
SSL *SSL_new(SSL_CTX *);
void SSL_free(SSL *);
int SSL_set_fd(SSL *, int);
void SSL_set_bio(SSL *, BIO *, BIO *);
void SSL_set_connect_state(SSL *);
void SSL_set_accept_state(SSL *);
void SSL_set_shutdown(SSL *, int);
int SSL_get_shutdown(const SSL *);
int SSL_pending(const SSL *);
int SSL_write(SSL *, const void *, int);
int SSL_read(SSL *, void *, int);
X509 *SSL_get_peer_certificate(const SSL *);
int SSL_get_ex_data_X509_STORE_CTX_idx(void);
Cryptography_STACK_OF_X509 *SSL_get_peer_cert_chain(const SSL *);
Cryptography_STACK_OF_X509_NAME *SSL_get_client_CA_list(const SSL *);
int SSL_get_error(const SSL *, int);
int SSL_do_handshake(SSL *);
int SSL_shutdown(SSL *);
const char *SSL_get_cipher_list(const SSL *, int);
/* context */
void SSL_CTX_free(SSL_CTX *);
long SSL_CTX_set_timeout(SSL_CTX *, long);
int SSL_CTX_set_default_verify_paths(SSL_CTX *);
void SSL_CTX_set_verify(SSL_CTX *, int, int (*)(int, X509_STORE_CTX *));
void SSL_CTX_set_verify_depth(SSL_CTX *, int);
int (*SSL_CTX_get_verify_callback(const SSL_CTX *))(int, X509_STORE_CTX *);
int SSL_CTX_get_verify_mode(const SSL_CTX *);
int SSL_CTX_get_verify_depth(const SSL_CTX *);
int SSL_CTX_set_cipher_list(SSL_CTX *, const char *);
int SSL_CTX_load_verify_locations(SSL_CTX *, const char *, const char *);
void SSL_CTX_set_default_passwd_cb(SSL_CTX *, pem_password_cb *);
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *, void *);
int SSL_CTX_use_certificate(SSL_CTX *, X509 *);
int SSL_CTX_use_certificate_file(SSL_CTX *, const char *, int);
int SSL_CTX_use_certificate_chain_file(SSL_CTX *, const char *);
int SSL_CTX_use_PrivateKey(SSL_CTX *, EVP_PKEY *);
int SSL_CTX_use_PrivateKey_file(SSL_CTX *, const char *, int);
void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
int SSL_CTX_add_client_CA(SSL_CTX *, X509 *);
void SSL_CTX_set_client_CA_list(SSL_CTX *, Cryptography_STACK_OF_X509_NAME *);
/* X509_STORE_CTX */
int X509_STORE_CTX_get_error(X509_STORE_CTX *);
void X509_STORE_CTX_set_error(X509_STORE_CTX *, int);
int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *);
X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *);
int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *, int, void *);
void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *, int);
/* SSL_SESSION */
void SSL_SESSION_free(SSL_SESSION *);
/* Information about actually used cipher */
const char *SSL_CIPHER_get_name(const SSL_CIPHER *);
int SSL_CIPHER_get_bits(const SSL_CIPHER *, int *);
char *SSL_CIPHER_get_version(const SSL_CIPHER *);
size_t SSL_get_finished(const SSL *, void *, size_t);
size_t SSL_get_peer_finished(const SSL *, void *, size_t);
"""
MACROS = """
unsigned long SSL_set_mode(SSL *, unsigned long);
unsigned long SSL_get_mode(SSL *);
unsigned long SSL_set_options(SSL *, unsigned long);
unsigned long SSL_get_options(SSL *);
int SSL_want_read(const SSL *);
int SSL_want_write(const SSL *);
long SSL_total_renegotiations(SSL *);
/* Defined as unsigned long because SSL_OP_ALL is greater than signed 32-bit
and Windows defines long as 32-bit. */
unsigned long SSL_CTX_set_options(SSL_CTX *, unsigned long);
unsigned long SSL_CTX_get_options(SSL_CTX *);
unsigned long SSL_CTX_set_mode(SSL_CTX *, unsigned long);
unsigned long SSL_CTX_get_mode(SSL_CTX *);
unsigned long SSL_CTX_set_session_cache_mode(SSL_CTX *, unsigned long);
unsigned long SSL_CTX_get_session_cache_mode(SSL_CTX *);
unsigned long SSL_CTX_set_tmp_dh(SSL_CTX *, DH *);
unsigned long SSL_CTX_set_tmp_ecdh(SSL_CTX *, EC_KEY *);
unsigned long SSL_CTX_add_extra_chain_cert(SSL_CTX *, X509 *);
/*- These aren't macros these functions are all const X on openssl > 1.0.x -*/
/* methods */
/* SSLv2 support is compiled out of some versions of OpenSSL. These will
* get special support when we generate the bindings so that if they are
* available they will be wrapped, but if they are not they won't cause
* problems (like link errors).
*/
const SSL_METHOD *SSLv2_method(void);
const SSL_METHOD *SSLv2_server_method(void);
const SSL_METHOD *SSLv2_client_method(void);
/*
* TLSv1_1 and TLSv1_2 are recent additions. Only sufficiently new versions of
* OpenSSL support them.
*/
const SSL_METHOD *TLSv1_1_method(void);
const SSL_METHOD *TLSv1_1_server_method(void);
const SSL_METHOD *TLSv1_1_client_method(void);
const SSL_METHOD *TLSv1_2_method(void);
const SSL_METHOD *TLSv1_2_server_method(void);
const SSL_METHOD *TLSv1_2_client_method(void);
const SSL_METHOD *SSLv3_method(void);
const SSL_METHOD *SSLv3_server_method(void);
const SSL_METHOD *SSLv3_client_method(void);
const SSL_METHOD *TLSv1_method(void);
const SSL_METHOD *TLSv1_server_method(void);
const SSL_METHOD *TLSv1_client_method(void);
const SSL_METHOD *DTLSv1_method(void);
const SSL_METHOD *DTLSv1_server_method(void);
const SSL_METHOD *DTLSv1_client_method(void);
const SSL_METHOD *SSLv23_method(void);
const SSL_METHOD *SSLv23_server_method(void);
const SSL_METHOD *SSLv23_client_method(void);
/*- These aren't macros these arguments are all const X on openssl > 1.0.x -*/
SSL_CTX *SSL_CTX_new(SSL_METHOD *);
long SSL_CTX_get_timeout(const SSL_CTX *);
const SSL_CIPHER *SSL_get_current_cipher(const SSL *);
/* SNI APIs were introduced in OpenSSL 1.0.0. To continue to support
* earlier versions some special handling of these is necessary.
*/
const char *SSL_get_servername(const SSL *, const int);
void SSL_set_tlsext_host_name(SSL *, char *);
void SSL_CTX_set_tlsext_servername_callback(
SSL_CTX *,
int (*)(const SSL *, int *, void *));
long SSL_session_reused(SSL *);
/* The following were macros in 0.9.8e. Once we drop support for RHEL/CentOS 5
we should move these back to FUNCTIONS. */
void SSL_CTX_set_info_callback(SSL_CTX *, void (*)(const SSL *, int, int));
void (*SSL_CTX_get_info_callback(SSL_CTX *))(const SSL *, int, int);
/* This function does not exist in 0.9.8e. Once we drop support for
RHEL/CentOS 5 this can be moved back to FUNCTIONS. */
SSL_CTX *SSL_set_SSL_CTX(SSL *, SSL_CTX *);
const SSL_METHOD* Cryptography_SSL_CTX_get_method(const SSL_CTX*);
/* NPN APIs were introduced in OpenSSL 1.0.1. To continue to support earlier
* versions some special handling of these is necessary.
*/
void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *,
int (*)(SSL *,
const unsigned char **,
unsigned int *,
void *),
void *);
void SSL_CTX_set_next_proto_select_cb(SSL_CTX *,
int (*)(SSL *,
unsigned char **,
unsigned char *,
const unsigned char *,
unsigned int,
void *),
void *);
int SSL_select_next_proto(unsigned char **, unsigned char *,
const unsigned char *, unsigned int,
const unsigned char *, unsigned int);
void SSL_get0_next_proto_negotiated(const SSL *,
const unsigned char **, unsigned *);
"""
CUSTOMIZATIONS = """
#ifdef OPENSSL_NO_SSL2
static const long Cryptography_HAS_SSL2 = 0;
SSL_METHOD* (*SSLv2_method)(void) = NULL;
SSL_METHOD* (*SSLv2_client_method)(void) = NULL;
SSL_METHOD* (*SSLv2_server_method)(void) = NULL;
#else
static const long Cryptography_HAS_SSL2 = 1;
#endif
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
static const long Cryptography_HAS_TLSEXT_HOSTNAME = 1;
#else
static const long Cryptography_HAS_TLSEXT_HOSTNAME = 0;
void (*SSL_set_tlsext_host_name)(SSL *, char *) = NULL;
const char* (*SSL_get_servername)(const SSL *, const int) = NULL;
void (*SSL_CTX_set_tlsext_servername_callback)(
SSL_CTX *,
int (*)(const SSL *, int *, void *)) = NULL;
#endif
#ifdef SSL_MODE_RELEASE_BUFFERS
static const long Cryptography_HAS_RELEASE_BUFFERS = 1;
#else
static const long Cryptography_HAS_RELEASE_BUFFERS = 0;
const long SSL_MODE_RELEASE_BUFFERS = 0;
#endif
#ifdef SSL_OP_NO_COMPRESSION
static const long Cryptography_HAS_OP_NO_COMPRESSION = 1;
#else
static const long Cryptography_HAS_OP_NO_COMPRESSION = 0;
const long SSL_OP_NO_COMPRESSION = 0;
#endif
#ifdef SSL_OP_NO_TLSv1_1
static const long Cryptography_HAS_TLSv1_1 = 1;
#else
static const long Cryptography_HAS_TLSv1_1 = 0;
static const long SSL_OP_NO_TLSv1_1 = 0;
SSL_METHOD* (*TLSv1_1_method)(void) = NULL;
SSL_METHOD* (*TLSv1_1_client_method)(void) = NULL;
SSL_METHOD* (*TLSv1_1_server_method)(void) = NULL;
#endif
#ifdef SSL_OP_NO_TLSv1_2
static const long Cryptography_HAS_TLSv1_2 = 1;
#else
static const long Cryptography_HAS_TLSv1_2 = 0;
static const long SSL_OP_NO_TLSv1_2 = 0;
SSL_METHOD* (*TLSv1_2_method)(void) = NULL;
SSL_METHOD* (*TLSv1_2_client_method)(void) = NULL;
SSL_METHOD* (*TLSv1_2_server_method)(void) = NULL;
#endif
#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
static const long Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING = 1;
#else
static const long Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING = 0;
const long SSL_OP_MSIE_SSLV2_RSA_PADDING = 0;
#endif
#ifdef OPENSSL_NO_EC
long (*SSL_CTX_set_tmp_ecdh)(SSL_CTX *, EC_KEY *) = NULL;
#endif
#ifdef SSL_OP_NO_TICKET
static const long Cryptography_HAS_SSL_OP_NO_TICKET = 1;
#else
static const long Cryptography_HAS_SSL_OP_NO_TICKET = 0;
const long SSL_OP_NO_TICKET = 0;
#endif
// OpenSSL 0.9.8f+
#if OPENSSL_VERSION_NUMBER >= 0x00908070L
static const long Cryptography_HAS_SSL_SET_SSL_CTX = 1;
#else
static const long Cryptography_HAS_SSL_SET_SSL_CTX = 0;
static const long TLSEXT_NAMETYPE_host_name = 0;
SSL_CTX *(*SSL_set_SSL_CTX)(SSL *, SSL_CTX *) = NULL;
#endif
/* NetBSD shipped without including d1_meth.c. This workaround checks to see
if the version of NetBSD we're currently running on is old enough to
have the bug and provides an empty implementation so we can link and
then remove the function from the ffi object. */
#ifdef __NetBSD__
# include <sys/param.h>
# if (__NetBSD_Version__ < 699003800)
static const long Cryptography_HAS_NETBSD_D1_METH = 0;
const SSL_METHOD *DTLSv1_method(void) {
return NULL;
}
# else
static const long Cryptography_HAS_NETBSD_D1_METH = 1;
# endif
#else
static const long Cryptography_HAS_NETBSD_D1_METH = 1;
#endif
// Workaround for #794 caused by cffi const** bug.
const SSL_METHOD* Cryptography_SSL_CTX_get_method(const SSL_CTX* ctx) {
return ctx->method;
}
/* Because OPENSSL defines macros that claim lack of support for things, rather
* than macros that claim support for things, we need to do a version check in
* addition to a definition check. NPN was added in 1.0.1: for any version
* before that, there is no compatibility.
*/
#if defined(OPENSSL_NO_NEXTPROTONEG) || OPENSSL_VERSION_NUMBER < 0x1000100fL
static const long Cryptography_HAS_NEXTPROTONEG = 0;
void (*SSL_CTX_set_next_protos_advertised_cb)(SSL_CTX *,
int (*)(SSL *,
const unsigned char **,
unsigned int *,
void *),
void *) = NULL;
void (*SSL_CTX_set_next_proto_select_cb)(SSL_CTX *,
int (*)(SSL *,
unsigned char **,
unsigned char *,
const unsigned char *,
unsigned int,
void *),
void *) = NULL;
int (*SSL_select_next_proto)(unsigned char **, unsigned char *,
const unsigned char *, unsigned int,
const unsigned char *, unsigned int) = NULL;
void (*SSL_get0_next_proto_negotiated)(const SSL *,
const unsigned char **,
unsigned *) = NULL;
#else
static const long Cryptography_HAS_NEXTPROTONEG = 1;
#endif
"""
CONDITIONAL_NAMES = {
"Cryptography_HAS_TLSv1_1": [
"SSL_OP_NO_TLSv1_1",
"TLSv1_1_method",
"TLSv1_1_server_method",
"TLSv1_1_client_method",
],
"Cryptography_HAS_TLSv1_2": [
"SSL_OP_NO_TLSv1_2",
"TLSv1_2_method",
"TLSv1_2_server_method",
"TLSv1_2_client_method",
],
"Cryptography_HAS_SSL2": [
"SSLv2_method",
"SSLv2_client_method",
"SSLv2_server_method",
],
"Cryptography_HAS_TLSEXT_HOSTNAME": [
"SSL_set_tlsext_host_name",
"SSL_get_servername",
"SSL_CTX_set_tlsext_servername_callback",
],
"Cryptography_HAS_RELEASE_BUFFERS": [
"SSL_MODE_RELEASE_BUFFERS",
],
"Cryptography_HAS_OP_NO_COMPRESSION": [
"SSL_OP_NO_COMPRESSION",
],
"Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING": [
"SSL_OP_MSIE_SSLV2_RSA_PADDING",
],
"Cryptography_HAS_EC": [
"SSL_CTX_set_tmp_ecdh",
],
"Cryptography_HAS_SSL_OP_NO_TICKET": [
"SSL_OP_NO_TICKET",
],
"Cryptography_HAS_SSL_SET_SSL_CTX": [
"SSL_set_SSL_CTX",
"TLSEXT_NAMETYPE_host_name",
],
"Cryptography_HAS_NETBSD_D1_METH": [
"DTLSv1_method",
],
"Cryptography_HAS_NEXTPROTONEG": [
"SSL_CTX_set_next_protos_advertised_cb",
"SSL_CTX_set_next_proto_select_cb",
"SSL_select_next_proto",
"SSL_get0_next_proto_negotiated",
]
}

View file

@ -0,0 +1,277 @@
# 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/ssl.h>
/*
* This is part of a work-around for the difficulty cffi has in dealing with
* `STACK_OF(foo)` as the name of a type. We invent a new, simpler name that
* will be an alias for this type and use the alias throughout. This works
* together with another opaque typedef for the same name in the TYPES section.
* Note that the result is an opaque type.
*/
typedef STACK_OF(X509) Cryptography_STACK_OF_X509;
typedef STACK_OF(X509_REVOKED) Cryptography_STACK_OF_X509_REVOKED;
"""
TYPES = """
typedef ... Cryptography_STACK_OF_X509;
typedef ... Cryptography_STACK_OF_X509_REVOKED;
typedef struct {
ASN1_OBJECT *algorithm;
...;
} X509_ALGOR;
typedef ... X509_ATTRIBUTE;
typedef struct {
X509_ALGOR *signature;
...;
} X509_CINF;
typedef struct {
ASN1_OBJECT *object;
ASN1_BOOLEAN critical;
ASN1_OCTET_STRING *value;
} X509_EXTENSION;
typedef ... X509_EXTENSIONS;
typedef ... X509_REQ;
typedef struct {
ASN1_INTEGER *serialNumber;
ASN1_TIME *revocationDate;
X509_EXTENSIONS *extensions;
int sequence;
...;
} X509_REVOKED;
typedef struct {
Cryptography_STACK_OF_X509_REVOKED *revoked;
...;
} X509_CRL_INFO;
typedef struct {
X509_CRL_INFO *crl;
...;
} X509_CRL;
typedef struct {
X509_CINF *cert_info;
...;
} X509;
typedef ... X509_STORE;
typedef ... NETSCAPE_SPKI;
"""
FUNCTIONS = """
X509 *X509_new(void);
void X509_free(X509 *);
X509 *X509_dup(X509 *);
int X509_print_ex(BIO *, X509 *, unsigned long, unsigned long);
int X509_set_version(X509 *, long);
EVP_PKEY *X509_get_pubkey(X509 *);
int X509_set_pubkey(X509 *, EVP_PKEY *);
unsigned char *X509_alias_get0(X509 *, int *);
int X509_sign(X509 *, EVP_PKEY *, const EVP_MD *);
int X509_digest(const X509 *, const EVP_MD *, unsigned char *, unsigned int *);
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *, long);
unsigned long X509_subject_name_hash(X509 *);
X509_NAME *X509_get_subject_name(X509 *);
int X509_set_subject_name(X509 *, X509_NAME *);
X509_NAME *X509_get_issuer_name(X509 *);
int X509_set_issuer_name(X509 *, X509_NAME *);
int X509_get_ext_count(X509 *);
int X509_add_ext(X509 *, X509_EXTENSION *, int);
X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *);
X509_EXTENSION *X509_get_ext(X509 *, int);
int X509_EXTENSION_get_critical(X509_EXTENSION *);
ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *);
void X509_EXTENSION_free(X509_EXTENSION *);
int X509_REQ_set_version(X509_REQ *, long);
X509_REQ *X509_REQ_new(void);
void X509_REQ_free(X509_REQ *);
int X509_REQ_set_pubkey(X509_REQ *, EVP_PKEY *);
int X509_REQ_sign(X509_REQ *, EVP_PKEY *, const EVP_MD *);
int X509_REQ_verify(X509_REQ *, EVP_PKEY *);
EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *);
int X509_REQ_print_ex(BIO *, X509_REQ *, unsigned long, unsigned long);
int X509V3_EXT_print(BIO *, X509_EXTENSION *, unsigned long, int);
ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *);
X509_REVOKED *X509_REVOKED_new(void);
void X509_REVOKED_free(X509_REVOKED *);
int X509_REVOKED_set_serialNumber(X509_REVOKED *, ASN1_INTEGER *);
int X509_REVOKED_add1_ext_i2d(X509_REVOKED *, int, void *, int, unsigned long);
X509_CRL *d2i_X509_CRL_bio(BIO *, X509_CRL **);
X509_CRL *X509_CRL_new(void);
void X509_CRL_free(X509_CRL *);
int X509_CRL_add0_revoked(X509_CRL *, X509_REVOKED *);
int i2d_X509_CRL_bio(BIO *, X509_CRL *);
int X509_CRL_print(BIO *, X509_CRL *);
int X509_CRL_set_issuer_name(X509_CRL *, X509_NAME *);
int X509_CRL_sign(X509_CRL *, EVP_PKEY *, const EVP_MD *);
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *, EVP_PKEY *);
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *, EVP_PKEY *, const EVP_MD *);
char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *);
EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *);
int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *, EVP_PKEY *);
NETSCAPE_SPKI *NETSCAPE_SPKI_new(void);
void NETSCAPE_SPKI_free(NETSCAPE_SPKI *);
/* ASN1 serialization */
int i2d_X509_bio(BIO *, X509 *);
X509 *d2i_X509_bio(BIO *, X509 **);
int i2d_X509_REQ_bio(BIO *, X509_REQ *);
X509_REQ *d2i_X509_REQ_bio(BIO *, X509_REQ **);
int i2d_PrivateKey_bio(BIO *, EVP_PKEY *);
EVP_PKEY *d2i_PrivateKey_bio(BIO *, EVP_PKEY **);
int i2d_PUBKEY_bio(BIO *, EVP_PKEY *);
EVP_PKEY *d2i_PUBKEY_bio(BIO *, EVP_PKEY **);
ASN1_INTEGER *X509_get_serialNumber(X509 *);
int X509_set_serialNumber(X509 *, ASN1_INTEGER *);
/* X509_STORE */
X509_STORE *X509_STORE_new(void);
void X509_STORE_free(X509_STORE *);
int X509_STORE_add_cert(X509_STORE *, X509 *);
int X509_verify_cert(X509_STORE_CTX *);
const char *X509_verify_cert_error_string(long);
const char *X509_get_default_cert_area(void);
const char *X509_get_default_cert_dir(void);
const char *X509_get_default_cert_file(void);
const char *X509_get_default_cert_dir_env(void);
const char *X509_get_default_cert_file_env(void);
const char *X509_get_default_private_dir(void);
int i2d_RSA_PUBKEY(RSA *, unsigned char **);
RSA *d2i_RSA_PUBKEY(RSA **, const unsigned char **, long);
RSA *d2i_RSAPublicKey(RSA **, const unsigned char **, long);
RSA *d2i_RSAPrivateKey(RSA **, const unsigned char **, long);
int i2d_DSA_PUBKEY(DSA *, unsigned char **);
DSA *d2i_DSA_PUBKEY(DSA **, const unsigned char **, long);
DSA *d2i_DSAPublicKey(DSA **, const unsigned char **, long);
DSA *d2i_DSAPrivateKey(DSA **, const unsigned char **, long);
RSA *d2i_RSAPrivateKey_bio(BIO *, RSA **);
int i2d_RSAPrivateKey_bio(BIO *, RSA *);
RSA *d2i_RSAPublicKey_bio(BIO *, RSA **);
int i2d_RSAPublicKey_bio(BIO *, RSA *);
RSA *d2i_RSA_PUBKEY_bio(BIO *, RSA **);
int i2d_RSA_PUBKEY_bio(BIO *, RSA *);
DSA *d2i_DSA_PUBKEY_bio(BIO *, DSA **);
int i2d_DSA_PUBKEY_bio(BIO *, DSA *);
DSA *d2i_DSAPrivateKey_bio(BIO *, DSA **);
int i2d_DSAPrivateKey_bio(BIO *, DSA *);
"""
MACROS = """
long X509_get_version(X509 *);
ASN1_TIME *X509_get_notBefore(X509 *);
ASN1_TIME *X509_get_notAfter(X509 *);
long X509_REQ_get_version(X509_REQ *);
X509_NAME *X509_REQ_get_subject_name(X509_REQ *);
Cryptography_STACK_OF_X509 *sk_X509_new_null(void);
void sk_X509_free(Cryptography_STACK_OF_X509 *);
int sk_X509_num(Cryptography_STACK_OF_X509 *);
int sk_X509_push(Cryptography_STACK_OF_X509 *, X509 *);
X509 *sk_X509_value(Cryptography_STACK_OF_X509 *, int);
X509_EXTENSIONS *sk_X509_EXTENSION_new_null(void);
int sk_X509_EXTENSION_num(X509_EXTENSIONS *);
X509_EXTENSION *sk_X509_EXTENSION_value(X509_EXTENSIONS *, int);
int sk_X509_EXTENSION_push(X509_EXTENSIONS *, X509_EXTENSION *);
X509_EXTENSION *sk_X509_EXTENSION_delete(X509_EXTENSIONS *, int);
void sk_X509_EXTENSION_free(X509_EXTENSIONS *);
int sk_X509_REVOKED_num(Cryptography_STACK_OF_X509_REVOKED *);
X509_REVOKED *sk_X509_REVOKED_value(Cryptography_STACK_OF_X509_REVOKED *, int);
int i2d_RSAPublicKey(RSA *, unsigned char **);
int i2d_RSAPrivateKey(RSA *, unsigned char **);
int i2d_DSAPublicKey(DSA *, unsigned char **);
int i2d_DSAPrivateKey(DSA *, unsigned char **);
/* These aren't macros these arguments are all const X on openssl > 1.0.x */
int X509_CRL_set_lastUpdate(X509_CRL *, ASN1_TIME *);
int X509_CRL_set_nextUpdate(X509_CRL *, ASN1_TIME *);
/* these use STACK_OF(X509_EXTENSION) in 0.9.8e. Once we drop support for
RHEL/CentOS 5 we should move these back to FUNCTIONS. */
int X509_REQ_add_extensions(X509_REQ *, X509_EXTENSIONS *);
X509_EXTENSIONS *X509_REQ_get_extensions(X509_REQ *);
int i2d_EC_PUBKEY(EC_KEY *, unsigned char **);
EC_KEY *d2i_EC_PUBKEY(EC_KEY **, const unsigned char **, long);
EC_KEY *d2i_EC_PUBKEY_bio(BIO *, EC_KEY **);
int i2d_EC_PUBKEY_bio(BIO *, EC_KEY *);
EC_KEY *d2i_ECPrivateKey_bio(BIO *, EC_KEY **);
int i2d_ECPrivateKey_bio(BIO *, EC_KEY *);
"""
CUSTOMIZATIONS = """
// OpenSSL 0.9.8e does not have this definition
#if OPENSSL_VERSION_NUMBER <= 0x0090805fL
typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
#endif
#ifdef OPENSSL_NO_EC
int (*i2d_EC_PUBKEY)(EC_KEY *, unsigned char **) = NULL;
EC_KEY *(*d2i_EC_PUBKEY)(EC_KEY **, const unsigned char **, long) = NULL;
EC_KEY *(*d2i_EC_PUBKEY_bio)(BIO *, EC_KEY **) = NULL;
int (*i2d_EC_PUBKEY_bio)(BIO *, EC_KEY *) = NULL;
EC_KEY *(*d2i_ECPrivateKey_bio)(BIO *, EC_KEY **) = NULL;
int (*i2d_ECPrivateKey_bio)(BIO *, EC_KEY *) = NULL;
#endif
"""
CONDITIONAL_NAMES = {
"Cryptography_HAS_EC": [
"i2d_EC_PUBKEY",
"d2i_EC_PUBKEY",
"d2i_EC_PUBKEY_bio",
"i2d_EC_PUBKEY_bio",
"d2i_ECPrivateKey_bio",
"i2d_ECPrivateKey_bio",
]
}

View file

@ -0,0 +1,61 @@
# 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/x509.h>
/*
* See the comment above Cryptography_STACK_OF_X509 in x509.py
*/
typedef STACK_OF(X509_NAME) Cryptography_STACK_OF_X509_NAME;
"""
TYPES = """
typedef ... X509_NAME;
typedef ... X509_NAME_ENTRY;
typedef ... Cryptography_STACK_OF_X509_NAME;
"""
FUNCTIONS = """
int X509_NAME_entry_count(X509_NAME *);
X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *, int);
ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *);
ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *);
unsigned long X509_NAME_hash(X509_NAME *);
int i2d_X509_NAME(X509_NAME *, unsigned char **);
int X509_NAME_add_entry_by_NID(X509_NAME *, int, int, unsigned char *,
int, int, int);
X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *, int);
void X509_NAME_ENTRY_free(X509_NAME_ENTRY *);
int X509_NAME_get_index_by_NID(X509_NAME *, int, int);
int X509_NAME_cmp(const X509_NAME *, const X509_NAME *);
char *X509_NAME_oneline(X509_NAME *, char *, int);
X509_NAME *X509_NAME_dup(X509_NAME *);
void X509_NAME_free(X509_NAME *);
"""
MACROS = """
Cryptography_STACK_OF_X509_NAME *sk_X509_NAME_new_null(void);
int sk_X509_NAME_num(Cryptography_STACK_OF_X509_NAME *);
int sk_X509_NAME_push(Cryptography_STACK_OF_X509_NAME *, X509_NAME *);
X509_NAME *sk_X509_NAME_value(Cryptography_STACK_OF_X509_NAME *, int);
void sk_X509_NAME_free(Cryptography_STACK_OF_X509_NAME *);
"""
CUSTOMIZATIONS = """
"""
CONDITIONAL_NAMES = {}

View file

@ -0,0 +1,101 @@
# 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/x509v3.h>
"""
TYPES = """
typedef struct {
X509 *issuer_cert;
X509 *subject_cert;
...;
} X509V3_CTX;
typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char **, long);
typedef struct {
ASN1_ITEM_EXP *it;
X509V3_EXT_D2I d2i;
...;
} X509V3_EXT_METHOD;
static const int GEN_OTHERNAME;
static const int GEN_EMAIL;
static const int GEN_X400;
static const int GEN_DNS;
static const int GEN_URI;
static const int GEN_DIRNAME;
static const int GEN_EDIPARTY;
static const int GEN_IPADD;
static const int GEN_RID;
typedef struct {
...;
} OTHERNAME;
typedef struct {
...;
} EDIPARTYNAME;
typedef struct {
int type;
union {
char *ptr;
OTHERNAME *otherName; /* otherName */
ASN1_IA5STRING *rfc822Name;
ASN1_IA5STRING *dNSName;
ASN1_TYPE *x400Address;
X509_NAME *directoryName;
EDIPARTYNAME *ediPartyName;
ASN1_IA5STRING *uniformResourceIdentifier;
ASN1_OCTET_STRING *iPAddress;
ASN1_OBJECT *registeredID;
/* Old names */
ASN1_OCTET_STRING *ip; /* iPAddress */
X509_NAME *dirn; /* dirn */
ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, */
/* uniformResourceIdentifier */
ASN1_OBJECT *rid; /* registeredID */
ASN1_TYPE *other; /* x400Address */
} d;
...;
} GENERAL_NAME;
typedef struct stack_st_GENERAL_NAME GENERAL_NAMES;
"""
FUNCTIONS = """
void X509V3_set_ctx(X509V3_CTX *, X509 *, X509 *, X509_REQ *, X509_CRL *, int);
X509_EXTENSION *X509V3_EXT_nconf(CONF *, X509V3_CTX *, char *, char *);
int GENERAL_NAME_print(BIO *, GENERAL_NAME *);
"""
MACROS = """
void *X509V3_set_ctx_nodb(X509V3_CTX *);
int sk_GENERAL_NAME_num(struct stack_st_GENERAL_NAME *);
int sk_GENERAL_NAME_push(struct stack_st_GENERAL_NAME *, GENERAL_NAME *);
GENERAL_NAME *sk_GENERAL_NAME_value(struct stack_st_GENERAL_NAME *, int);
/* These aren't macros these functions are all const X on openssl > 1.0.x */
const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *);
const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int);
"""
CUSTOMIZATIONS = """
"""
CONDITIONAL_NAMES = {}

View file

@ -0,0 +1,108 @@
# 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 binascii
import sys
import cffi
def build_ffi(module_prefix, modules, pre_include="", post_include="",
libraries=[], extra_compile_args=[], extra_link_args=[]):
"""
Modules listed in ``modules`` should have the following attributes:
* ``INCLUDES``: A string containing C includes.
* ``TYPES``: A string containing C declarations for types.
* ``FUNCTIONS``: A string containing C declarations for functions.
* ``MACROS``: A string containing C declarations for any macros.
* ``CUSTOMIZATIONS``: A string containing arbitrary top-level C code, this
can be used to do things like test for a define and provide an
alternate implementation based on that.
* ``CONDITIONAL_NAMES``: A dict mapping strings of condition names from the
library to a list of names which will not be present without the
condition.
"""
ffi = cffi.FFI()
types = []
includes = []
functions = []
macros = []
customizations = []
for name in modules:
module_name = module_prefix + name
__import__(module_name)
module = sys.modules[module_name]
types.append(module.TYPES)
macros.append(module.MACROS)
functions.append(module.FUNCTIONS)
includes.append(module.INCLUDES)
customizations.append(module.CUSTOMIZATIONS)
cdef_sources = types + functions + macros
ffi.cdef("\n".join(cdef_sources))
# We include functions here so that if we got any of their definitions
# wrong, the underlying C compiler will explode. In C you are allowed
# to re-declare a function if it has the same signature. That is:
# int foo(int);
# int foo(int);
# is legal, but the following will fail to compile:
# int foo(int);
# int foo(short);
source = "\n".join(
[pre_include] +
includes +
[post_include] +
functions +
customizations
)
lib = ffi.verify(
source=source,
modulename=_create_modulename(cdef_sources, source, sys.version),
libraries=libraries,
ext_package="cryptography",
extra_compile_args=extra_compile_args,
extra_link_args=extra_link_args,
)
for name in modules:
module_name = module_prefix + name
module = sys.modules[module_name]
for condition, names in module.CONDITIONAL_NAMES.items():
if not getattr(lib, condition):
for name in names:
delattr(lib, name)
return ffi, lib
def _create_modulename(cdef_sources, source, sys_version):
"""
cffi creates a modulename internally that incorporates the cffi version.
This will cause cryptography's wheels to break when the version of cffi
the user has does not match what was used when building the wheel. To
resolve this we build our own modulename that uses most of the same code
from cffi but elides the version key.
"""
key = '\x00'.join([sys_version[:3], source] + cdef_sources)
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')
return '_Cryptography_cffi_{0}{1}'.format(k1, k2)

View file

@ -0,0 +1,14 @@
# 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

View file

@ -0,0 +1,14 @@
# 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

View file

@ -0,0 +1,183 @@
# 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 UnsupportedAlgorithm, _Reasons
from cryptography.hazmat.backends.interfaces import DSABackend
from cryptography.hazmat.primitives import interfaces
def _check_dsa_parameters(modulus, subgroup_order, generator):
if (
not isinstance(modulus, six.integer_types) or
not isinstance(subgroup_order, six.integer_types) or
not isinstance(generator, six.integer_types)
):
raise TypeError("DSA parameters must be integers")
if (utils.bit_length(modulus),
utils.bit_length(subgroup_order)) not in (
(1024, 160),
(2048, 256),
(3072, 256)):
raise ValueError("modulus and subgroup_order lengths must be "
"one of these pairs (1024, 160) or (2048, 256) "
"or (3072, 256)")
if generator <= 1 or generator >= modulus:
raise ValueError("generator must be > 1 and < modulus")
@utils.register_interface(interfaces.DSAParameters)
class DSAParameters(object):
def __init__(self, modulus, subgroup_order, generator):
_check_dsa_parameters(modulus, subgroup_order, generator)
self._modulus = modulus
self._subgroup_order = subgroup_order
self._generator = generator
@classmethod
def generate(cls, key_size, backend):
if not isinstance(backend, DSABackend):
raise UnsupportedAlgorithm(
"Backend object does not implement DSABackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
return backend.generate_dsa_parameters(key_size)
@property
def modulus(self):
return self._modulus
@property
def subgroup_order(self):
return self._subgroup_order
@property
def generator(self):
return self._generator
@property
def p(self):
return self.modulus
@property
def q(self):
return self.subgroup_order
@property
def g(self):
return self.generator
@utils.register_interface(interfaces.DSAPrivateKey)
class DSAPrivateKey(object):
def __init__(self, modulus, subgroup_order, generator, x, y):
_check_dsa_parameters(modulus, subgroup_order, generator)
if (
not isinstance(x, six.integer_types) or
not isinstance(y, six.integer_types)
):
raise TypeError("DSAPrivateKey arguments must be integers")
if x <= 0 or x >= subgroup_order:
raise ValueError("x must be > 0 and < subgroup_order")
if y != pow(generator, x, modulus):
raise ValueError("y must be equal to (generator ** x % modulus)")
self._modulus = modulus
self._subgroup_order = subgroup_order
self._generator = generator
self._x = x
self._y = y
@classmethod
def generate(cls, parameters, backend):
if not isinstance(backend, DSABackend):
raise UnsupportedAlgorithm(
"Backend object does not implement DSABackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
return backend.generate_dsa_private_key(parameters)
def signer(self, algorithm, backend):
if not isinstance(backend, DSABackend):
raise UnsupportedAlgorithm(
"Backend object does not implement DSABackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
return backend.create_dsa_signature_ctx(self, algorithm)
@property
def key_size(self):
return utils.bit_length(self._modulus)
def public_key(self):
return DSAPublicKey(self._modulus, self._subgroup_order,
self._generator, self.y)
@property
def x(self):
return self._x
@property
def y(self):
return self._y
def parameters(self):
return DSAParameters(self._modulus, self._subgroup_order,
self._generator)
@utils.register_interface(interfaces.DSAPublicKey)
class DSAPublicKey(object):
def __init__(self, modulus, subgroup_order, generator, y):
_check_dsa_parameters(modulus, subgroup_order, generator)
if not isinstance(y, six.integer_types):
raise TypeError("y must be an integer")
self._modulus = modulus
self._subgroup_order = subgroup_order
self._generator = generator
self._y = y
def verifier(self, signature, algorithm, backend):
if not isinstance(backend, DSABackend):
raise UnsupportedAlgorithm(
"Backend object does not implement DSABackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
return backend.create_dsa_verification_ctx(self, signature,
algorithm)
@property
def key_size(self):
return utils.bit_length(self._modulus)
@property
def y(self):
return self._y
def parameters(self):
return DSAParameters(self._modulus, self._subgroup_order,
self._generator)

View file

@ -0,0 +1,92 @@
# 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
import six
from cryptography import utils
from cryptography.hazmat.primitives import interfaces
@utils.register_interface(interfaces.AsymmetricPadding)
class PKCS1v15(object):
name = "EMSA-PKCS1-v1_5"
@utils.register_interface(interfaces.AsymmetricPadding)
class PSS(object):
MAX_LENGTH = object()
name = "EMSA-PSS"
def __init__(self, mgf, salt_length=None):
self._mgf = mgf
if salt_length is None:
warnings.warn(
"salt_length is deprecated on MGF1 and should be added via the"
" PSS constructor.",
utils.DeprecatedIn04
)
else:
if (not isinstance(salt_length, six.integer_types) and
salt_length is not self.MAX_LENGTH):
raise TypeError("salt_length must be an integer")
if salt_length is not self.MAX_LENGTH and salt_length < 0:
raise ValueError("salt_length must be zero or greater")
if salt_length is None and self._mgf._salt_length is None:
raise ValueError("You must supply salt_length")
self._salt_length = salt_length
@utils.register_interface(interfaces.AsymmetricPadding)
class OAEP(object):
name = "EME-OAEP"
def __init__(self, mgf, algorithm, label):
if not isinstance(algorithm, interfaces.HashAlgorithm):
raise TypeError("Expected instance of interfaces.HashAlgorithm.")
self._mgf = mgf
self._algorithm = algorithm
self._label = label
class MGF1(object):
MAX_LENGTH = object()
def __init__(self, algorithm, salt_length=None):
if not isinstance(algorithm, interfaces.HashAlgorithm):
raise TypeError("Expected instance of interfaces.HashAlgorithm.")
self._algorithm = algorithm
if salt_length is not None:
warnings.warn(
"salt_length is deprecated on MGF1 and should be passed to "
"the PSS constructor instead.",
utils.DeprecatedIn04
)
if (not isinstance(salt_length, six.integer_types) and
salt_length is not self.MAX_LENGTH):
raise TypeError("salt_length must be an integer")
if salt_length is not self.MAX_LENGTH and salt_length < 0:
raise ValueError("salt_length must be zero or greater")
self._salt_length = salt_length

View file

@ -0,0 +1,259 @@
# 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 UnsupportedAlgorithm, _Reasons
from cryptography.hazmat.backends.interfaces import RSABackend
from cryptography.hazmat.primitives import interfaces
@utils.register_interface(interfaces.RSAPublicKey)
class RSAPublicKey(object):
def __init__(self, public_exponent, modulus):
if (
not isinstance(public_exponent, six.integer_types) or
not isinstance(modulus, six.integer_types)
):
raise TypeError("RSAPublicKey arguments must be integers")
if modulus < 3:
raise ValueError("modulus must be >= 3")
if public_exponent < 3 or public_exponent >= modulus:
raise ValueError("public_exponent must be >= 3 and < modulus")
if public_exponent & 1 == 0:
raise ValueError("public_exponent must be odd")
self._public_exponent = public_exponent
self._modulus = modulus
def verifier(self, signature, padding, algorithm, backend):
if not isinstance(backend, RSABackend):
raise UnsupportedAlgorithm(
"Backend object does not implement RSABackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
return backend.create_rsa_verification_ctx(self, signature, padding,
algorithm)
def encrypt(self, plaintext, padding, backend):
if not isinstance(backend, RSABackend):
raise UnsupportedAlgorithm(
"Backend object does not implement RSABackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
return backend.encrypt_rsa(self, plaintext, padding)
@property
def key_size(self):
return utils.bit_length(self.modulus)
@property
def public_exponent(self):
return self._public_exponent
@property
def modulus(self):
return self._modulus
@property
def e(self):
return self.public_exponent
@property
def n(self):
return self.modulus
def _modinv(e, m):
"""
Modular Multiplicative Inverse. Returns x such that: (x*e) mod m == 1
"""
x1, y1, x2, y2 = 1, 0, 0, 1
a, b = e, m
while b > 0:
q, r = divmod(a, b)
xn, yn = x1 - q * x2, y1 - q * y2
a, b, x1, y1, x2, y2 = b, r, x2, y2, xn, yn
return x1 % m
def rsa_crt_iqmp(p, q):
"""
Compute the CRT (q ** -1) % p value from RSA primes p and q.
"""
return _modinv(q, p)
def rsa_crt_dmp1(private_exponent, p):
"""
Compute the CRT private_exponent % (p - 1) value from the RSA
private_exponent and p.
"""
return private_exponent % (p - 1)
def rsa_crt_dmq1(private_exponent, q):
"""
Compute the CRT private_exponent % (q - 1) value from the RSA
private_exponent and q.
"""
return private_exponent % (q - 1)
@utils.register_interface(interfaces.RSAPrivateKey)
class RSAPrivateKey(object):
def __init__(self, p, q, private_exponent, dmp1, dmq1, iqmp,
public_exponent, modulus):
if (
not isinstance(p, six.integer_types) or
not isinstance(q, six.integer_types) or
not isinstance(dmp1, six.integer_types) or
not isinstance(dmq1, six.integer_types) or
not isinstance(iqmp, six.integer_types) or
not isinstance(private_exponent, six.integer_types) or
not isinstance(public_exponent, six.integer_types) or
not isinstance(modulus, six.integer_types)
):
raise TypeError("RSAPrivateKey arguments must be integers")
if modulus < 3:
raise ValueError("modulus must be >= 3")
if p >= modulus:
raise ValueError("p must be < modulus")
if q >= modulus:
raise ValueError("q must be < modulus")
if dmp1 >= modulus:
raise ValueError("dmp1 must be < modulus")
if dmq1 >= modulus:
raise ValueError("dmq1 must be < modulus")
if iqmp >= modulus:
raise ValueError("iqmp must be < modulus")
if private_exponent >= modulus:
raise ValueError("private_exponent must be < modulus")
if public_exponent < 3 or public_exponent >= modulus:
raise ValueError("public_exponent must be >= 3 and < modulus")
if public_exponent & 1 == 0:
raise ValueError("public_exponent must be odd")
if dmp1 & 1 == 0:
raise ValueError("dmp1 must be odd")
if dmq1 & 1 == 0:
raise ValueError("dmq1 must be odd")
if p * q != modulus:
raise ValueError("p*q must equal modulus")
self._p = p
self._q = q
self._dmp1 = dmp1
self._dmq1 = dmq1
self._iqmp = iqmp
self._private_exponent = private_exponent
self._public_exponent = public_exponent
self._modulus = modulus
@classmethod
def generate(cls, public_exponent, key_size, backend):
if not isinstance(backend, RSABackend):
raise UnsupportedAlgorithm(
"Backend object does not implement RSABackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
return backend.generate_rsa_private_key(public_exponent, key_size)
def signer(self, padding, algorithm, backend):
if not isinstance(backend, RSABackend):
raise UnsupportedAlgorithm(
"Backend object does not implement RSABackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
return backend.create_rsa_signature_ctx(self, padding, algorithm)
def decrypt(self, ciphertext, padding, backend):
if not isinstance(backend, RSABackend):
raise UnsupportedAlgorithm(
"Backend object does not implement RSABackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
return backend.decrypt_rsa(self, ciphertext, padding)
@property
def key_size(self):
return utils.bit_length(self.modulus)
def public_key(self):
return RSAPublicKey(self.public_exponent, self.modulus)
@property
def p(self):
return self._p
@property
def q(self):
return self._q
@property
def private_exponent(self):
return self._private_exponent
@property
def public_exponent(self):
return self._public_exponent
@property
def modulus(self):
return self._modulus
@property
def d(self):
return self.private_exponent
@property
def dmp1(self):
return self._dmp1
@property
def dmq1(self):
return self._dmq1
@property
def iqmp(self):
return self._iqmp
@property
def e(self):
return self.public_exponent
@property
def n(self):
return self.modulus

View file

@ -0,0 +1,21 @@
# 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.primitives.ciphers.base import Cipher
__all__ = [
"Cipher",
]

View file

@ -0,0 +1,147 @@
# 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.hazmat.primitives import interfaces
def _verify_key_size(algorithm, key):
# Verify that the key size matches the expected key size
if len(key) * 8 not in algorithm.key_sizes:
raise ValueError("Invalid key size ({0}) for {1}".format(
len(key) * 8, algorithm.name
))
return key
@utils.register_interface(interfaces.BlockCipherAlgorithm)
@utils.register_interface(interfaces.CipherAlgorithm)
class AES(object):
name = "AES"
block_size = 128
key_sizes = frozenset([128, 192, 256])
def __init__(self, key):
self.key = _verify_key_size(self, key)
@property
def key_size(self):
return len(self.key) * 8
@utils.register_interface(interfaces.BlockCipherAlgorithm)
@utils.register_interface(interfaces.CipherAlgorithm)
class Camellia(object):
name = "camellia"
block_size = 128
key_sizes = frozenset([128, 192, 256])
def __init__(self, key):
self.key = _verify_key_size(self, key)
@property
def key_size(self):
return len(self.key) * 8
@utils.register_interface(interfaces.BlockCipherAlgorithm)
@utils.register_interface(interfaces.CipherAlgorithm)
class TripleDES(object):
name = "3DES"
block_size = 64
key_sizes = frozenset([64, 128, 192])
def __init__(self, key):
if len(key) == 8:
key += key + key
elif len(key) == 16:
key += key[:8]
self.key = _verify_key_size(self, key)
@property
def key_size(self):
return len(self.key) * 8
@utils.register_interface(interfaces.BlockCipherAlgorithm)
@utils.register_interface(interfaces.CipherAlgorithm)
class Blowfish(object):
name = "Blowfish"
block_size = 64
key_sizes = frozenset(range(32, 449, 8))
def __init__(self, key):
self.key = _verify_key_size(self, key)
@property
def key_size(self):
return len(self.key) * 8
@utils.register_interface(interfaces.BlockCipherAlgorithm)
@utils.register_interface(interfaces.CipherAlgorithm)
class CAST5(object):
name = "CAST5"
block_size = 64
key_sizes = frozenset(range(40, 129, 8))
def __init__(self, key):
self.key = _verify_key_size(self, key)
@property
def key_size(self):
return len(self.key) * 8
@utils.register_interface(interfaces.CipherAlgorithm)
class ARC4(object):
name = "RC4"
key_sizes = frozenset([40, 56, 64, 80, 128, 192, 256])
def __init__(self, key):
self.key = _verify_key_size(self, key)
@property
def key_size(self):
return len(self.key) * 8
@utils.register_interface(interfaces.CipherAlgorithm)
class IDEA(object):
name = "IDEA"
block_size = 64
key_sizes = frozenset([128])
def __init__(self, key):
self.key = _verify_key_size(self, key)
@property
def key_size(self):
return len(self.key) * 8
@utils.register_interface(interfaces.BlockCipherAlgorithm)
@utils.register_interface(interfaces.CipherAlgorithm)
class SEED(object):
name = "SEED"
block_size = 128
key_sizes = frozenset([128])
def __init__(self, key):
self.key = _verify_key_size(self, key)
@property
def key_size(self):
return len(self.key) * 8

View file

@ -0,0 +1,130 @@
# 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 (
AlreadyFinalized, AlreadyUpdated, NotYetFinalized, UnsupportedAlgorithm,
_Reasons
)
from cryptography.hazmat.backends.interfaces import CipherBackend
from cryptography.hazmat.primitives import interfaces
class Cipher(object):
def __init__(self, algorithm, mode, backend):
if not isinstance(backend, CipherBackend):
raise UnsupportedAlgorithm(
"Backend object does not implement CipherBackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
if not isinstance(algorithm, interfaces.CipherAlgorithm):
raise TypeError("Expected interface of interfaces.CipherAlgorithm")
if mode is not None:
mode.validate_for_algorithm(algorithm)
self.algorithm = algorithm
self.mode = mode
self._backend = backend
def encryptor(self):
if isinstance(self.mode, interfaces.ModeWithAuthenticationTag):
if self.mode.tag is not None:
raise ValueError(
"Authentication tag must be None when encrypting"
)
ctx = self._backend.create_symmetric_encryption_ctx(
self.algorithm, self.mode
)
return self._wrap_ctx(ctx, encrypt=True)
def decryptor(self):
if isinstance(self.mode, interfaces.ModeWithAuthenticationTag):
if self.mode.tag is None:
raise ValueError(
"Authentication tag must be provided when decrypting"
)
ctx = self._backend.create_symmetric_decryption_ctx(
self.algorithm, self.mode
)
return self._wrap_ctx(ctx, encrypt=False)
def _wrap_ctx(self, ctx, encrypt):
if isinstance(self.mode, interfaces.ModeWithAuthenticationTag):
if encrypt:
return _AEADEncryptionContext(ctx)
else:
return _AEADCipherContext(ctx)
else:
return _CipherContext(ctx)
@utils.register_interface(interfaces.CipherContext)
class _CipherContext(object):
def __init__(self, ctx):
self._ctx = ctx
def update(self, data):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
return self._ctx.update(data)
def finalize(self):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
data = self._ctx.finalize()
self._ctx = None
return data
@utils.register_interface(interfaces.AEADCipherContext)
@utils.register_interface(interfaces.CipherContext)
class _AEADCipherContext(object):
def __init__(self, ctx):
self._ctx = ctx
self._tag = None
self._updated = False
def update(self, data):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
self._updated = True
return self._ctx.update(data)
def finalize(self):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
data = self._ctx.finalize()
self._tag = self._ctx.tag
self._ctx = None
return data
def authenticate_additional_data(self, data):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
if self._updated:
raise AlreadyUpdated("Update has been called on this context")
self._ctx.authenticate_additional_data(data)
@utils.register_interface(interfaces.AEADEncryptionContext)
class _AEADEncryptionContext(_AEADCipherContext):
@property
def tag(self):
if self._ctx is not None:
raise NotYetFinalized("You must finalize encryption before "
"getting the tag")
return self._tag

View file

@ -0,0 +1,107 @@
# 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.hazmat.primitives import interfaces
@utils.register_interface(interfaces.Mode)
@utils.register_interface(interfaces.ModeWithInitializationVector)
class CBC(object):
name = "CBC"
def __init__(self, initialization_vector):
self.initialization_vector = initialization_vector
def validate_for_algorithm(self, algorithm):
if len(self.initialization_vector) * 8 != algorithm.block_size:
raise ValueError("Invalid iv size ({0}) for {1}".format(
len(self.initialization_vector), self.name
))
@utils.register_interface(interfaces.Mode)
class ECB(object):
name = "ECB"
def validate_for_algorithm(self, algorithm):
pass
@utils.register_interface(interfaces.Mode)
@utils.register_interface(interfaces.ModeWithInitializationVector)
class OFB(object):
name = "OFB"
def __init__(self, initialization_vector):
self.initialization_vector = initialization_vector
def validate_for_algorithm(self, algorithm):
if len(self.initialization_vector) * 8 != algorithm.block_size:
raise ValueError("Invalid iv size ({0}) for {1}".format(
len(self.initialization_vector), self.name
))
@utils.register_interface(interfaces.Mode)
@utils.register_interface(interfaces.ModeWithInitializationVector)
class CFB(object):
name = "CFB"
def __init__(self, initialization_vector):
self.initialization_vector = initialization_vector
def validate_for_algorithm(self, algorithm):
if len(self.initialization_vector) * 8 != algorithm.block_size:
raise ValueError("Invalid iv size ({0}) for {1}".format(
len(self.initialization_vector), self.name
))
@utils.register_interface(interfaces.Mode)
@utils.register_interface(interfaces.ModeWithNonce)
class CTR(object):
name = "CTR"
def __init__(self, nonce):
self.nonce = nonce
def validate_for_algorithm(self, algorithm):
if len(self.nonce) * 8 != algorithm.block_size:
raise ValueError("Invalid nonce size ({0}) for {1}".format(
len(self.nonce), self.name
))
@utils.register_interface(interfaces.Mode)
@utils.register_interface(interfaces.ModeWithInitializationVector)
@utils.register_interface(interfaces.ModeWithAuthenticationTag)
class GCM(object):
name = "GCM"
def __init__(self, initialization_vector, tag=None):
# len(initialization_vector) must in [1, 2 ** 64), but it's impossible
# to actually construct a bytes object that large, so we don't check
# for it
if tag is not None and len(tag) < 4:
raise ValueError(
"Authentication tag must be 4 bytes or longer"
)
self.initialization_vector = initialization_vector
self.tag = tag
def validate_for_algorithm(self, algorithm):
pass

View file

@ -0,0 +1,75 @@
# 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 (
AlreadyFinalized, InvalidSignature, UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.interfaces import CMACBackend
from cryptography.hazmat.primitives import constant_time, interfaces
@utils.register_interface(interfaces.CMACContext)
class CMAC(object):
def __init__(self, algorithm, backend, ctx=None):
if not isinstance(backend, CMACBackend):
raise UnsupportedAlgorithm(
"Backend object does not implement CMACBackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
if not isinstance(algorithm, interfaces.BlockCipherAlgorithm):
raise TypeError(
"Expected instance of interfaces.BlockCipherAlgorithm"
)
self._algorithm = algorithm
self._backend = backend
if ctx is None:
self._ctx = self._backend.create_cmac_ctx(self._algorithm)
else:
self._ctx = ctx
def update(self, data):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
if isinstance(data, six.text_type):
raise TypeError("Unicode-objects must be encoded before hashing")
self._ctx.update(data)
def finalize(self):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
digest = self._ctx.finalize()
self._ctx = None
return digest
def verify(self, signature):
if isinstance(signature, six.text_type):
raise TypeError("Unicode-objects must be encoded before verifying")
digest = self.finalize()
if not constant_time.bytes_eq(digest, signature):
raise InvalidSignature("Signature did not match digest.")
def copy(self):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
return CMAC(
self._algorithm,
backend=self._backend,
ctx=self._ctx.copy()
)

View file

@ -0,0 +1,63 @@
# 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 sys
import cffi
import six
from cryptography.hazmat.bindings.utils import _create_modulename
TYPES = """
uint8_t Cryptography_constant_time_bytes_eq(uint8_t *, size_t, uint8_t *,
size_t);
"""
FUNCTIONS = """
uint8_t Cryptography_constant_time_bytes_eq(uint8_t *a, size_t len_a,
uint8_t *b, size_t len_b) {
size_t i = 0;
uint8_t mismatch = 0;
if (len_a != len_b) {
return 0;
}
for (i = 0; i < len_a; i++) {
mismatch |= a[i] ^ b[i];
}
/* Make sure any bits set are copied to the lowest bit */
mismatch |= mismatch >> 4;
mismatch |= mismatch >> 2;
mismatch |= mismatch >> 1;
/* Now check the low bit to see if it's set */
return (mismatch & 1) == 0;
}
"""
_ffi = cffi.FFI()
_ffi.cdef(TYPES)
_lib = _ffi.verify(
source=FUNCTIONS,
modulename=_create_modulename([TYPES], FUNCTIONS, sys.version),
ext_package="cryptography",
)
def bytes_eq(a, b):
if isinstance(a, six.text_type) or isinstance(b, six.text_type):
raise TypeError("Unicode-objects must be encoded before comparing")
return _lib.Cryptography_constant_time_bytes_eq(a, len(a), b, len(b)) == 1

View file

@ -0,0 +1,121 @@
# 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 (
AlreadyFinalized, UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.interfaces import HashBackend
from cryptography.hazmat.primitives import interfaces
@utils.register_interface(interfaces.HashContext)
class Hash(object):
def __init__(self, algorithm, backend, ctx=None):
if not isinstance(backend, HashBackend):
raise UnsupportedAlgorithm(
"Backend object does not implement HashBackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
if not isinstance(algorithm, interfaces.HashAlgorithm):
raise TypeError("Expected instance of interfaces.HashAlgorithm.")
self.algorithm = algorithm
self._backend = backend
if ctx is None:
self._ctx = self._backend.create_hash_ctx(self.algorithm)
else:
self._ctx = ctx
def update(self, data):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
if isinstance(data, six.text_type):
raise TypeError("Unicode-objects must be encoded before hashing")
self._ctx.update(data)
def copy(self):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
return Hash(
self.algorithm, backend=self._backend, ctx=self._ctx.copy()
)
def finalize(self):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
digest = self._ctx.finalize()
self._ctx = None
return digest
@utils.register_interface(interfaces.HashAlgorithm)
class SHA1(object):
name = "sha1"
digest_size = 20
block_size = 64
@utils.register_interface(interfaces.HashAlgorithm)
class SHA224(object):
name = "sha224"
digest_size = 28
block_size = 64
@utils.register_interface(interfaces.HashAlgorithm)
class SHA256(object):
name = "sha256"
digest_size = 32
block_size = 64
@utils.register_interface(interfaces.HashAlgorithm)
class SHA384(object):
name = "sha384"
digest_size = 48
block_size = 128
@utils.register_interface(interfaces.HashAlgorithm)
class SHA512(object):
name = "sha512"
digest_size = 64
block_size = 128
@utils.register_interface(interfaces.HashAlgorithm)
class RIPEMD160(object):
name = "ripemd160"
digest_size = 20
block_size = 64
@utils.register_interface(interfaces.HashAlgorithm)
class Whirlpool(object):
name = "whirlpool"
digest_size = 64
block_size = 64
@utils.register_interface(interfaces.HashAlgorithm)
class MD5(object):
name = "md5"
digest_size = 16
block_size = 64

View file

@ -0,0 +1,75 @@
# 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 (
AlreadyFinalized, InvalidSignature, UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.interfaces import HMACBackend
from cryptography.hazmat.primitives import constant_time, interfaces
@utils.register_interface(interfaces.HashContext)
class HMAC(object):
def __init__(self, key, algorithm, backend, ctx=None):
if not isinstance(backend, HMACBackend):
raise UnsupportedAlgorithm(
"Backend object does not implement HMACBackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
if not isinstance(algorithm, interfaces.HashAlgorithm):
raise TypeError("Expected instance of interfaces.HashAlgorithm.")
self.algorithm = algorithm
self._backend = backend
self._key = key
if ctx is None:
self._ctx = self._backend.create_hmac_ctx(key, self.algorithm)
else:
self._ctx = ctx
def update(self, msg):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
if isinstance(msg, six.text_type):
raise TypeError("Unicode-objects must be encoded before hashing")
self._ctx.update(msg)
def copy(self):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
return HMAC(
self._key,
self.algorithm,
backend=self._backend,
ctx=self._ctx.copy()
)
def finalize(self):
if self._ctx is None:
raise AlreadyFinalized("Context was already finalized")
digest = self._ctx.finalize()
self._ctx = None
return digest
def verify(self, signature):
if isinstance(signature, six.text_type):
raise TypeError("Unicode-objects must be encoded before verifying")
digest = self.finalize()
if not constant_time.bytes_eq(digest, signature):
raise InvalidSignature("Signature did not match digest.")

View file

@ -0,0 +1,491 @@
# 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 CipherAlgorithm(object):
@abc.abstractproperty
def name(self):
"""
A string naming this mode (e.g. "AES", "Camellia").
"""
@abc.abstractproperty
def key_size(self):
"""
The size of the key being used as an integer in bits (e.g. 128, 256).
"""
@six.add_metaclass(abc.ABCMeta)
class BlockCipherAlgorithm(object):
@abc.abstractproperty
def block_size(self):
"""
The size of a block as an integer in bits (e.g. 64, 128).
"""
@six.add_metaclass(abc.ABCMeta)
class Mode(object):
@abc.abstractproperty
def name(self):
"""
A string naming this mode (e.g. "ECB", "CBC").
"""
@abc.abstractmethod
def validate_for_algorithm(self, algorithm):
"""
Checks that all the necessary invariants of this (mode, algorithm)
combination are met.
"""
@six.add_metaclass(abc.ABCMeta)
class ModeWithInitializationVector(object):
@abc.abstractproperty
def initialization_vector(self):
"""
The value of the initialization vector for this mode as bytes.
"""
@six.add_metaclass(abc.ABCMeta)
class ModeWithNonce(object):
@abc.abstractproperty
def nonce(self):
"""
The value of the nonce for this mode as bytes.
"""
@six.add_metaclass(abc.ABCMeta)
class ModeWithAuthenticationTag(object):
@abc.abstractproperty
def tag(self):
"""
The value of the tag supplied to the constructor of this mode.
"""
@six.add_metaclass(abc.ABCMeta)
class CipherContext(object):
@abc.abstractmethod
def update(self, data):
"""
Processes the provided bytes through the cipher and returns the results
as bytes.
"""
@abc.abstractmethod
def finalize(self):
"""
Returns the results of processing the final block as bytes.
"""
@six.add_metaclass(abc.ABCMeta)
class AEADCipherContext(object):
@abc.abstractmethod
def authenticate_additional_data(self, data):
"""
Authenticates the provided bytes.
"""
@six.add_metaclass(abc.ABCMeta)
class AEADEncryptionContext(object):
@abc.abstractproperty
def tag(self):
"""
Returns tag bytes. This is only available after encryption is
finalized.
"""
@six.add_metaclass(abc.ABCMeta)
class PaddingContext(object):
@abc.abstractmethod
def update(self, data):
"""
Pads the provided bytes and returns any available data as bytes.
"""
@abc.abstractmethod
def finalize(self):
"""
Finalize the padding, returns bytes.
"""
@six.add_metaclass(abc.ABCMeta)
class HashAlgorithm(object):
@abc.abstractproperty
def name(self):
"""
A string naming this algorithm (e.g. "sha256", "md5").
"""
@abc.abstractproperty
def digest_size(self):
"""
The size of the resulting digest in bytes.
"""
@abc.abstractproperty
def block_size(self):
"""
The internal block size of the hash algorithm in bytes.
"""
@six.add_metaclass(abc.ABCMeta)
class HashContext(object):
@abc.abstractproperty
def algorithm(self):
"""
A HashAlgorithm that will be used by this context.
"""
@abc.abstractmethod
def update(self, data):
"""
Processes the provided bytes through the hash.
"""
@abc.abstractmethod
def finalize(self):
"""
Finalizes the hash context and returns the hash digest as bytes.
"""
@abc.abstractmethod
def copy(self):
"""
Return a HashContext that is a copy of the current context.
"""
@six.add_metaclass(abc.ABCMeta)
class RSAPrivateKey(object):
@abc.abstractmethod
def signer(self, padding, algorithm, backend):
"""
Returns an AsymmetricSignatureContext used for signing data.
"""
@abc.abstractproperty
def modulus(self):
"""
The public modulus of the RSA key.
"""
@abc.abstractproperty
def public_exponent(self):
"""
The public exponent of the RSA key.
"""
@abc.abstractproperty
def private_exponent(self):
"""
The private exponent of the RSA key.
"""
@abc.abstractproperty
def key_size(self):
"""
The bit length of the public modulus.
"""
@abc.abstractmethod
def public_key(self):
"""
The RSAPublicKey associated with this private key.
"""
@abc.abstractproperty
def n(self):
"""
The public modulus of the RSA key. Alias for modulus.
"""
@abc.abstractproperty
def p(self):
"""
One of the two primes used to generate d.
"""
@abc.abstractproperty
def q(self):
"""
One of the two primes used to generate d.
"""
@abc.abstractproperty
def d(self):
"""
The private exponent. This can be calculated using p and q. Alias for
private_exponent.
"""
@abc.abstractproperty
def dmp1(self):
"""
A Chinese remainder theorem coefficient used to speed up RSA
calculations. Calculated as: d mod (p-1)
"""
@abc.abstractproperty
def dmq1(self):
"""
A Chinese remainder theorem coefficient used to speed up RSA
calculations. Calculated as: d mod (q-1)
"""
@abc.abstractproperty
def iqmp(self):
"""
A Chinese remainder theorem coefficient used to speed up RSA
calculations. The modular inverse of q modulo p
"""
@abc.abstractproperty
def e(self):
"""
The public exponent of the RSA key. Alias for public_exponent.
"""
@six.add_metaclass(abc.ABCMeta)
class RSAPublicKey(object):
@abc.abstractmethod
def verifier(self, signature, padding, algorithm, backend):
"""
Returns an AsymmetricVerificationContext used for verifying signatures.
"""
@abc.abstractproperty
def modulus(self):
"""
The public modulus of the RSA key.
"""
@abc.abstractproperty
def public_exponent(self):
"""
The public exponent of the RSA key.
"""
@abc.abstractproperty
def key_size(self):
"""
The bit length of the public modulus.
"""
@abc.abstractproperty
def n(self):
"""
The public modulus of the RSA key. Alias for modulus.
"""
@abc.abstractproperty
def e(self):
"""
The public exponent of the RSA key. Alias for public_exponent.
"""
@six.add_metaclass(abc.ABCMeta)
class DSAParameters(object):
@abc.abstractproperty
def modulus(self):
"""
The prime modulus that's used in generating the DSA keypair and used
in the DSA signing and verification processes.
"""
@abc.abstractproperty
def subgroup_order(self):
"""
The subgroup order that's used in generating the DSA keypair
by the generator and used in the DSA signing and verification
processes.
"""
@abc.abstractproperty
def generator(self):
"""
The generator that is used in generating the DSA keypair and used
in the DSA signing and verification processes.
"""
@abc.abstractproperty
def p(self):
"""
The prime modulus that's used in generating the DSA keypair and used
in the DSA signing and verification processes. Alias for modulus.
"""
@abc.abstractproperty
def q(self):
"""
The subgroup order that's used in generating the DSA keypair
by the generator and used in the DSA signing and verification
processes. Alias for subgroup_order.
"""
@abc.abstractproperty
def g(self):
"""
The generator that is used in generating the DSA keypair and used
in the DSA signing and verification processes. Alias for generator.
"""
@six.add_metaclass(abc.ABCMeta)
class DSAPrivateKey(object):
@abc.abstractproperty
def key_size(self):
"""
The bit length of the prime modulus.
"""
@abc.abstractmethod
def public_key(self):
"""
The DSAPublicKey associated with this private key.
"""
@abc.abstractproperty
def x(self):
"""
The private key "x" in the DSA structure.
"""
@abc.abstractproperty
def y(self):
"""
The public key.
"""
@abc.abstractmethod
def parameters(self):
"""
The DSAParameters object associated with this private key.
"""
@six.add_metaclass(abc.ABCMeta)
class DSAPublicKey(object):
@abc.abstractproperty
def key_size(self):
"""
The bit length of the prime modulus.
"""
@abc.abstractproperty
def y(self):
"""
The public key.
"""
@abc.abstractmethod
def parameters(self):
"""
The DSAParameters object associated with this public key.
"""
@six.add_metaclass(abc.ABCMeta)
class AsymmetricSignatureContext(object):
@abc.abstractmethod
def update(self, data):
"""
Processes the provided bytes and returns nothing.
"""
@abc.abstractmethod
def finalize(self):
"""
Returns the signature as bytes.
"""
@six.add_metaclass(abc.ABCMeta)
class AsymmetricVerificationContext(object):
@abc.abstractmethod
def update(self, data):
"""
Processes the provided bytes and returns nothing.
"""
@abc.abstractmethod
def verify(self):
"""
Raises an exception if the bytes provided to update do not match the
signature or the signature does not match the public key.
"""
@six.add_metaclass(abc.ABCMeta)
class AsymmetricPadding(object):
@abc.abstractproperty
def name(self):
"""
A string naming this padding (e.g. "PSS", "PKCS1").
"""
@six.add_metaclass(abc.ABCMeta)
class KeyDerivationFunction(object):
@abc.abstractmethod
def derive(self, key_material):
"""
Deterministically generates and returns a new key based on the existing
key material.
"""
@abc.abstractmethod
def verify(self, key_material, expected_key):
"""
Checks whether the key generated by the key material matches the
expected derived key. Raises an exception if they do not match.
"""
@six.add_metaclass(abc.ABCMeta)
class CMACContext(object):
@abc.abstractmethod
def update(self, data):
"""
Processes the provided bytes.
"""
def finalize(self):
"""
Returns the message authentication code as bytes.
"""
@abc.abstractmethod
def copy(self):
"""
Return a CMACContext that is a copy of the current context.
"""

View file

@ -0,0 +1,14 @@
# 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

View file

@ -0,0 +1,102 @@
# 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 (
AlreadyFinalized, InvalidKey, UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.interfaces import HMACBackend
from cryptography.hazmat.primitives import constant_time, hmac, interfaces
@utils.register_interface(interfaces.KeyDerivationFunction)
class HKDF(object):
def __init__(self, algorithm, length, salt, info, backend):
if not isinstance(backend, HMACBackend):
raise UnsupportedAlgorithm(
"Backend object does not implement HMACBackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
self._algorithm = algorithm
max_length = 255 * (algorithm.digest_size // 8)
if length > max_length:
raise ValueError(
"Can not derive keys larger than {0} octets.".format(
max_length
))
self._length = length
if isinstance(salt, six.text_type):
raise TypeError(
"Unicode-objects must be encoded before using them as a salt.")
if salt is None:
salt = b"\x00" * (self._algorithm.digest_size // 8)
self._salt = salt
if isinstance(info, six.text_type):
raise TypeError(
"Unicode-objects must be encoded before using them as info.")
if info is None:
info = b""
self._info = info
self._backend = backend
self._used = False
def _extract(self, key_material):
h = hmac.HMAC(self._salt, self._algorithm, backend=self._backend)
h.update(key_material)
return h.finalize()
def _expand(self, key_material):
output = [b""]
counter = 1
while (self._algorithm.digest_size // 8) * len(output) < self._length:
h = hmac.HMAC(key_material, self._algorithm, backend=self._backend)
h.update(output[-1])
h.update(self._info)
h.update(six.int2byte(counter))
output.append(h.finalize())
counter += 1
return b"".join(output)[:self._length]
def derive(self, key_material):
if isinstance(key_material, six.text_type):
raise TypeError(
"Unicode-objects must be encoded before using them as key "
"material."
)
if self._used:
raise AlreadyFinalized
self._used = True
return self._expand(self._extract(key_material))
def verify(self, key_material, expected_key):
if not constant_time.bytes_eq(self.derive(key_material), expected_key):
raise InvalidKey

View file

@ -0,0 +1,74 @@
# 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 (
AlreadyFinalized, InvalidKey, UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.interfaces import PBKDF2HMACBackend
from cryptography.hazmat.primitives import constant_time, interfaces
@utils.register_interface(interfaces.KeyDerivationFunction)
class PBKDF2HMAC(object):
def __init__(self, algorithm, length, salt, iterations, backend):
if not isinstance(backend, PBKDF2HMACBackend):
raise UnsupportedAlgorithm(
"Backend object does not implement PBKDF2HMACBackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
if not backend.pbkdf2_hmac_supported(algorithm):
raise UnsupportedAlgorithm(
"{0} is not supported for PBKDF2 by this backend".format(
algorithm.name),
_Reasons.UNSUPPORTED_HASH
)
self._used = False
self._algorithm = algorithm
self._length = length
if isinstance(salt, six.text_type):
raise TypeError(
"Unicode-objects must be encoded before using them as key "
"material."
)
self._salt = salt
self._iterations = iterations
self._backend = backend
def derive(self, key_material):
if self._used:
raise AlreadyFinalized("PBKDF2 instances can only be used once")
self._used = True
if isinstance(key_material, six.text_type):
raise TypeError(
"Unicode-objects must be encoded before using them as key "
"material."
)
return self._backend.derive_pbkdf2_hmac(
self._algorithm,
self._length,
self._salt,
self._iterations,
key_material
)
def verify(self, key_material, expected_key):
derived_key = self.derive(key_material)
if not constant_time.bytes_eq(derived_key, expected_key):
raise InvalidKey("Keys do not match.")

View file

@ -0,0 +1,172 @@
# 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 sys
import cffi
import six
from cryptography import utils
from cryptography.exceptions import AlreadyFinalized
from cryptography.hazmat.bindings.utils import _create_modulename
from cryptography.hazmat.primitives import interfaces
TYPES = """
uint8_t Cryptography_check_pkcs7_padding(const uint8_t *, uint8_t);
"""
FUNCTIONS = """
/* Returns the value of the input with the most-significant-bit copied to all
of the bits. */
static uint8_t Cryptography_DUPLICATE_MSB_TO_ALL(uint8_t a) {
return (1 - (a >> (sizeof(uint8_t) * 8 - 1))) - 1;
}
/* This returns 0xFF if a < b else 0x00, but does so in a constant time
fashion */
static uint8_t Cryptography_constant_time_lt(uint8_t a, uint8_t b) {
a -= b;
return Cryptography_DUPLICATE_MSB_TO_ALL(a);
}
uint8_t Cryptography_check_pkcs7_padding(const uint8_t *data,
uint8_t block_len) {
uint8_t i;
uint8_t pad_size = data[block_len - 1];
uint8_t mismatch = 0;
for (i = 0; i < block_len; i++) {
unsigned int mask = Cryptography_constant_time_lt(i, pad_size);
uint8_t b = data[block_len - 1 - i];
mismatch |= (mask & (pad_size ^ b));
}
/* Check to make sure the pad_size was within the valid range. */
mismatch |= ~Cryptography_constant_time_lt(0, pad_size);
mismatch |= Cryptography_constant_time_lt(block_len, pad_size);
/* Make sure any bits set are copied to the lowest bit */
mismatch |= mismatch >> 4;
mismatch |= mismatch >> 2;
mismatch |= mismatch >> 1;
/* Now check the low bit to see if it's set */
return (mismatch & 1) == 0;
}
"""
_ffi = cffi.FFI()
_ffi.cdef(TYPES)
_lib = _ffi.verify(
source=FUNCTIONS,
modulename=_create_modulename([TYPES], FUNCTIONS, sys.version),
ext_package="cryptography",
)
class PKCS7(object):
def __init__(self, block_size):
if not (0 <= block_size < 256):
raise ValueError("block_size must be in range(0, 256)")
if block_size % 8 != 0:
raise ValueError("block_size must be a multiple of 8")
self.block_size = block_size
def padder(self):
return _PKCS7PaddingContext(self.block_size)
def unpadder(self):
return _PKCS7UnpaddingContext(self.block_size)
@utils.register_interface(interfaces.PaddingContext)
class _PKCS7PaddingContext(object):
def __init__(self, block_size):
self.block_size = block_size
# TODO: more copies than necessary, we should use zero-buffer (#193)
self._buffer = b""
def update(self, data):
if self._buffer is None:
raise AlreadyFinalized("Context was already finalized")
if isinstance(data, six.text_type):
raise TypeError("Unicode-objects must be encoded before padding")
self._buffer += data
finished_blocks = len(self._buffer) // (self.block_size // 8)
result = self._buffer[:finished_blocks * (self.block_size // 8)]
self._buffer = self._buffer[finished_blocks * (self.block_size // 8):]
return result
def finalize(self):
if self._buffer is None:
raise AlreadyFinalized("Context was already finalized")
pad_size = self.block_size // 8 - len(self._buffer)
result = self._buffer + six.int2byte(pad_size) * pad_size
self._buffer = None
return result
@utils.register_interface(interfaces.PaddingContext)
class _PKCS7UnpaddingContext(object):
def __init__(self, block_size):
self.block_size = block_size
# TODO: more copies than necessary, we should use zero-buffer (#193)
self._buffer = b""
def update(self, data):
if self._buffer is None:
raise AlreadyFinalized("Context was already finalized")
if isinstance(data, six.text_type):
raise TypeError("Unicode-objects must be encoded before unpadding")
self._buffer += data
finished_blocks = max(
len(self._buffer) // (self.block_size // 8) - 1,
0
)
result = self._buffer[:finished_blocks * (self.block_size // 8)]
self._buffer = self._buffer[finished_blocks * (self.block_size // 8):]
return result
def finalize(self):
if self._buffer is None:
raise AlreadyFinalized("Context was already finalized")
if len(self._buffer) != self.block_size // 8:
raise ValueError("Invalid padding bytes")
valid = _lib.Cryptography_check_pkcs7_padding(
self._buffer, self.block_size // 8
)
if not valid:
raise ValueError("Invalid padding bytes")
pad_size = six.indexbytes(self._buffer, -1)
res = self._buffer[:-pad_size]
self._buffer = None
return res

View file

@ -0,0 +1,14 @@
# 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

View file

@ -0,0 +1,71 @@
# 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 struct
import six
from cryptography.exceptions import (
InvalidToken, UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.interfaces import HMACBackend
from cryptography.hazmat.primitives import constant_time, hmac
from cryptography.hazmat.primitives.hashes import SHA1, SHA256, SHA512
class HOTP(object):
def __init__(self, key, length, algorithm, backend):
if not isinstance(backend, HMACBackend):
raise UnsupportedAlgorithm(
"Backend object does not implement HMACBackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
if len(key) < 16:
raise ValueError("Key length has to be at least 128 bits.")
if not isinstance(length, six.integer_types):
raise TypeError("Length parameter must be an integer type")
if length < 6 or length > 8:
raise ValueError("Length of HOTP has to be between 6 to 8.")
if not isinstance(algorithm, (SHA1, SHA256, SHA512)):
raise TypeError("Algorithm must be SHA1, SHA256 or SHA512")
self._key = key
self._length = length
self._algorithm = algorithm
self._backend = backend
def generate(self, counter):
truncated_value = self._dynamic_truncate(counter)
hotp = truncated_value % (10 ** self._length)
return "{0:0{1}}".format(hotp, self._length).encode()
def verify(self, hotp, counter):
if not constant_time.bytes_eq(self.generate(counter), hotp):
raise InvalidToken("Supplied HOTP value does not match")
def _dynamic_truncate(self, counter):
ctx = hmac.HMAC(self._key, self._algorithm, self._backend)
ctx.update(struct.pack(">Q", counter))
hmac_value = ctx.finalize()
offset_bits = six.indexbytes(hmac_value, len(hmac_value) - 1) & 0b1111
offset = int(offset_bits)
p = hmac_value[offset:offset + 4]
return struct.unpack(">I", p)[0] & 0x7fffffff

View file

@ -0,0 +1,41 @@
# 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.exceptions import (
InvalidToken, UnsupportedAlgorithm, _Reasons
)
from cryptography.hazmat.backends.interfaces import HMACBackend
from cryptography.hazmat.primitives import constant_time
from cryptography.hazmat.primitives.twofactor.hotp import HOTP
class TOTP(object):
def __init__(self, key, length, algorithm, time_step, backend):
if not isinstance(backend, HMACBackend):
raise UnsupportedAlgorithm(
"Backend object does not implement HMACBackend",
_Reasons.BACKEND_MISSING_INTERFACE
)
self._time_step = time_step
self._hotp = HOTP(key, length, algorithm, backend)
def generate(self, time):
counter = int(time / self._time_step)
return self._hotp.generate(counter)
def verify(self, totp, time):
if not constant_time.bytes_eq(self.generate(time), totp):
raise InvalidToken("Supplied TOTP value does not match")

View file

@ -0,0 +1,33 @@
# 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 sys
DeprecatedIn04 = PendingDeprecationWarning
def register_interface(iface):
def register_decorator(klass):
iface.register(klass)
return klass
return register_decorator
def bit_length(x):
if sys.version_info >= (2, 7):
return x.bit_length()
else:
return len(bin(x)) - (2 + (x <= 0))