From c62a78c015cf7aeb0c05bce82ef14cd86fe0b0fc Mon Sep 17 00:00:00 2001 From: Donald Stufft Date: Fri, 7 Nov 2014 19:17:08 -0500 Subject: Move the cryptography package into a src/ subdirectory Due to differences in how py.test determines which module to ``import`` the test suite actually runs against the cryptography which is in the *current* directory instead of the cryptography which is installed. The problem essentially boils down to when there is a tests/__init__.py then py.test adds the current directory to the front of the sys.path, causing it to take precedence over the installed location. This means that running the tests relies on the implicit compile that CFFI does instead of testing against what people will actually be runnning, which is the module compiled by setup.py. --- .coveragerc | 2 +- MANIFEST.in | 2 +- cryptography/__about__.py | 31 - cryptography/__init__.py | 25 - cryptography/exceptions.py | 63 -- cryptography/fernet.py | 150 --- cryptography/hazmat/__init__.py | 14 - cryptography/hazmat/backends/__init__.py | 46 - .../hazmat/backends/commoncrypto/__init__.py | 19 - .../hazmat/backends/commoncrypto/backend.py | 253 ----- .../hazmat/backends/commoncrypto/ciphers.py | 201 ---- .../hazmat/backends/commoncrypto/hashes.py | 64 -- cryptography/hazmat/backends/commoncrypto/hmac.py | 68 -- cryptography/hazmat/backends/interfaces.py | 261 ----- cryptography/hazmat/backends/multibackend.py | 358 ------- cryptography/hazmat/backends/openssl/__init__.py | 19 - cryptography/hazmat/backends/openssl/backend.py | 1036 -------------------- cryptography/hazmat/backends/openssl/ciphers.py | 225 ----- cryptography/hazmat/backends/openssl/cmac.py | 89 -- cryptography/hazmat/backends/openssl/dsa.py | 207 ---- cryptography/hazmat/backends/openssl/ec.py | 234 ----- cryptography/hazmat/backends/openssl/hashes.py | 71 -- cryptography/hazmat/backends/openssl/hmac.py | 90 -- cryptography/hazmat/backends/openssl/rsa.py | 603 ------------ cryptography/hazmat/backends/openssl/utils.py | 35 - cryptography/hazmat/bindings/__init__.py | 14 - .../hazmat/bindings/commoncrypto/__init__.py | 14 - .../hazmat/bindings/commoncrypto/binding.py | 60 -- cryptography/hazmat/bindings/commoncrypto/cf.py | 114 --- .../hazmat/bindings/commoncrypto/common_cryptor.py | 110 --- .../hazmat/bindings/commoncrypto/common_digest.py | 69 -- .../hazmat/bindings/commoncrypto/common_hmac.py | 48 - .../bindings/commoncrypto/common_key_derivation.py | 50 - .../hazmat/bindings/commoncrypto/secimport.py | 95 -- .../hazmat/bindings/commoncrypto/secitem.py | 38 - .../hazmat/bindings/commoncrypto/seckey.py | 35 - .../hazmat/bindings/commoncrypto/seckeychain.py | 36 - .../hazmat/bindings/commoncrypto/sectransform.py | 79 -- cryptography/hazmat/bindings/openssl/__init__.py | 14 - cryptography/hazmat/bindings/openssl/aes.py | 70 -- cryptography/hazmat/bindings/openssl/asn1.py | 152 --- cryptography/hazmat/bindings/openssl/bignum.py | 114 --- cryptography/hazmat/bindings/openssl/binding.py | 176 ---- cryptography/hazmat/bindings/openssl/bio.py | 181 ---- cryptography/hazmat/bindings/openssl/cmac.py | 65 -- cryptography/hazmat/bindings/openssl/cms.py | 100 -- cryptography/hazmat/bindings/openssl/conf.py | 35 - cryptography/hazmat/bindings/openssl/crypto.py | 67 -- cryptography/hazmat/bindings/openssl/dh.py | 57 -- cryptography/hazmat/bindings/openssl/dsa.py | 65 -- cryptography/hazmat/bindings/openssl/ec.py | 490 --------- cryptography/hazmat/bindings/openssl/ecdh.py | 68 -- cryptography/hazmat/bindings/openssl/ecdsa.py | 130 --- cryptography/hazmat/bindings/openssl/engine.py | 165 ---- cryptography/hazmat/bindings/openssl/err.py | 365 ------- cryptography/hazmat/bindings/openssl/evp.py | 263 ----- cryptography/hazmat/bindings/openssl/hmac.py | 94 -- cryptography/hazmat/bindings/openssl/nid.py | 241 ----- cryptography/hazmat/bindings/openssl/objects.py | 45 - cryptography/hazmat/bindings/openssl/opensslv.py | 36 - .../hazmat/bindings/openssl/osrandom_engine.py | 218 ---- cryptography/hazmat/bindings/openssl/pem.py | 89 -- cryptography/hazmat/bindings/openssl/pkcs12.py | 41 - cryptography/hazmat/bindings/openssl/pkcs7.py | 41 - cryptography/hazmat/bindings/openssl/rand.py | 45 - cryptography/hazmat/bindings/openssl/rsa.py | 108 -- cryptography/hazmat/bindings/openssl/ssl.py | 620 ------------ cryptography/hazmat/bindings/openssl/x509.py | 273 ------ cryptography/hazmat/bindings/openssl/x509_vfy.py | 336 ------- cryptography/hazmat/bindings/openssl/x509name.py | 61 -- cryptography/hazmat/bindings/openssl/x509v3.py | 103 -- cryptography/hazmat/bindings/utils.py | 144 --- cryptography/hazmat/primitives/__init__.py | 14 - .../hazmat/primitives/asymmetric/__init__.py | 14 - cryptography/hazmat/primitives/asymmetric/dsa.py | 108 -- cryptography/hazmat/primitives/asymmetric/ec.py | 195 ---- .../hazmat/primitives/asymmetric/padding.py | 65 -- cryptography/hazmat/primitives/asymmetric/rsa.py | 191 ---- cryptography/hazmat/primitives/ciphers/__init__.py | 21 - .../hazmat/primitives/ciphers/algorithms.py | 147 --- cryptography/hazmat/primitives/ciphers/base.py | 132 --- cryptography/hazmat/primitives/ciphers/modes.py | 125 --- cryptography/hazmat/primitives/cmac.py | 75 -- cryptography/hazmat/primitives/constant_time.py | 47 - cryptography/hazmat/primitives/hashes.py | 121 --- cryptography/hazmat/primitives/hmac.py | 78 -- cryptography/hazmat/primitives/interfaces.py | 499 ---------- cryptography/hazmat/primitives/kdf/__init__.py | 14 - cryptography/hazmat/primitives/kdf/hkdf.py | 124 --- cryptography/hazmat/primitives/kdf/pbkdf2.py | 66 -- cryptography/hazmat/primitives/padding.py | 164 ---- cryptography/hazmat/primitives/serialization.py | 50 - cryptography/hazmat/primitives/src/constant_time.c | 31 - cryptography/hazmat/primitives/src/constant_time.h | 16 - .../hazmat/primitives/twofactor/__init__.py | 14 - cryptography/hazmat/primitives/twofactor/hotp.py | 69 -- cryptography/hazmat/primitives/twofactor/totp.py | 41 - cryptography/utils.py | 64 -- docs/conf.py | 2 +- setup.py | 10 +- src/cryptography/__about__.py | 31 + src/cryptography/__init__.py | 25 + src/cryptography/exceptions.py | 63 ++ src/cryptography/fernet.py | 150 +++ src/cryptography/hazmat/__init__.py | 14 + src/cryptography/hazmat/backends/__init__.py | 46 + .../hazmat/backends/commoncrypto/__init__.py | 19 + .../hazmat/backends/commoncrypto/backend.py | 253 +++++ .../hazmat/backends/commoncrypto/ciphers.py | 201 ++++ .../hazmat/backends/commoncrypto/hashes.py | 64 ++ .../hazmat/backends/commoncrypto/hmac.py | 68 ++ src/cryptography/hazmat/backends/interfaces.py | 261 +++++ src/cryptography/hazmat/backends/multibackend.py | 358 +++++++ .../hazmat/backends/openssl/__init__.py | 19 + .../hazmat/backends/openssl/backend.py | 1036 ++++++++++++++++++++ .../hazmat/backends/openssl/ciphers.py | 225 +++++ src/cryptography/hazmat/backends/openssl/cmac.py | 89 ++ src/cryptography/hazmat/backends/openssl/dsa.py | 207 ++++ src/cryptography/hazmat/backends/openssl/ec.py | 234 +++++ src/cryptography/hazmat/backends/openssl/hashes.py | 71 ++ src/cryptography/hazmat/backends/openssl/hmac.py | 90 ++ src/cryptography/hazmat/backends/openssl/rsa.py | 603 ++++++++++++ src/cryptography/hazmat/backends/openssl/utils.py | 35 + src/cryptography/hazmat/bindings/__init__.py | 14 + .../hazmat/bindings/commoncrypto/__init__.py | 14 + .../hazmat/bindings/commoncrypto/binding.py | 60 ++ .../hazmat/bindings/commoncrypto/cf.py | 114 +++ .../hazmat/bindings/commoncrypto/common_cryptor.py | 110 +++ .../hazmat/bindings/commoncrypto/common_digest.py | 69 ++ .../hazmat/bindings/commoncrypto/common_hmac.py | 48 + .../bindings/commoncrypto/common_key_derivation.py | 50 + .../hazmat/bindings/commoncrypto/secimport.py | 95 ++ .../hazmat/bindings/commoncrypto/secitem.py | 38 + .../hazmat/bindings/commoncrypto/seckey.py | 35 + .../hazmat/bindings/commoncrypto/seckeychain.py | 36 + .../hazmat/bindings/commoncrypto/sectransform.py | 79 ++ .../hazmat/bindings/openssl/__init__.py | 14 + src/cryptography/hazmat/bindings/openssl/aes.py | 70 ++ src/cryptography/hazmat/bindings/openssl/asn1.py | 152 +++ src/cryptography/hazmat/bindings/openssl/bignum.py | 114 +++ .../hazmat/bindings/openssl/binding.py | 176 ++++ src/cryptography/hazmat/bindings/openssl/bio.py | 181 ++++ src/cryptography/hazmat/bindings/openssl/cmac.py | 65 ++ src/cryptography/hazmat/bindings/openssl/cms.py | 100 ++ src/cryptography/hazmat/bindings/openssl/conf.py | 35 + src/cryptography/hazmat/bindings/openssl/crypto.py | 67 ++ src/cryptography/hazmat/bindings/openssl/dh.py | 57 ++ src/cryptography/hazmat/bindings/openssl/dsa.py | 65 ++ src/cryptography/hazmat/bindings/openssl/ec.py | 490 +++++++++ src/cryptography/hazmat/bindings/openssl/ecdh.py | 68 ++ src/cryptography/hazmat/bindings/openssl/ecdsa.py | 130 +++ src/cryptography/hazmat/bindings/openssl/engine.py | 165 ++++ src/cryptography/hazmat/bindings/openssl/err.py | 365 +++++++ src/cryptography/hazmat/bindings/openssl/evp.py | 263 +++++ src/cryptography/hazmat/bindings/openssl/hmac.py | 94 ++ src/cryptography/hazmat/bindings/openssl/nid.py | 241 +++++ .../hazmat/bindings/openssl/objects.py | 45 + .../hazmat/bindings/openssl/opensslv.py | 36 + .../hazmat/bindings/openssl/osrandom_engine.py | 218 ++++ src/cryptography/hazmat/bindings/openssl/pem.py | 89 ++ src/cryptography/hazmat/bindings/openssl/pkcs12.py | 41 + src/cryptography/hazmat/bindings/openssl/pkcs7.py | 41 + src/cryptography/hazmat/bindings/openssl/rand.py | 45 + src/cryptography/hazmat/bindings/openssl/rsa.py | 108 ++ src/cryptography/hazmat/bindings/openssl/ssl.py | 620 ++++++++++++ src/cryptography/hazmat/bindings/openssl/x509.py | 273 ++++++ .../hazmat/bindings/openssl/x509_vfy.py | 336 +++++++ .../hazmat/bindings/openssl/x509name.py | 61 ++ src/cryptography/hazmat/bindings/openssl/x509v3.py | 103 ++ src/cryptography/hazmat/bindings/utils.py | 144 +++ src/cryptography/hazmat/primitives/__init__.py | 14 + .../hazmat/primitives/asymmetric/__init__.py | 14 + .../hazmat/primitives/asymmetric/dsa.py | 108 ++ .../hazmat/primitives/asymmetric/ec.py | 195 ++++ .../hazmat/primitives/asymmetric/padding.py | 65 ++ .../hazmat/primitives/asymmetric/rsa.py | 191 ++++ .../hazmat/primitives/ciphers/__init__.py | 21 + .../hazmat/primitives/ciphers/algorithms.py | 147 +++ src/cryptography/hazmat/primitives/ciphers/base.py | 132 +++ .../hazmat/primitives/ciphers/modes.py | 125 +++ src/cryptography/hazmat/primitives/cmac.py | 75 ++ .../hazmat/primitives/constant_time.py | 47 + src/cryptography/hazmat/primitives/hashes.py | 121 +++ src/cryptography/hazmat/primitives/hmac.py | 78 ++ src/cryptography/hazmat/primitives/interfaces.py | 499 ++++++++++ src/cryptography/hazmat/primitives/kdf/__init__.py | 14 + src/cryptography/hazmat/primitives/kdf/hkdf.py | 124 +++ src/cryptography/hazmat/primitives/kdf/pbkdf2.py | 66 ++ src/cryptography/hazmat/primitives/padding.py | 164 ++++ .../hazmat/primitives/serialization.py | 50 + .../hazmat/primitives/src/constant_time.c | 31 + .../hazmat/primitives/src/constant_time.h | 16 + .../hazmat/primitives/twofactor/__init__.py | 14 + .../hazmat/primitives/twofactor/hotp.py | 69 ++ .../hazmat/primitives/twofactor/totp.py | 41 + src/cryptography/utils.py | 64 ++ 196 files changed, 12492 insertions(+), 12486 deletions(-) delete mode 100644 cryptography/__about__.py delete mode 100644 cryptography/__init__.py delete mode 100644 cryptography/exceptions.py delete mode 100644 cryptography/fernet.py delete mode 100644 cryptography/hazmat/__init__.py delete mode 100644 cryptography/hazmat/backends/__init__.py delete mode 100644 cryptography/hazmat/backends/commoncrypto/__init__.py delete mode 100644 cryptography/hazmat/backends/commoncrypto/backend.py delete mode 100644 cryptography/hazmat/backends/commoncrypto/ciphers.py delete mode 100644 cryptography/hazmat/backends/commoncrypto/hashes.py delete mode 100644 cryptography/hazmat/backends/commoncrypto/hmac.py delete mode 100644 cryptography/hazmat/backends/interfaces.py delete mode 100644 cryptography/hazmat/backends/multibackend.py delete mode 100644 cryptography/hazmat/backends/openssl/__init__.py delete mode 100644 cryptography/hazmat/backends/openssl/backend.py delete mode 100644 cryptography/hazmat/backends/openssl/ciphers.py delete mode 100644 cryptography/hazmat/backends/openssl/cmac.py delete mode 100644 cryptography/hazmat/backends/openssl/dsa.py delete mode 100644 cryptography/hazmat/backends/openssl/ec.py delete mode 100644 cryptography/hazmat/backends/openssl/hashes.py delete mode 100644 cryptography/hazmat/backends/openssl/hmac.py delete mode 100644 cryptography/hazmat/backends/openssl/rsa.py delete mode 100644 cryptography/hazmat/backends/openssl/utils.py delete mode 100644 cryptography/hazmat/bindings/__init__.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/__init__.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/binding.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/cf.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/common_cryptor.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/common_digest.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/common_hmac.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/secimport.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/secitem.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/seckey.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/seckeychain.py delete mode 100644 cryptography/hazmat/bindings/commoncrypto/sectransform.py delete mode 100644 cryptography/hazmat/bindings/openssl/__init__.py delete mode 100644 cryptography/hazmat/bindings/openssl/aes.py delete mode 100644 cryptography/hazmat/bindings/openssl/asn1.py delete mode 100644 cryptography/hazmat/bindings/openssl/bignum.py delete mode 100644 cryptography/hazmat/bindings/openssl/binding.py delete mode 100644 cryptography/hazmat/bindings/openssl/bio.py delete mode 100644 cryptography/hazmat/bindings/openssl/cmac.py delete mode 100644 cryptography/hazmat/bindings/openssl/cms.py delete mode 100644 cryptography/hazmat/bindings/openssl/conf.py delete mode 100644 cryptography/hazmat/bindings/openssl/crypto.py delete mode 100644 cryptography/hazmat/bindings/openssl/dh.py delete mode 100644 cryptography/hazmat/bindings/openssl/dsa.py delete mode 100644 cryptography/hazmat/bindings/openssl/ec.py delete mode 100644 cryptography/hazmat/bindings/openssl/ecdh.py delete mode 100644 cryptography/hazmat/bindings/openssl/ecdsa.py delete mode 100644 cryptography/hazmat/bindings/openssl/engine.py delete mode 100644 cryptography/hazmat/bindings/openssl/err.py delete mode 100644 cryptography/hazmat/bindings/openssl/evp.py delete mode 100644 cryptography/hazmat/bindings/openssl/hmac.py delete mode 100644 cryptography/hazmat/bindings/openssl/nid.py delete mode 100644 cryptography/hazmat/bindings/openssl/objects.py delete mode 100644 cryptography/hazmat/bindings/openssl/opensslv.py delete mode 100644 cryptography/hazmat/bindings/openssl/osrandom_engine.py delete mode 100644 cryptography/hazmat/bindings/openssl/pem.py delete mode 100644 cryptography/hazmat/bindings/openssl/pkcs12.py delete mode 100644 cryptography/hazmat/bindings/openssl/pkcs7.py delete mode 100644 cryptography/hazmat/bindings/openssl/rand.py delete mode 100644 cryptography/hazmat/bindings/openssl/rsa.py delete mode 100644 cryptography/hazmat/bindings/openssl/ssl.py delete mode 100644 cryptography/hazmat/bindings/openssl/x509.py delete mode 100644 cryptography/hazmat/bindings/openssl/x509_vfy.py delete mode 100644 cryptography/hazmat/bindings/openssl/x509name.py delete mode 100644 cryptography/hazmat/bindings/openssl/x509v3.py delete mode 100644 cryptography/hazmat/bindings/utils.py delete mode 100644 cryptography/hazmat/primitives/__init__.py delete mode 100644 cryptography/hazmat/primitives/asymmetric/__init__.py delete mode 100644 cryptography/hazmat/primitives/asymmetric/dsa.py delete mode 100644 cryptography/hazmat/primitives/asymmetric/ec.py delete mode 100644 cryptography/hazmat/primitives/asymmetric/padding.py delete mode 100644 cryptography/hazmat/primitives/asymmetric/rsa.py delete mode 100644 cryptography/hazmat/primitives/ciphers/__init__.py delete mode 100644 cryptography/hazmat/primitives/ciphers/algorithms.py delete mode 100644 cryptography/hazmat/primitives/ciphers/base.py delete mode 100644 cryptography/hazmat/primitives/ciphers/modes.py delete mode 100644 cryptography/hazmat/primitives/cmac.py delete mode 100644 cryptography/hazmat/primitives/constant_time.py delete mode 100644 cryptography/hazmat/primitives/hashes.py delete mode 100644 cryptography/hazmat/primitives/hmac.py delete mode 100644 cryptography/hazmat/primitives/interfaces.py delete mode 100644 cryptography/hazmat/primitives/kdf/__init__.py delete mode 100644 cryptography/hazmat/primitives/kdf/hkdf.py delete mode 100644 cryptography/hazmat/primitives/kdf/pbkdf2.py delete mode 100644 cryptography/hazmat/primitives/padding.py delete mode 100644 cryptography/hazmat/primitives/serialization.py delete mode 100644 cryptography/hazmat/primitives/src/constant_time.c delete mode 100644 cryptography/hazmat/primitives/src/constant_time.h delete mode 100644 cryptography/hazmat/primitives/twofactor/__init__.py delete mode 100644 cryptography/hazmat/primitives/twofactor/hotp.py delete mode 100644 cryptography/hazmat/primitives/twofactor/totp.py delete mode 100644 cryptography/utils.py create mode 100644 src/cryptography/__about__.py create mode 100644 src/cryptography/__init__.py create mode 100644 src/cryptography/exceptions.py create mode 100644 src/cryptography/fernet.py create mode 100644 src/cryptography/hazmat/__init__.py create mode 100644 src/cryptography/hazmat/backends/__init__.py create mode 100644 src/cryptography/hazmat/backends/commoncrypto/__init__.py create mode 100644 src/cryptography/hazmat/backends/commoncrypto/backend.py create mode 100644 src/cryptography/hazmat/backends/commoncrypto/ciphers.py create mode 100644 src/cryptography/hazmat/backends/commoncrypto/hashes.py create mode 100644 src/cryptography/hazmat/backends/commoncrypto/hmac.py create mode 100644 src/cryptography/hazmat/backends/interfaces.py create mode 100644 src/cryptography/hazmat/backends/multibackend.py create mode 100644 src/cryptography/hazmat/backends/openssl/__init__.py create mode 100644 src/cryptography/hazmat/backends/openssl/backend.py create mode 100644 src/cryptography/hazmat/backends/openssl/ciphers.py create mode 100644 src/cryptography/hazmat/backends/openssl/cmac.py create mode 100644 src/cryptography/hazmat/backends/openssl/dsa.py create mode 100644 src/cryptography/hazmat/backends/openssl/ec.py create mode 100644 src/cryptography/hazmat/backends/openssl/hashes.py create mode 100644 src/cryptography/hazmat/backends/openssl/hmac.py create mode 100644 src/cryptography/hazmat/backends/openssl/rsa.py create mode 100644 src/cryptography/hazmat/backends/openssl/utils.py create mode 100644 src/cryptography/hazmat/bindings/__init__.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/__init__.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/binding.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/cf.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/common_digest.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/common_hmac.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/secimport.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/secitem.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/seckey.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/seckeychain.py create mode 100644 src/cryptography/hazmat/bindings/commoncrypto/sectransform.py create mode 100644 src/cryptography/hazmat/bindings/openssl/__init__.py create mode 100644 src/cryptography/hazmat/bindings/openssl/aes.py create mode 100644 src/cryptography/hazmat/bindings/openssl/asn1.py create mode 100644 src/cryptography/hazmat/bindings/openssl/bignum.py create mode 100644 src/cryptography/hazmat/bindings/openssl/binding.py create mode 100644 src/cryptography/hazmat/bindings/openssl/bio.py create mode 100644 src/cryptography/hazmat/bindings/openssl/cmac.py create mode 100644 src/cryptography/hazmat/bindings/openssl/cms.py create mode 100644 src/cryptography/hazmat/bindings/openssl/conf.py create mode 100644 src/cryptography/hazmat/bindings/openssl/crypto.py create mode 100644 src/cryptography/hazmat/bindings/openssl/dh.py create mode 100644 src/cryptography/hazmat/bindings/openssl/dsa.py create mode 100644 src/cryptography/hazmat/bindings/openssl/ec.py create mode 100644 src/cryptography/hazmat/bindings/openssl/ecdh.py create mode 100644 src/cryptography/hazmat/bindings/openssl/ecdsa.py create mode 100644 src/cryptography/hazmat/bindings/openssl/engine.py create mode 100644 src/cryptography/hazmat/bindings/openssl/err.py create mode 100644 src/cryptography/hazmat/bindings/openssl/evp.py create mode 100644 src/cryptography/hazmat/bindings/openssl/hmac.py create mode 100644 src/cryptography/hazmat/bindings/openssl/nid.py create mode 100644 src/cryptography/hazmat/bindings/openssl/objects.py create mode 100644 src/cryptography/hazmat/bindings/openssl/opensslv.py create mode 100644 src/cryptography/hazmat/bindings/openssl/osrandom_engine.py create mode 100644 src/cryptography/hazmat/bindings/openssl/pem.py create mode 100644 src/cryptography/hazmat/bindings/openssl/pkcs12.py create mode 100644 src/cryptography/hazmat/bindings/openssl/pkcs7.py create mode 100644 src/cryptography/hazmat/bindings/openssl/rand.py create mode 100644 src/cryptography/hazmat/bindings/openssl/rsa.py create mode 100644 src/cryptography/hazmat/bindings/openssl/ssl.py create mode 100644 src/cryptography/hazmat/bindings/openssl/x509.py create mode 100644 src/cryptography/hazmat/bindings/openssl/x509_vfy.py create mode 100644 src/cryptography/hazmat/bindings/openssl/x509name.py create mode 100644 src/cryptography/hazmat/bindings/openssl/x509v3.py create mode 100644 src/cryptography/hazmat/bindings/utils.py create mode 100644 src/cryptography/hazmat/primitives/__init__.py create mode 100644 src/cryptography/hazmat/primitives/asymmetric/__init__.py create mode 100644 src/cryptography/hazmat/primitives/asymmetric/dsa.py create mode 100644 src/cryptography/hazmat/primitives/asymmetric/ec.py create mode 100644 src/cryptography/hazmat/primitives/asymmetric/padding.py create mode 100644 src/cryptography/hazmat/primitives/asymmetric/rsa.py create mode 100644 src/cryptography/hazmat/primitives/ciphers/__init__.py create mode 100644 src/cryptography/hazmat/primitives/ciphers/algorithms.py create mode 100644 src/cryptography/hazmat/primitives/ciphers/base.py create mode 100644 src/cryptography/hazmat/primitives/ciphers/modes.py create mode 100644 src/cryptography/hazmat/primitives/cmac.py create mode 100644 src/cryptography/hazmat/primitives/constant_time.py create mode 100644 src/cryptography/hazmat/primitives/hashes.py create mode 100644 src/cryptography/hazmat/primitives/hmac.py create mode 100644 src/cryptography/hazmat/primitives/interfaces.py create mode 100644 src/cryptography/hazmat/primitives/kdf/__init__.py create mode 100644 src/cryptography/hazmat/primitives/kdf/hkdf.py create mode 100644 src/cryptography/hazmat/primitives/kdf/pbkdf2.py create mode 100644 src/cryptography/hazmat/primitives/padding.py create mode 100644 src/cryptography/hazmat/primitives/serialization.py create mode 100644 src/cryptography/hazmat/primitives/src/constant_time.c create mode 100644 src/cryptography/hazmat/primitives/src/constant_time.h create mode 100644 src/cryptography/hazmat/primitives/twofactor/__init__.py create mode 100644 src/cryptography/hazmat/primitives/twofactor/hotp.py create mode 100644 src/cryptography/hazmat/primitives/twofactor/totp.py create mode 100644 src/cryptography/utils.py diff --git a/.coveragerc b/.coveragerc index 8964f1cd..aa69fd4f 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,7 +1,7 @@ [run] branch = True source = - cryptography/ + cryptography tests/ [report] diff --git a/MANIFEST.in b/MANIFEST.in index 41fb19b2..b7e6559f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,7 +7,7 @@ include LICENSE.BSD include README.rst recursive-include docs * -recursive-include cryptography/hazmat/primitives/src *.c *.h +recursive-include src/cryptography/hazmat/primitives/src *.c *.h prune docs/_build recursive-include tests *.py recursive-exclude vectors * diff --git a/cryptography/__about__.py b/cryptography/__about__.py deleted file mode 100644 index 3d39d18b..00000000 --- a/cryptography/__about__.py +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -from __future__ import absolute_import, division, print_function - -__all__ = [ - "__title__", "__summary__", "__uri__", "__version__", "__author__", - "__email__", "__license__", "__copyright__", -] - -__title__ = "cryptography" -__summary__ = ("cryptography is a package which provides cryptographic recipes" - " and primitives to Python developers.") -__uri__ = "https://github.com/pyca/cryptography" - -__version__ = "0.7.dev1" - -__author__ = "The cryptography developers" -__email__ = "cryptography-dev@python.org" - -__license__ = "BSD or Apache License, Version 2.0" -__copyright__ = "Copyright 2013-2014 {0}".format(__author__) diff --git a/cryptography/__init__.py b/cryptography/__init__.py deleted file mode 100644 index f27ba856..00000000 --- a/cryptography/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography.__about__ import ( - __author__, __copyright__, __email__, __license__, __summary__, __title__, - __uri__, __version__ -) - - -__all__ = [ - "__title__", "__summary__", "__uri__", "__version__", "__author__", - "__email__", "__license__", "__copyright__", -] diff --git a/cryptography/exceptions.py b/cryptography/exceptions.py deleted file mode 100644 index c14763f7..00000000 --- a/cryptography/exceptions.py +++ /dev/null @@ -1,63 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - - -class _Reasons(object): - BACKEND_MISSING_INTERFACE = object() - UNSUPPORTED_HASH = object() - UNSUPPORTED_CIPHER = object() - UNSUPPORTED_PADDING = object() - UNSUPPORTED_MGF = object() - UNSUPPORTED_PUBLIC_KEY_ALGORITHM = object() - UNSUPPORTED_ELLIPTIC_CURVE = object() - UNSUPPORTED_SERIALIZATION = object() - - -class UnsupportedAlgorithm(Exception): - def __init__(self, message, reason=None): - super(UnsupportedAlgorithm, self).__init__(message) - self._reason = reason - - -class AlreadyFinalized(Exception): - pass - - -class AlreadyUpdated(Exception): - pass - - -class NotYetFinalized(Exception): - pass - - -class InvalidTag(Exception): - pass - - -class InvalidSignature(Exception): - pass - - -class InternalError(Exception): - pass - - -class InvalidKey(Exception): - pass - - -class InvalidToken(Exception): - pass diff --git a/cryptography/fernet.py b/cryptography/fernet.py deleted file mode 100644 index 4f98feec..00000000 --- a/cryptography/fernet.py +++ /dev/null @@ -1,150 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import base64 -import binascii -import os -import struct -import time - -import six - -from cryptography.exceptions import InvalidSignature -from cryptography.hazmat.backends import default_backend -from cryptography.hazmat.primitives import hashes, padding -from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes -from cryptography.hazmat.primitives.hmac import HMAC - - -class InvalidToken(Exception): - pass - - -_MAX_CLOCK_SKEW = 60 - - -class Fernet(object): - def __init__(self, key, backend=None): - if backend is None: - backend = default_backend() - - key = base64.urlsafe_b64decode(key) - if len(key) != 32: - raise ValueError( - "Fernet key must be 32 url-safe base64-encoded bytes." - ) - - self._signing_key = key[:16] - self._encryption_key = key[16:] - self._backend = backend - - @classmethod - def generate_key(cls): - return base64.urlsafe_b64encode(os.urandom(32)) - - def encrypt(self, data): - current_time = int(time.time()) - iv = os.urandom(16) - return self._encrypt_from_parts(data, current_time, iv) - - def _encrypt_from_parts(self, data, current_time, iv): - if not isinstance(data, bytes): - raise TypeError("data must be bytes.") - - padder = padding.PKCS7(algorithms.AES.block_size).padder() - padded_data = padder.update(data) + padder.finalize() - encryptor = Cipher( - algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend - ).encryptor() - ciphertext = encryptor.update(padded_data) + encryptor.finalize() - - basic_parts = ( - b"\x80" + struct.pack(">Q", current_time) + iv + ciphertext - ) - - h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend) - h.update(basic_parts) - hmac = h.finalize() - return base64.urlsafe_b64encode(basic_parts + hmac) - - def decrypt(self, token, ttl=None): - if not isinstance(token, bytes): - raise TypeError("token must be bytes.") - - current_time = int(time.time()) - - try: - data = base64.urlsafe_b64decode(token) - except (TypeError, binascii.Error): - raise InvalidToken - - if not data or 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 - - -class MultiFernet(object): - def __init__(self, fernets): - fernets = list(fernets) - if not fernets: - raise ValueError( - "MultiFernet requires at least one Fernet instance" - ) - self._fernets = fernets - - def encrypt(self, msg): - return self._fernets[0].encrypt(msg) - - def decrypt(self, msg, ttl=None): - for f in self._fernets: - try: - return f.decrypt(msg, ttl) - except InvalidToken: - pass - raise InvalidToken diff --git a/cryptography/hazmat/__init__.py b/cryptography/hazmat/__init__.py deleted file mode 100644 index 2f420574..00000000 --- a/cryptography/hazmat/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function diff --git a/cryptography/hazmat/backends/__init__.py b/cryptography/hazmat/backends/__init__.py deleted file mode 100644 index b0f663fe..00000000 --- a/cryptography/hazmat/backends/__init__.py +++ /dev/null @@ -1,46 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import pkg_resources - -from cryptography.hazmat.backends.multibackend import MultiBackend - - -_available_backends_list = None - - -def _available_backends(): - global _available_backends_list - - if _available_backends_list is None: - _available_backends_list = [ - backend.load(require=False) - for backend in pkg_resources.iter_entry_points( - "cryptography.backends" - ) - ] - - return _available_backends_list - -_default_backend = None - - -def default_backend(): - global _default_backend - - if _default_backend is None: - _default_backend = MultiBackend(_available_backends()) - - return _default_backend diff --git a/cryptography/hazmat/backends/commoncrypto/__init__.py b/cryptography/hazmat/backends/commoncrypto/__init__.py deleted file mode 100644 index f080394f..00000000 --- a/cryptography/hazmat/backends/commoncrypto/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography.hazmat.backends.commoncrypto.backend import backend - - -__all__ = ["backend"] diff --git a/cryptography/hazmat/backends/commoncrypto/backend.py b/cryptography/hazmat/backends/commoncrypto/backend.py deleted file mode 100644 index 7bab979f..00000000 --- a/cryptography/hazmat/backends/commoncrypto/backend.py +++ /dev/null @@ -1,253 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from collections import namedtuple - -from cryptography import utils -from cryptography.exceptions import InternalError -from cryptography.hazmat.backends.commoncrypto.ciphers import ( - _CipherContext, _GCMCipherContext -) -from cryptography.hazmat.backends.commoncrypto.hashes import _HashContext -from cryptography.hazmat.backends.commoncrypto.hmac import _HMACContext -from cryptography.hazmat.backends.interfaces import ( - CipherBackend, HMACBackend, HashBackend, PBKDF2HMACBackend -) -from cryptography.hazmat.bindings.commoncrypto.binding import Binding -from cryptography.hazmat.primitives.ciphers.algorithms import ( - AES, ARC4, Blowfish, CAST5, TripleDES -) -from cryptography.hazmat.primitives.ciphers.modes import ( - CBC, CFB, CFB8, CTR, ECB, GCM, OFB -) - - -HashMethods = namedtuple( - "HashMethods", ["ctx", "hash_init", "hash_update", "hash_final"] -) - - -@utils.register_interface(CipherBackend) -@utils.register_interface(HashBackend) -@utils.register_interface(HMACBackend) -@utils.register_interface(PBKDF2HMACBackend) -class Backend(object): - """ - CommonCrypto API wrapper. - """ - name = "commoncrypto" - - def __init__(self): - self._binding = Binding() - self._ffi = self._binding.ffi - self._lib = self._binding.lib - - self._cipher_registry = {} - self._register_default_ciphers() - self._hash_mapping = { - "md5": HashMethods( - "CC_MD5_CTX *", self._lib.CC_MD5_Init, - self._lib.CC_MD5_Update, self._lib.CC_MD5_Final - ), - "sha1": HashMethods( - "CC_SHA1_CTX *", self._lib.CC_SHA1_Init, - self._lib.CC_SHA1_Update, self._lib.CC_SHA1_Final - ), - "sha224": HashMethods( - "CC_SHA256_CTX *", self._lib.CC_SHA224_Init, - self._lib.CC_SHA224_Update, self._lib.CC_SHA224_Final - ), - "sha256": HashMethods( - "CC_SHA256_CTX *", self._lib.CC_SHA256_Init, - self._lib.CC_SHA256_Update, self._lib.CC_SHA256_Final - ), - "sha384": HashMethods( - "CC_SHA512_CTX *", self._lib.CC_SHA384_Init, - self._lib.CC_SHA384_Update, self._lib.CC_SHA384_Final - ), - "sha512": HashMethods( - "CC_SHA512_CTX *", self._lib.CC_SHA512_Init, - self._lib.CC_SHA512_Update, self._lib.CC_SHA512_Final - ), - } - - self._supported_hmac_algorithms = { - "md5": self._lib.kCCHmacAlgMD5, - "sha1": self._lib.kCCHmacAlgSHA1, - "sha224": self._lib.kCCHmacAlgSHA224, - "sha256": self._lib.kCCHmacAlgSHA256, - "sha384": self._lib.kCCHmacAlgSHA384, - "sha512": self._lib.kCCHmacAlgSHA512, - } - - self._supported_pbkdf2_hmac_algorithms = { - "sha1": self._lib.kCCPRFHmacAlgSHA1, - "sha224": self._lib.kCCPRFHmacAlgSHA224, - "sha256": self._lib.kCCPRFHmacAlgSHA256, - "sha384": self._lib.kCCPRFHmacAlgSHA384, - "sha512": self._lib.kCCPRFHmacAlgSHA512, - } - - def hash_supported(self, algorithm): - return algorithm.name in self._hash_mapping - - def hmac_supported(self, algorithm): - return algorithm.name in self._supported_hmac_algorithms - - def create_hash_ctx(self, algorithm): - return _HashContext(self, algorithm) - - def create_hmac_ctx(self, key, algorithm): - return _HMACContext(self, key, algorithm) - - def cipher_supported(self, cipher, mode): - return (type(cipher), type(mode)) in self._cipher_registry - - def create_symmetric_encryption_ctx(self, cipher, mode): - if isinstance(mode, GCM): - return _GCMCipherContext( - self, cipher, mode, self._lib.kCCEncrypt - ) - else: - return _CipherContext(self, cipher, mode, self._lib.kCCEncrypt) - - def create_symmetric_decryption_ctx(self, cipher, mode): - if isinstance(mode, GCM): - return _GCMCipherContext( - self, cipher, mode, self._lib.kCCDecrypt - ) - else: - return _CipherContext(self, cipher, mode, self._lib.kCCDecrypt) - - def pbkdf2_hmac_supported(self, algorithm): - return algorithm.name in self._supported_pbkdf2_hmac_algorithms - - def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations, - key_material): - alg_enum = self._supported_pbkdf2_hmac_algorithms[algorithm.name] - buf = self._ffi.new("char[]", length) - res = self._lib.CCKeyDerivationPBKDF( - self._lib.kCCPBKDF2, - key_material, - len(key_material), - salt, - len(salt), - alg_enum, - iterations, - buf, - length - ) - self._check_cipher_response(res) - - return self._ffi.buffer(buf)[:] - - def _register_cipher_adapter(self, cipher_cls, cipher_const, mode_cls, - mode_const): - if (cipher_cls, mode_cls) in self._cipher_registry: - raise ValueError("Duplicate registration for: {0} {1}.".format( - cipher_cls, mode_cls) - ) - self._cipher_registry[cipher_cls, mode_cls] = (cipher_const, - mode_const) - - def _register_default_ciphers(self): - for mode_cls, mode_const in [ - (CBC, self._lib.kCCModeCBC), - (ECB, self._lib.kCCModeECB), - (CFB, self._lib.kCCModeCFB), - (CFB8, self._lib.kCCModeCFB8), - (OFB, self._lib.kCCModeOFB), - (CTR, self._lib.kCCModeCTR), - (GCM, self._lib.kCCModeGCM), - ]: - self._register_cipher_adapter( - AES, - self._lib.kCCAlgorithmAES128, - mode_cls, - mode_const - ) - for mode_cls, mode_const in [ - (CBC, self._lib.kCCModeCBC), - (ECB, self._lib.kCCModeECB), - (CFB, self._lib.kCCModeCFB), - (CFB8, self._lib.kCCModeCFB8), - (OFB, self._lib.kCCModeOFB), - ]: - self._register_cipher_adapter( - TripleDES, - self._lib.kCCAlgorithm3DES, - mode_cls, - mode_const - ) - for mode_cls, mode_const in [ - (CBC, self._lib.kCCModeCBC), - (ECB, self._lib.kCCModeECB), - (CFB, self._lib.kCCModeCFB), - (OFB, self._lib.kCCModeOFB) - ]: - self._register_cipher_adapter( - Blowfish, - self._lib.kCCAlgorithmBlowfish, - mode_cls, - mode_const - ) - for mode_cls, mode_const in [ - (CBC, self._lib.kCCModeCBC), - (ECB, self._lib.kCCModeECB), - (CFB, self._lib.kCCModeCFB), - (OFB, self._lib.kCCModeOFB), - (CTR, self._lib.kCCModeCTR) - ]: - self._register_cipher_adapter( - CAST5, - self._lib.kCCAlgorithmCAST, - mode_cls, - mode_const - ) - self._register_cipher_adapter( - ARC4, - self._lib.kCCAlgorithmRC4, - type(None), - self._lib.kCCModeRC4 - ) - - def _check_cipher_response(self, response): - if response == self._lib.kCCSuccess: - return - elif response == self._lib.kCCAlignmentError: - # This error is not currently triggered due to a bug filed as - # rdar://15589470 - raise ValueError( - "The length of the provided data is not a multiple of " - "the block length." - ) - else: - raise InternalError( - "The backend returned an unknown error, consider filing a bug." - " Code: {0}.".format(response) - ) - - def _release_cipher_ctx(self, ctx): - """ - Called by the garbage collector and used to safely dereference and - release the context. - """ - if ctx[0] != self._ffi.NULL: - res = self._lib.CCCryptorRelease(ctx[0]) - self._check_cipher_response(res) - ctx[0] = self._ffi.NULL - - -backend = Backend() diff --git a/cryptography/hazmat/backends/commoncrypto/ciphers.py b/cryptography/hazmat/backends/commoncrypto/ciphers.py deleted file mode 100644 index d94746c6..00000000 --- a/cryptography/hazmat/backends/commoncrypto/ciphers.py +++ /dev/null @@ -1,201 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import ( - InvalidTag, UnsupportedAlgorithm, _Reasons -) -from cryptography.hazmat.primitives import constant_time, interfaces -from cryptography.hazmat.primitives.ciphers.modes import ( - CFB, CFB8, CTR, OFB -) - - -@utils.register_interface(interfaces.CipherContext) -class _CipherContext(object): - def __init__(self, backend, cipher, mode, operation): - self._backend = backend - self._cipher = cipher - self._mode = mode - self._operation = operation - # There is a bug in CommonCrypto where block ciphers do not raise - # kCCAlignmentError when finalizing if you supply non-block aligned - # data. To work around this we need to keep track of the block - # alignment ourselves, but only for alg+mode combos that require - # block alignment. OFB, CFB, and CTR make a block cipher algorithm - # into a stream cipher so we don't need to track them (and thus their - # block size is effectively 1 byte just like OpenSSL/CommonCrypto - # treat RC4 and other stream cipher block sizes). - # This bug has been filed as rdar://15589470 - self._bytes_processed = 0 - if (isinstance(cipher, interfaces.BlockCipherAlgorithm) and not - isinstance(mode, (OFB, CFB, CFB8, CTR))): - self._byte_block_size = cipher.block_size // 8 - else: - self._byte_block_size = 1 - - registry = self._backend._cipher_registry - try: - cipher_enum, mode_enum = registry[type(cipher), type(mode)] - except KeyError: - raise UnsupportedAlgorithm( - "cipher {0} in {1} mode is not supported " - "by this backend.".format( - cipher.name, mode.name if mode else mode), - _Reasons.UNSUPPORTED_CIPHER - ) - - ctx = self._backend._ffi.new("CCCryptorRef *") - ctx = self._backend._ffi.gc(ctx, self._backend._release_cipher_ctx) - - if isinstance(mode, interfaces.ModeWithInitializationVector): - iv_nonce = mode.initialization_vector - elif isinstance(mode, interfaces.ModeWithNonce): - iv_nonce = mode.nonce - else: - iv_nonce = self._backend._ffi.NULL - - if isinstance(mode, CTR): - mode_option = self._backend._lib.kCCModeOptionCTR_BE - else: - mode_option = 0 - - res = self._backend._lib.CCCryptorCreateWithMode( - operation, - mode_enum, cipher_enum, - self._backend._lib.ccNoPadding, iv_nonce, - cipher.key, len(cipher.key), - self._backend._ffi.NULL, 0, 0, mode_option, ctx) - self._backend._check_cipher_response(res) - - self._ctx = ctx - - def update(self, data): - # Count bytes processed to handle block alignment. - self._bytes_processed += len(data) - buf = self._backend._ffi.new( - "unsigned char[]", len(data) + self._byte_block_size - 1) - outlen = self._backend._ffi.new("size_t *") - res = self._backend._lib.CCCryptorUpdate( - self._ctx[0], data, len(data), buf, - len(data) + self._byte_block_size - 1, outlen) - self._backend._check_cipher_response(res) - return self._backend._ffi.buffer(buf)[:outlen[0]] - - def finalize(self): - # Raise error if block alignment is wrong. - if self._bytes_processed % self._byte_block_size: - raise ValueError( - "The length of the provided data is not a multiple of " - "the block length." - ) - buf = self._backend._ffi.new("unsigned char[]", self._byte_block_size) - outlen = self._backend._ffi.new("size_t *") - res = self._backend._lib.CCCryptorFinal( - self._ctx[0], buf, len(buf), outlen) - self._backend._check_cipher_response(res) - self._backend._release_cipher_ctx(self._ctx) - return self._backend._ffi.buffer(buf)[:outlen[0]] - - -@utils.register_interface(interfaces.AEADCipherContext) -@utils.register_interface(interfaces.AEADEncryptionContext) -class _GCMCipherContext(object): - def __init__(self, backend, cipher, mode, operation): - self._backend = backend - self._cipher = cipher - self._mode = mode - self._operation = operation - self._tag = None - - registry = self._backend._cipher_registry - try: - cipher_enum, mode_enum = registry[type(cipher), type(mode)] - except KeyError: - raise UnsupportedAlgorithm( - "cipher {0} in {1} mode is not supported " - "by this backend.".format( - cipher.name, mode.name if mode else mode), - _Reasons.UNSUPPORTED_CIPHER - ) - - ctx = self._backend._ffi.new("CCCryptorRef *") - ctx = self._backend._ffi.gc(ctx, self._backend._release_cipher_ctx) - - self._ctx = ctx - - res = self._backend._lib.CCCryptorCreateWithMode( - operation, - mode_enum, cipher_enum, - self._backend._lib.ccNoPadding, - self._backend._ffi.NULL, - cipher.key, len(cipher.key), - self._backend._ffi.NULL, 0, 0, 0, self._ctx) - self._backend._check_cipher_response(res) - - res = self._backend._lib.CCCryptorGCMAddIV( - self._ctx[0], - mode.initialization_vector, - len(mode.initialization_vector) - ) - self._backend._check_cipher_response(res) - # CommonCrypto has a bug where calling update without at least one - # call to authenticate_additional_data will result in null byte output - # for ciphertext. The following empty byte string call prevents the - # issue, which is present in at least 10.8 and 10.9. - # Filed as rdar://18314544 - self.authenticate_additional_data(b"") - - def update(self, data): - buf = self._backend._ffi.new("unsigned char[]", len(data)) - args = (self._ctx[0], data, len(data), buf) - if self._operation == self._backend._lib.kCCEncrypt: - res = self._backend._lib.CCCryptorGCMEncrypt(*args) - else: - res = self._backend._lib.CCCryptorGCMDecrypt(*args) - - self._backend._check_cipher_response(res) - return self._backend._ffi.buffer(buf)[:] - - def finalize(self): - # CommonCrypto has a yet another bug where you must make at least one - # call to update. If you pass just AAD and call finalize without a call - # to update you'll get null bytes for tag. The following update call - # prevents this issue, which is present in at least 10.8 and 10.9. - # Filed as rdar://18314580 - self.update(b"") - tag_size = self._cipher.block_size // 8 - tag_buf = self._backend._ffi.new("unsigned char[]", tag_size) - tag_len = self._backend._ffi.new("size_t *", tag_size) - res = self._backend._lib.CCCryptorGCMFinal( - self._ctx[0], tag_buf, tag_len - ) - self._backend._check_cipher_response(res) - self._backend._release_cipher_ctx(self._ctx) - self._tag = self._backend._ffi.buffer(tag_buf)[:] - if (self._operation == self._backend._lib.kCCDecrypt and - not constant_time.bytes_eq( - self._tag[:len(self._mode.tag)], self._mode.tag - )): - raise InvalidTag - return b"" - - def authenticate_additional_data(self, data): - res = self._backend._lib.CCCryptorGCMAddAAD( - self._ctx[0], data, len(data) - ) - self._backend._check_cipher_response(res) - - tag = utils.read_only_property("_tag") diff --git a/cryptography/hazmat/backends/commoncrypto/hashes.py b/cryptography/hazmat/backends/commoncrypto/hashes.py deleted file mode 100644 index 217f4e8c..00000000 --- a/cryptography/hazmat/backends/commoncrypto/hashes.py +++ /dev/null @@ -1,64 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import UnsupportedAlgorithm, _Reasons -from cryptography.hazmat.primitives import interfaces - - -@utils.register_interface(interfaces.HashContext) -class _HashContext(object): - def __init__(self, backend, algorithm, ctx=None): - self._algorithm = algorithm - self._backend = backend - - if ctx is None: - try: - methods = self._backend._hash_mapping[self.algorithm.name] - except KeyError: - raise UnsupportedAlgorithm( - "{0} is not a supported hash on this backend.".format( - algorithm.name), - _Reasons.UNSUPPORTED_HASH - ) - ctx = self._backend._ffi.new(methods.ctx) - res = methods.hash_init(ctx) - assert res == 1 - - self._ctx = ctx - - algorithm = utils.read_only_property("_algorithm") - - 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)[:] diff --git a/cryptography/hazmat/backends/commoncrypto/hmac.py b/cryptography/hazmat/backends/commoncrypto/hmac.py deleted file mode 100644 index ee7e3abb..00000000 --- a/cryptography/hazmat/backends/commoncrypto/hmac.py +++ /dev/null @@ -1,68 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import ( - InvalidSignature, UnsupportedAlgorithm, _Reasons -) -from cryptography.hazmat.primitives import constant_time, interfaces - - -@utils.register_interface(interfaces.MACContext) -@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 - - algorithm = utils.read_only_property("_algorithm") - - 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)[:] - - def verify(self, signature): - digest = self.finalize() - if not constant_time.bytes_eq(digest, signature): - raise InvalidSignature("Signature did not match digest.") diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py deleted file mode 100644 index ecb5bf48..00000000 --- a/cryptography/hazmat/backends/interfaces.py +++ /dev/null @@ -1,261 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -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 MACContext for calculating a message authentication code. - """ - - -@six.add_metaclass(abc.ABCMeta) -class CMACBackend(object): - @abc.abstractmethod - def cmac_algorithm_supported(self, algorithm): - """ - Returns True if the block cipher is supported for CMAC by this backend - """ - - @abc.abstractmethod - def create_cmac_ctx(self, algorithm): - """ - Create a MACContext 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 rsa_padding_supported(self, padding): - """ - Returns True if the backend supports the given padding options. - """ - - @abc.abstractmethod - def generate_rsa_parameters_supported(self, public_exponent, key_size): - """ - Returns True if the backend supports the given parameters for key - generation. - """ - - @abc.abstractmethod - def load_rsa_private_numbers(self, numbers): - """ - Returns an RSAPrivateKey provider. - """ - - @abc.abstractmethod - def load_rsa_public_numbers(self, numbers): - """ - Returns an RSAPublicKey provider. - """ - - -@six.add_metaclass(abc.ABCMeta) -class DSABackend(object): - @abc.abstractmethod - def generate_dsa_parameters(self, key_size): - """ - Generate a DSAParameters instance with a modulus of key_size bits. - """ - - @abc.abstractmethod - def generate_dsa_private_key(self, parameters): - """ - Generate a DSAPrivateKey instance with parameters as a DSAParameters - object. - """ - - @abc.abstractmethod - def generate_dsa_private_key_and_parameters(self, key_size): - """ - Generate a DSAPrivateKey instance using key size only. - """ - - @abc.abstractmethod - def dsa_hash_supported(self, algorithm): - """ - Return True if the hash algorithm is supported by the backend for DSA. - """ - - @abc.abstractmethod - def dsa_parameters_supported(self, p, q, g): - """ - Return True if the parameters are supported by the backend for DSA. - """ - - @abc.abstractmethod - def load_dsa_private_numbers(self, numbers): - """ - Returns a DSAPrivateKey provider. - """ - - @abc.abstractmethod - def load_dsa_public_numbers(self, numbers): - """ - Returns a DSAPublicKey provider. - """ - - @abc.abstractmethod - def load_dsa_parameter_numbers(self, numbers): - """ - Returns a DSAParameters provider. - """ - - -@six.add_metaclass(abc.ABCMeta) -class EllipticCurveBackend(object): - @abc.abstractmethod - def elliptic_curve_signature_algorithm_supported( - self, signature_algorithm, curve - ): - """ - Returns True if the backend supports the named elliptic curve with the - specified signature algorithm. - """ - - @abc.abstractmethod - def elliptic_curve_supported(self, curve): - """ - Returns True if the backend supports the named elliptic curve. - """ - - @abc.abstractmethod - def generate_elliptic_curve_private_key(self, curve): - """ - Return an object conforming to the EllipticCurvePrivateKey interface. - """ - - @abc.abstractmethod - def load_elliptic_curve_public_numbers(self, numbers): - """ - Return an EllipticCurvePublicKey provider using the given numbers. - """ - - @abc.abstractmethod - def load_elliptic_curve_private_numbers(self, numbers): - """ - Return an EllipticCurvePublicKey provider using the given numbers. - """ - - -@six.add_metaclass(abc.ABCMeta) -class PEMSerializationBackend(object): - @abc.abstractmethod - def load_pem_private_key(self, data, password): - """ - Loads a private key from PEM encoded data, using the provided password - if the data is encrypted. - """ - - @abc.abstractmethod - def load_pem_public_key(self, data): - """ - Loads a public key from PEM encoded data. - """ - - -@six.add_metaclass(abc.ABCMeta) -class TraditionalOpenSSLSerializationBackend(object): - @abc.abstractmethod - def load_traditional_openssl_pem_private_key(self, data, password): - """ - Load a private key from PEM encoded data, using password if the data - is encrypted. - """ - - -@six.add_metaclass(abc.ABCMeta) -class PKCS8SerializationBackend(object): - @abc.abstractmethod - def load_pkcs8_pem_private_key(self, data, password): - """ - Load a private key from PKCS8 encoded data, using password if the data - is encrypted. - """ diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py deleted file mode 100644 index c62b790c..00000000 --- a/cryptography/hazmat/backends/multibackend.py +++ /dev/null @@ -1,358 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import warnings - -from cryptography import utils -from cryptography.exceptions import UnsupportedAlgorithm, _Reasons -from cryptography.hazmat.backends.interfaces import ( - CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend, - HashBackend, PBKDF2HMACBackend, PEMSerializationBackend, - PKCS8SerializationBackend, RSABackend, - TraditionalOpenSSLSerializationBackend -) - - -@utils.register_interface(CMACBackend) -@utils.register_interface(CipherBackend) -@utils.register_interface(HashBackend) -@utils.register_interface(HMACBackend) -@utils.register_interface(PBKDF2HMACBackend) -@utils.register_interface(PKCS8SerializationBackend) -@utils.register_interface(RSABackend) -@utils.register_interface(TraditionalOpenSSLSerializationBackend) -@utils.register_interface(DSABackend) -@utils.register_interface(EllipticCurveBackend) -@utils.register_interface(PEMSerializationBackend) -class MultiBackend(object): - name = "multibackend" - - def __init__(self, backends): - self._backends = backends - - def _filtered_backends(self, interface): - for b in self._backends: - if isinstance(b, interface): - yield b - - def cipher_supported(self, cipher, mode): - return any( - b.cipher_supported(cipher, mode) - for b in self._filtered_backends(CipherBackend) - ) - - def create_symmetric_encryption_ctx(self, cipher, mode): - for b in self._filtered_backends(CipherBackend): - try: - return b.create_symmetric_encryption_ctx(cipher, mode) - except UnsupportedAlgorithm: - pass - 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 - ) - - def create_symmetric_decryption_ctx(self, cipher, mode): - for b in self._filtered_backends(CipherBackend): - try: - return b.create_symmetric_decryption_ctx(cipher, mode) - except UnsupportedAlgorithm: - pass - 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 - ) - - def hash_supported(self, algorithm): - return any( - b.hash_supported(algorithm) - for b in self._filtered_backends(HashBackend) - ) - - def create_hash_ctx(self, algorithm): - for b in self._filtered_backends(HashBackend): - try: - return b.create_hash_ctx(algorithm) - except UnsupportedAlgorithm: - pass - raise UnsupportedAlgorithm( - "{0} is not a supported hash on this backend.".format( - algorithm.name), - _Reasons.UNSUPPORTED_HASH - ) - - def hmac_supported(self, algorithm): - return any( - b.hmac_supported(algorithm) - for b in self._filtered_backends(HMACBackend) - ) - - def create_hmac_ctx(self, key, algorithm): - for b in self._filtered_backends(HMACBackend): - try: - return b.create_hmac_ctx(key, algorithm) - except UnsupportedAlgorithm: - pass - raise UnsupportedAlgorithm( - "{0} is not a supported hash on this backend.".format( - algorithm.name), - _Reasons.UNSUPPORTED_HASH - ) - - def pbkdf2_hmac_supported(self, algorithm): - return any( - b.pbkdf2_hmac_supported(algorithm) - for b in self._filtered_backends(PBKDF2HMACBackend) - ) - - def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations, - key_material): - for b in self._filtered_backends(PBKDF2HMACBackend): - try: - return b.derive_pbkdf2_hmac( - algorithm, length, salt, iterations, key_material - ) - except UnsupportedAlgorithm: - pass - raise UnsupportedAlgorithm( - "{0} is not a supported hash on this backend.".format( - algorithm.name), - _Reasons.UNSUPPORTED_HASH - ) - - def generate_rsa_private_key(self, public_exponent, key_size): - for b in self._filtered_backends(RSABackend): - return b.generate_rsa_private_key(public_exponent, key_size) - raise UnsupportedAlgorithm("RSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def generate_rsa_parameters_supported(self, public_exponent, key_size): - for b in self._filtered_backends(RSABackend): - return b.generate_rsa_parameters_supported( - public_exponent, key_size - ) - raise UnsupportedAlgorithm("RSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def rsa_padding_supported(self, padding): - for b in self._filtered_backends(RSABackend): - return b.rsa_padding_supported(padding) - raise UnsupportedAlgorithm("RSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def load_rsa_private_numbers(self, numbers): - for b in self._filtered_backends(RSABackend): - return b.load_rsa_private_numbers(numbers) - - raise UnsupportedAlgorithm("RSA is not supported by the backend", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def load_rsa_public_numbers(self, numbers): - for b in self._filtered_backends(RSABackend): - return b.load_rsa_public_numbers(numbers) - - raise UnsupportedAlgorithm("RSA is not supported by the backend", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def generate_dsa_parameters(self, key_size): - for b in self._filtered_backends(DSABackend): - return b.generate_dsa_parameters(key_size) - raise UnsupportedAlgorithm("DSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def generate_dsa_private_key(self, parameters): - for b in self._filtered_backends(DSABackend): - return b.generate_dsa_private_key(parameters) - raise UnsupportedAlgorithm("DSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def generate_dsa_private_key_and_parameters(self, key_size): - for b in self._filtered_backends(DSABackend): - return b.generate_dsa_private_key_and_parameters(key_size) - raise UnsupportedAlgorithm("DSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def dsa_hash_supported(self, algorithm): - for b in self._filtered_backends(DSABackend): - return b.dsa_hash_supported(algorithm) - raise UnsupportedAlgorithm("DSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def dsa_parameters_supported(self, p, q, g): - for b in self._filtered_backends(DSABackend): - return b.dsa_parameters_supported(p, q, g) - raise UnsupportedAlgorithm("DSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def load_dsa_public_numbers(self, numbers): - for b in self._filtered_backends(DSABackend): - return b.load_dsa_public_numbers(numbers) - raise UnsupportedAlgorithm("DSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def load_dsa_private_numbers(self, numbers): - for b in self._filtered_backends(DSABackend): - return b.load_dsa_private_numbers(numbers) - raise UnsupportedAlgorithm("DSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def load_dsa_parameter_numbers(self, numbers): - for b in self._filtered_backends(DSABackend): - return b.load_dsa_parameter_numbers(numbers) - raise UnsupportedAlgorithm("DSA is not supported by the backend.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def cmac_algorithm_supported(self, algorithm): - return any( - b.cmac_algorithm_supported(algorithm) - for b in self._filtered_backends(CMACBackend) - ) - - def create_cmac_ctx(self, algorithm): - for b in self._filtered_backends(CMACBackend): - try: - return b.create_cmac_ctx(algorithm) - except UnsupportedAlgorithm: - pass - raise UnsupportedAlgorithm("This backend does not support CMAC.", - _Reasons.UNSUPPORTED_CIPHER) - - def elliptic_curve_supported(self, curve): - return any( - b.elliptic_curve_supported(curve) - for b in self._filtered_backends(EllipticCurveBackend) - ) - - def elliptic_curve_signature_algorithm_supported( - self, signature_algorithm, curve - ): - return any( - b.elliptic_curve_signature_algorithm_supported( - signature_algorithm, curve - ) - for b in self._filtered_backends(EllipticCurveBackend) - ) - - def generate_elliptic_curve_private_key(self, curve): - for b in self._filtered_backends(EllipticCurveBackend): - try: - return b.generate_elliptic_curve_private_key(curve) - except UnsupportedAlgorithm: - continue - - raise UnsupportedAlgorithm( - "This backend does not support this elliptic curve.", - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE - ) - - def elliptic_curve_private_key_from_numbers(self, numbers): - warnings.warn( - "elliptic_curve_private_key_from_numbers is deprecated and will " - "be removed in a future version.", - utils.DeprecatedIn06, - stacklevel=2 - ) - for b in self._filtered_backends(EllipticCurveBackend): - try: - return b.elliptic_curve_private_key_from_numbers(numbers) - except UnsupportedAlgorithm: - continue - - raise UnsupportedAlgorithm( - "This backend does not support this elliptic curve.", - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE - ) - - def load_elliptic_curve_private_numbers(self, numbers): - for b in self._filtered_backends(EllipticCurveBackend): - try: - return b.load_elliptic_curve_private_numbers(numbers) - except UnsupportedAlgorithm: - continue - - raise UnsupportedAlgorithm( - "This backend does not support this elliptic curve.", - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE - ) - - def elliptic_curve_public_key_from_numbers(self, numbers): - warnings.warn( - "elliptic_curve_public_key_from_numbers is deprecated and will " - "be removed in a future version.", - utils.DeprecatedIn06, - stacklevel=2 - ) - for b in self._filtered_backends(EllipticCurveBackend): - try: - return b.elliptic_curve_public_key_from_numbers(numbers) - except UnsupportedAlgorithm: - continue - - raise UnsupportedAlgorithm( - "This backend does not support this elliptic curve.", - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE - ) - - def load_elliptic_curve_public_numbers(self, numbers): - for b in self._filtered_backends(EllipticCurveBackend): - try: - return b.load_elliptic_curve_public_numbers(numbers) - except UnsupportedAlgorithm: - continue - - raise UnsupportedAlgorithm( - "This backend does not support this elliptic curve.", - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE - ) - - def load_pem_private_key(self, data, password): - for b in self._filtered_backends(PEMSerializationBackend): - return b.load_pem_private_key(data, password) - - raise UnsupportedAlgorithm( - "This backend does not support this key serialization.", - _Reasons.UNSUPPORTED_SERIALIZATION - ) - - def load_pem_public_key(self, data): - for b in self._filtered_backends(PEMSerializationBackend): - return b.load_pem_public_key(data) - - raise UnsupportedAlgorithm( - "This backend does not support this key serialization.", - _Reasons.UNSUPPORTED_SERIALIZATION - ) - - def load_pkcs8_pem_private_key(self, data, password): - for b in self._filtered_backends(PKCS8SerializationBackend): - return b.load_pkcs8_pem_private_key(data, password) - - raise UnsupportedAlgorithm( - "This backend does not support this key serialization.", - _Reasons.UNSUPPORTED_SERIALIZATION - ) - - def load_traditional_openssl_pem_private_key(self, data, password): - for b in self._filtered_backends( - TraditionalOpenSSLSerializationBackend - ): - return b.load_traditional_openssl_pem_private_key(data, password) - - raise UnsupportedAlgorithm( - "This backend does not support this key serialization.", - _Reasons.UNSUPPORTED_SERIALIZATION - ) diff --git a/cryptography/hazmat/backends/openssl/__init__.py b/cryptography/hazmat/backends/openssl/__init__.py deleted file mode 100644 index 25885e18..00000000 --- a/cryptography/hazmat/backends/openssl/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography.hazmat.backends.openssl.backend import backend - - -__all__ = ["backend"] diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py deleted file mode 100644 index bb1a3f3d..00000000 --- a/cryptography/hazmat/backends/openssl/backend.py +++ /dev/null @@ -1,1036 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import collections -import itertools -import warnings -from contextlib import contextmanager - -import six - -from cryptography import utils -from cryptography.exceptions import ( - InternalError, UnsupportedAlgorithm, _Reasons -) -from cryptography.hazmat.backends.interfaces import ( - CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend, - HashBackend, PBKDF2HMACBackend, PEMSerializationBackend, - PKCS8SerializationBackend, RSABackend, - TraditionalOpenSSLSerializationBackend -) -from cryptography.hazmat.backends.openssl.ciphers import ( - _AESCTRCipherContext, _CipherContext -) -from cryptography.hazmat.backends.openssl.cmac import _CMACContext -from cryptography.hazmat.backends.openssl.dsa import ( - _DSAParameters, _DSAPrivateKey, _DSAPublicKey -) -from cryptography.hazmat.backends.openssl.ec import ( - _EllipticCurvePrivateKey, _EllipticCurvePublicKey -) -from cryptography.hazmat.backends.openssl.hashes import _HashContext -from cryptography.hazmat.backends.openssl.hmac import _HMACContext -from cryptography.hazmat.backends.openssl.rsa import ( - _RSAPrivateKey, _RSAPublicKey -) -from cryptography.hazmat.bindings.openssl.binding import Binding -from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa -from cryptography.hazmat.primitives.asymmetric.padding import ( - MGF1, OAEP, PKCS1v15, PSS -) -from cryptography.hazmat.primitives.ciphers.algorithms import ( - AES, ARC4, Blowfish, CAST5, Camellia, IDEA, SEED, TripleDES -) -from cryptography.hazmat.primitives.ciphers.modes import ( - CBC, CFB, CFB8, CTR, ECB, GCM, OFB -) - - -_MemoryBIO = collections.namedtuple("_MemoryBIO", ["bio", "char_ptr"]) -_OpenSSLError = collections.namedtuple("_OpenSSLError", - ["code", "lib", "func", "reason"]) - - -@utils.register_interface(CipherBackend) -@utils.register_interface(CMACBackend) -@utils.register_interface(DSABackend) -@utils.register_interface(EllipticCurveBackend) -@utils.register_interface(HashBackend) -@utils.register_interface(HMACBackend) -@utils.register_interface(PBKDF2HMACBackend) -@utils.register_interface(PKCS8SerializationBackend) -@utils.register_interface(RSABackend) -@utils.register_interface(TraditionalOpenSSLSerializationBackend) -@utils.register_interface(PEMSerializationBackend) -class Backend(object): - """ - OpenSSL API binding interfaces. - """ - name = "openssl" - - def __init__(self): - self._binding = Binding() - self._ffi = self._binding.ffi - self._lib = self._binding.lib - - self._binding.init_static_locks() - - # adds all ciphers/digests for EVP - self._lib.OpenSSL_add_all_algorithms() - # registers available SSL/TLS ciphers and digests - self._lib.SSL_library_init() - # loads error strings for libcrypto and libssl functions - self._lib.SSL_load_error_strings() - - self._cipher_registry = {} - self._register_default_ciphers() - self.activate_osrandom_engine() - - def activate_builtin_random(self): - # Obtain a new structural reference. - e = self._lib.ENGINE_get_default_RAND() - if e != self._ffi.NULL: - self._lib.ENGINE_unregister_RAND(e) - # Reset the RNG to use the new engine. - self._lib.RAND_cleanup() - # decrement the structural reference from get_default_RAND - res = self._lib.ENGINE_finish(e) - assert res == 1 - - def activate_osrandom_engine(self): - # Unregister and free the current engine. - self.activate_builtin_random() - # Fetches an engine by id and returns it. This creates a structural - # reference. - e = self._lib.ENGINE_by_id(self._lib.Cryptography_osrandom_engine_id) - assert e != self._ffi.NULL - # Initialize the engine for use. This adds a functional reference. - res = self._lib.ENGINE_init(e) - assert res == 1 - # Set the engine as the default RAND provider. - res = self._lib.ENGINE_set_default_RAND(e) - assert res == 1 - # Decrement the structural ref incremented by ENGINE_by_id. - res = self._lib.ENGINE_free(e) - assert res == 1 - # Decrement the functional ref incremented by ENGINE_init. - res = self._lib.ENGINE_finish(e) - assert res == 1 - # Reset the RNG to use the new engine. - self._lib.RAND_cleanup() - - def openssl_version_text(self): - """ - Friendly string name of the loaded OpenSSL library. This is not - necessarily the same version as it was compiled against. - - Example: OpenSSL 1.0.1e 11 Feb 2013 - """ - return self._ffi.string( - self._lib.SSLeay_version(self._lib.SSLEAY_VERSION) - ).decode("ascii") - - def create_hmac_ctx(self, key, algorithm): - return _HMACContext(self, key, algorithm) - - def hash_supported(self, algorithm): - digest = self._lib.EVP_get_digestbyname(algorithm.name.encode("ascii")) - return digest != self._ffi.NULL - - def hmac_supported(self, algorithm): - return self.hash_supported(algorithm) - - def create_hash_ctx(self, algorithm): - return _HashContext(self, algorithm) - - def cipher_supported(self, cipher, mode): - if self._evp_cipher_supported(cipher, mode): - return True - elif isinstance(mode, CTR) and isinstance(cipher, AES): - return True - else: - return False - - def _evp_cipher_supported(self, cipher, mode): - try: - adapter = self._cipher_registry[type(cipher), type(mode)] - except KeyError: - return False - evp_cipher = adapter(self, cipher, mode) - return self._ffi.NULL != evp_cipher - - def register_cipher_adapter(self, cipher_cls, mode_cls, adapter): - 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] = adapter - - def _register_default_ciphers(self): - for mode_cls in [CBC, CTR, ECB, OFB, CFB, CFB8]: - self.register_cipher_adapter( - AES, - mode_cls, - GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}") - ) - for mode_cls in [CBC, CTR, ECB, OFB, CFB]: - self.register_cipher_adapter( - Camellia, - mode_cls, - GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}") - ) - for mode_cls in [CBC, CFB, CFB8, OFB]: - self.register_cipher_adapter( - TripleDES, - mode_cls, - GetCipherByName("des-ede3-{mode.name}") - ) - self.register_cipher_adapter( - TripleDES, - ECB, - GetCipherByName("des-ede3") - ) - for mode_cls in [CBC, CFB, OFB, ECB]: - self.register_cipher_adapter( - Blowfish, - mode_cls, - GetCipherByName("bf-{mode.name}") - ) - for mode_cls in [CBC, CFB, OFB, ECB]: - self.register_cipher_adapter( - SEED, - mode_cls, - GetCipherByName("seed-{mode.name}") - ) - for cipher_cls, mode_cls in itertools.product( - [CAST5, IDEA], - [CBC, OFB, CFB, ECB], - ): - self.register_cipher_adapter( - cipher_cls, - mode_cls, - GetCipherByName("{cipher.name}-{mode.name}") - ) - self.register_cipher_adapter( - ARC4, - type(None), - GetCipherByName("rc4") - ) - self.register_cipher_adapter( - AES, - GCM, - GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}") - ) - - def create_symmetric_encryption_ctx(self, cipher, mode): - if (isinstance(mode, CTR) and isinstance(cipher, AES) - and not self._evp_cipher_supported(cipher, mode)): - # This is needed to provide support for AES CTR mode in OpenSSL - # 0.9.8. It can be removed when we drop 0.9.8 support (RHEL 5 - # extended life ends 2020). - return _AESCTRCipherContext(self, cipher, mode) - else: - return _CipherContext(self, cipher, mode, _CipherContext._ENCRYPT) - - def create_symmetric_decryption_ctx(self, cipher, mode): - if (isinstance(mode, CTR) and isinstance(cipher, AES) - and not self._evp_cipher_supported(cipher, mode)): - # This is needed to provide support for AES CTR mode in OpenSSL - # 0.9.8. It can be removed when we drop 0.9.8 support (RHEL 5 - # extended life ends 2020). - return _AESCTRCipherContext(self, cipher, mode) - else: - return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT) - - def pbkdf2_hmac_supported(self, algorithm): - if self._lib.Cryptography_HAS_PBKDF2_HMAC: - return self.hmac_supported(algorithm) - else: - # OpenSSL < 1.0.0 has an explicit PBKDF2-HMAC-SHA1 function, - # so if the PBKDF2_HMAC function is missing we only support - # SHA1 via PBKDF2_HMAC_SHA1. - return isinstance(algorithm, hashes.SHA1) - - def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations, - key_material): - buf = self._ffi.new("char[]", length) - if self._lib.Cryptography_HAS_PBKDF2_HMAC: - evp_md = self._lib.EVP_get_digestbyname( - algorithm.name.encode("ascii")) - assert evp_md != self._ffi.NULL - res = self._lib.PKCS5_PBKDF2_HMAC( - key_material, - len(key_material), - salt, - len(salt), - iterations, - evp_md, - length, - buf - ) - assert res == 1 - else: - if not isinstance(algorithm, hashes.SHA1): - raise UnsupportedAlgorithm( - "This version of OpenSSL only supports PBKDF2HMAC with " - "SHA1.", - _Reasons.UNSUPPORTED_HASH - ) - res = self._lib.PKCS5_PBKDF2_HMAC_SHA1( - key_material, - len(key_material), - salt, - len(salt), - iterations, - length, - buf - ) - assert res == 1 - - return self._ffi.buffer(buf)[:] - - def _err_string(self, code): - err_buf = self._ffi.new("char[]", 256) - self._lib.ERR_error_string_n(code, err_buf, 256) - return self._ffi.string(err_buf, 256)[:] - - def _consume_errors(self): - errors = [] - while True: - code = self._lib.ERR_get_error() - if code == 0: - break - - lib = self._lib.ERR_GET_LIB(code) - func = self._lib.ERR_GET_FUNC(code) - reason = self._lib.ERR_GET_REASON(code) - - errors.append(_OpenSSLError(code, lib, func, reason)) - return errors - - def _unknown_error(self, error): - return InternalError( - "Unknown error code {0} from OpenSSL, " - "you should probably file a bug. {1}.".format( - error.code, self._err_string(error.code) - ) - ) - - def _bn_to_int(self, bn): - if six.PY3: - # Python 3 has constant time from_bytes, so use that. - - bn_num_bytes = (self._lib.BN_num_bits(bn) + 7) // 8 - bin_ptr = self._ffi.new("unsigned char[]", bn_num_bytes) - bin_len = self._lib.BN_bn2bin(bn, bin_ptr) - assert bin_len > 0 - assert bin_ptr != self._ffi.NULL - return int.from_bytes(self._ffi.buffer(bin_ptr)[:bin_len], "big") - - else: - # Under Python 2 the best we can do is hex() - - hex_cdata = self._lib.BN_bn2hex(bn) - assert hex_cdata != self._ffi.NULL - hex_str = self._ffi.string(hex_cdata) - self._lib.OPENSSL_free(hex_cdata) - return int(hex_str, 16) - - def _int_to_bn(self, num, bn=None): - """ - Converts a python integer to a BIGNUM. The returned BIGNUM will not - be garbage collected (to support adding them to structs that take - ownership of the object). Be sure to register it for GC if it will - be discarded after use. - """ - - if bn is None: - bn = self._ffi.NULL - - if six.PY3: - # Python 3 has constant time to_bytes, so use that. - - binary = num.to_bytes(int(num.bit_length() / 8.0 + 1), "big") - bn_ptr = self._lib.BN_bin2bn(binary, len(binary), bn) - assert bn_ptr != self._ffi.NULL - return bn_ptr - - else: - # Under Python 2 the best we can do is hex() - - hex_num = hex(num).rstrip("L").lstrip("0x").encode("ascii") or b"0" - bn_ptr = self._ffi.new("BIGNUM **") - bn_ptr[0] = bn - res = self._lib.BN_hex2bn(bn_ptr, hex_num) - assert res != 0 - assert bn_ptr[0] != self._ffi.NULL - return bn_ptr[0] - - def generate_rsa_private_key(self, public_exponent, key_size): - rsa._verify_rsa_parameters(public_exponent, key_size) - - rsa_cdata = self._lib.RSA_new() - assert rsa_cdata != self._ffi.NULL - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - - bn = self._int_to_bn(public_exponent) - bn = self._ffi.gc(bn, self._lib.BN_free) - - res = self._lib.RSA_generate_key_ex( - rsa_cdata, key_size, bn, self._ffi.NULL - ) - assert res == 1 - - return _RSAPrivateKey(self, rsa_cdata) - - def generate_rsa_parameters_supported(self, public_exponent, key_size): - return (public_exponent >= 3 and public_exponent & 1 != 0 and - key_size >= 512) - - def load_rsa_private_numbers(self, numbers): - rsa._check_private_key_components( - numbers.p, - numbers.q, - numbers.d, - numbers.dmp1, - numbers.dmq1, - numbers.iqmp, - numbers.public_numbers.e, - numbers.public_numbers.n - ) - rsa_cdata = self._lib.RSA_new() - assert rsa_cdata != self._ffi.NULL - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - rsa_cdata.p = self._int_to_bn(numbers.p) - rsa_cdata.q = self._int_to_bn(numbers.q) - rsa_cdata.d = self._int_to_bn(numbers.d) - rsa_cdata.dmp1 = self._int_to_bn(numbers.dmp1) - rsa_cdata.dmq1 = self._int_to_bn(numbers.dmq1) - rsa_cdata.iqmp = self._int_to_bn(numbers.iqmp) - rsa_cdata.e = self._int_to_bn(numbers.public_numbers.e) - rsa_cdata.n = self._int_to_bn(numbers.public_numbers.n) - res = self._lib.RSA_blinding_on(rsa_cdata, self._ffi.NULL) - assert res == 1 - - return _RSAPrivateKey(self, rsa_cdata) - - def load_rsa_public_numbers(self, numbers): - rsa._check_public_key_components(numbers.e, numbers.n) - rsa_cdata = self._lib.RSA_new() - assert rsa_cdata != self._ffi.NULL - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - rsa_cdata.e = self._int_to_bn(numbers.e) - rsa_cdata.n = self._int_to_bn(numbers.n) - res = self._lib.RSA_blinding_on(rsa_cdata, self._ffi.NULL) - assert res == 1 - - return _RSAPublicKey(self, rsa_cdata) - - def _bytes_to_bio(self, data): - """ - Return a _MemoryBIO namedtuple of (BIO, char*). - - The char* is the storage for the BIO and it must stay alive until the - BIO is finished with. - """ - data_char_p = self._ffi.new("char[]", data) - bio = self._lib.BIO_new_mem_buf( - data_char_p, len(data) - ) - assert bio != self._ffi.NULL - - return _MemoryBIO(self._ffi.gc(bio, self._lib.BIO_free), data_char_p) - - def _evp_pkey_to_private_key(self, evp_pkey): - """ - Return the appropriate type of PrivateKey given an evp_pkey cdata - pointer. - """ - - type = evp_pkey.type - - if type == self._lib.EVP_PKEY_RSA: - rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) - assert rsa_cdata != self._ffi.NULL - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - return _RSAPrivateKey(self, rsa_cdata) - elif type == self._lib.EVP_PKEY_DSA: - dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey) - assert dsa_cdata != self._ffi.NULL - dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) - return _DSAPrivateKey(self, dsa_cdata) - elif (self._lib.Cryptography_HAS_EC == 1 and - type == self._lib.EVP_PKEY_EC): - ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) - assert ec_cdata != self._ffi.NULL - ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) - return _EllipticCurvePrivateKey(self, ec_cdata) - else: - raise UnsupportedAlgorithm("Unsupported key type.") - - def _evp_pkey_to_public_key(self, evp_pkey): - """ - Return the appropriate type of PublicKey given an evp_pkey cdata - pointer. - """ - - type = evp_pkey.type - - if type == self._lib.EVP_PKEY_RSA: - rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) - assert rsa_cdata != self._ffi.NULL - rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) - return _RSAPublicKey(self, rsa_cdata) - elif type == self._lib.EVP_PKEY_DSA: - dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey) - assert dsa_cdata != self._ffi.NULL - dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) - return _DSAPublicKey(self, dsa_cdata) - elif (self._lib.Cryptography_HAS_EC == 1 and - type == self._lib.EVP_PKEY_EC): - ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) - assert ec_cdata != self._ffi.NULL - ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) - return _EllipticCurvePublicKey(self, ec_cdata) - else: - raise UnsupportedAlgorithm("Unsupported key type.") - - def _pem_password_cb(self, password): - """ - Generate a pem_password_cb function pointer that copied the password to - OpenSSL as required and returns the number of bytes copied. - - typedef int pem_password_cb(char *buf, int size, - int rwflag, void *userdata); - - Useful for decrypting PKCS8 files and so on. - - Returns a tuple of (cdata function pointer, callback function). - """ - - def pem_password_cb(buf, size, writing, userdata): - pem_password_cb.called += 1 - - if not password: - pem_password_cb.exception = TypeError( - "Password was not given but private key is encrypted." - ) - return 0 - elif len(password) < size: - pw_buf = self._ffi.buffer(buf, size) - pw_buf[:len(password)] = password - return len(password) - else: - pem_password_cb.exception = ValueError( - "Passwords longer than {0} bytes are not supported " - "by this backend.".format(size - 1) - ) - return 0 - - pem_password_cb.called = 0 - pem_password_cb.exception = None - - return ( - self._ffi.callback("int (char *, int, int, void *)", - pem_password_cb), - pem_password_cb - ) - - def _mgf1_hash_supported(self, algorithm): - if self._lib.Cryptography_HAS_MGF1_MD: - return self.hash_supported(algorithm) - else: - return isinstance(algorithm, hashes.SHA1) - - def rsa_padding_supported(self, padding): - if isinstance(padding, PKCS1v15): - return True - elif isinstance(padding, PSS) and isinstance(padding._mgf, MGF1): - return self._mgf1_hash_supported(padding._mgf._algorithm) - elif isinstance(padding, OAEP) and isinstance(padding._mgf, MGF1): - return isinstance(padding._mgf._algorithm, hashes.SHA1) - else: - return False - - def generate_dsa_parameters(self, key_size): - if key_size not in (1024, 2048, 3072): - raise ValueError( - "Key size must be 1024 or 2048 or 3072 bits.") - - if (self._lib.OPENSSL_VERSION_NUMBER < 0x1000000f and - key_size > 1024): - raise ValueError( - "Key size must be 1024 because OpenSSL < 1.0.0 doesn't " - "support larger key sizes.") - - ctx = self._lib.DSA_new() - assert ctx != self._ffi.NULL - ctx = self._ffi.gc(ctx, self._lib.DSA_free) - - res = self._lib.DSA_generate_parameters_ex( - ctx, key_size, self._ffi.NULL, 0, - self._ffi.NULL, self._ffi.NULL, self._ffi.NULL - ) - - assert res == 1 - - return _DSAParameters(self, ctx) - - def generate_dsa_private_key(self, parameters): - ctx = self._lib.DSA_new() - assert ctx != self._ffi.NULL - ctx = self._ffi.gc(ctx, self._lib.DSA_free) - ctx.p = self._lib.BN_dup(parameters._dsa_cdata.p) - ctx.q = self._lib.BN_dup(parameters._dsa_cdata.q) - ctx.g = self._lib.BN_dup(parameters._dsa_cdata.g) - - self._lib.DSA_generate_key(ctx) - - return _DSAPrivateKey(self, ctx) - - def generate_dsa_private_key_and_parameters(self, key_size): - parameters = self.generate_dsa_parameters(key_size) - return self.generate_dsa_private_key(parameters) - - def load_dsa_private_numbers(self, numbers): - dsa._check_dsa_private_numbers(numbers) - parameter_numbers = numbers.public_numbers.parameter_numbers - - dsa_cdata = self._lib.DSA_new() - assert dsa_cdata != self._ffi.NULL - dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) - - dsa_cdata.p = self._int_to_bn(parameter_numbers.p) - dsa_cdata.q = self._int_to_bn(parameter_numbers.q) - dsa_cdata.g = self._int_to_bn(parameter_numbers.g) - dsa_cdata.pub_key = self._int_to_bn(numbers.public_numbers.y) - dsa_cdata.priv_key = self._int_to_bn(numbers.x) - - return _DSAPrivateKey(self, dsa_cdata) - - def load_dsa_public_numbers(self, numbers): - dsa._check_dsa_parameters(numbers.parameter_numbers) - dsa_cdata = self._lib.DSA_new() - assert dsa_cdata != self._ffi.NULL - dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) - - dsa_cdata.p = self._int_to_bn(numbers.parameter_numbers.p) - dsa_cdata.q = self._int_to_bn(numbers.parameter_numbers.q) - dsa_cdata.g = self._int_to_bn(numbers.parameter_numbers.g) - dsa_cdata.pub_key = self._int_to_bn(numbers.y) - - return _DSAPublicKey(self, dsa_cdata) - - def load_dsa_parameter_numbers(self, numbers): - dsa._check_dsa_parameters(numbers) - dsa_cdata = self._lib.DSA_new() - assert dsa_cdata != self._ffi.NULL - dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) - - dsa_cdata.p = self._int_to_bn(numbers.p) - dsa_cdata.q = self._int_to_bn(numbers.q) - dsa_cdata.g = self._int_to_bn(numbers.g) - - return _DSAParameters(self, dsa_cdata) - - def dsa_hash_supported(self, algorithm): - if self._lib.OPENSSL_VERSION_NUMBER < 0x1000000f: - return isinstance(algorithm, hashes.SHA1) - else: - return self.hash_supported(algorithm) - - def dsa_parameters_supported(self, p, q, g): - if self._lib.OPENSSL_VERSION_NUMBER < 0x1000000f: - return (utils.bit_length(p) <= 1024 and utils.bit_length(q) <= 160) - else: - return True - - def cmac_algorithm_supported(self, algorithm): - return ( - self._lib.Cryptography_HAS_CMAC == 1 - and self.cipher_supported(algorithm, CBC( - b"\x00" * algorithm.block_size)) - ) - - def create_cmac_ctx(self, algorithm): - return _CMACContext(self, algorithm) - - def load_pem_private_key(self, data, password): - return self._load_key( - self._lib.PEM_read_bio_PrivateKey, - self._evp_pkey_to_private_key, - data, - password, - ) - - def load_pem_public_key(self, data): - return self._load_key( - self._lib.PEM_read_bio_PUBKEY, - self._evp_pkey_to_public_key, - data, - None, - ) - - def load_traditional_openssl_pem_private_key(self, data, password): - warnings.warn( - "load_traditional_openssl_pem_private_key is deprecated and will " - "be removed in a future version, use load_pem_private_key " - "instead.", - utils.DeprecatedIn06, - stacklevel=2 - ) - return self.load_pem_private_key(data, password) - - def load_pkcs8_pem_private_key(self, data, password): - warnings.warn( - "load_pkcs8_pem_private_key is deprecated and will be removed in a" - " future version, use load_pem_private_key instead.", - utils.DeprecatedIn06, - stacklevel=2 - ) - return self.load_pem_private_key(data, password) - - def _load_key(self, openssl_read_func, convert_func, data, password): - mem_bio = self._bytes_to_bio(data) - - password_callback, password_func = self._pem_password_cb(password) - - evp_pkey = openssl_read_func( - mem_bio.bio, - self._ffi.NULL, - password_callback, - self._ffi.NULL - ) - - if evp_pkey == self._ffi.NULL: - if password_func.exception is not None: - errors = self._consume_errors() - assert errors - raise password_func.exception - else: - self._handle_key_loading_error() - - evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) - - if password is not None and password_func.called == 0: - raise TypeError( - "Password was given but private key is not encrypted.") - - assert ( - (password is not None and password_func.called == 1) or - password is None - ) - - return convert_func(evp_pkey) - - def _handle_key_loading_error(self): - errors = self._consume_errors() - - if not errors: - raise ValueError("Could not unserialize key data.") - - elif errors[0][1:] in ( - ( - self._lib.ERR_LIB_EVP, - self._lib.EVP_F_EVP_DECRYPTFINAL_EX, - self._lib.EVP_R_BAD_DECRYPT - ), - ( - self._lib.ERR_LIB_PKCS12, - self._lib.PKCS12_F_PKCS12_PBE_CRYPT, - self._lib.PKCS12_R_PKCS12_CIPHERFINAL_ERROR, - ) - ): - raise ValueError("Bad decrypt. Incorrect password?") - - elif errors[0][1:] in ( - ( - self._lib.ERR_LIB_PEM, - self._lib.PEM_F_PEM_GET_EVP_CIPHER_INFO, - self._lib.PEM_R_UNSUPPORTED_ENCRYPTION - ), - - ( - self._lib.ERR_LIB_EVP, - self._lib.EVP_F_EVP_PBE_CIPHERINIT, - self._lib.EVP_R_UNKNOWN_PBE_ALGORITHM - ) - ): - raise UnsupportedAlgorithm( - "PEM data is encrypted with an unsupported cipher", - _Reasons.UNSUPPORTED_CIPHER - ) - - elif any( - error[1:] == ( - self._lib.ERR_LIB_EVP, - self._lib.EVP_F_EVP_PKCS82PKEY, - self._lib.EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM - ) - for error in errors - ): - raise UnsupportedAlgorithm( - "Unsupported public key algorithm.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM - ) - - else: - assert errors[0][1] in ( - self._lib.ERR_LIB_EVP, - self._lib.ERR_LIB_PEM, - self._lib.ERR_LIB_ASN1, - ) - raise ValueError("Could not unserialize key data.") - - def elliptic_curve_supported(self, curve): - if self._lib.Cryptography_HAS_EC != 1: - return False - - try: - curve_nid = self._elliptic_curve_to_nid(curve) - except UnsupportedAlgorithm: - curve_nid = self._lib.NID_undef - - ctx = self._lib.EC_GROUP_new_by_curve_name(curve_nid) - - if ctx == self._ffi.NULL: - errors = self._consume_errors() - assert ( - curve_nid == self._lib.NID_undef or - errors[0][1:] == ( - self._lib.ERR_LIB_EC, - self._lib.EC_F_EC_GROUP_NEW_BY_CURVE_NAME, - self._lib.EC_R_UNKNOWN_GROUP - ) - ) - return False - else: - assert curve_nid != self._lib.NID_undef - self._lib.EC_GROUP_free(ctx) - return True - - def elliptic_curve_signature_algorithm_supported( - self, signature_algorithm, curve - ): - if self._lib.Cryptography_HAS_EC != 1: - return False - - # We only support ECDSA right now. - if not isinstance(signature_algorithm, ec.ECDSA): - return False - - # Before 0.9.8m OpenSSL can't cope with digests longer than the curve. - if ( - self._lib.OPENSSL_VERSION_NUMBER < 0x009080df and - curve.key_size < signature_algorithm.algorithm.digest_size * 8 - ): - return False - - return self.elliptic_curve_supported(curve) - - def generate_elliptic_curve_private_key(self, curve): - """ - Generate a new private key on the named curve. - """ - - if self.elliptic_curve_supported(curve): - curve_nid = self._elliptic_curve_to_nid(curve) - - ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid) - assert ec_cdata != self._ffi.NULL - ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) - - res = self._lib.EC_KEY_generate_key(ec_cdata) - assert res == 1 - - res = self._lib.EC_KEY_check_key(ec_cdata) - assert res == 1 - - return _EllipticCurvePrivateKey(self, ec_cdata) - else: - raise UnsupportedAlgorithm( - "Backend object does not support {0}.".format(curve.name), - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE - ) - - def elliptic_curve_private_key_from_numbers(self, numbers): - warnings.warn( - "elliptic_curve_private_key_from_numbers is deprecated and will " - "be removed in a future version.", - utils.DeprecatedIn06, - stacklevel=2 - ) - return self.load_elliptic_curve_private_numbers(numbers) - - def load_elliptic_curve_private_numbers(self, numbers): - public = numbers.public_numbers - - curve_nid = self._elliptic_curve_to_nid(public.curve) - - ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid) - assert ec_cdata != self._ffi.NULL - ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) - - ec_cdata = self._ec_key_set_public_key_affine_coordinates( - ec_cdata, public.x, public.y) - - res = self._lib.EC_KEY_set_private_key( - ec_cdata, self._int_to_bn(numbers.private_value)) - assert res == 1 - - return _EllipticCurvePrivateKey(self, ec_cdata) - - def elliptic_curve_public_key_from_numbers(self, numbers): - warnings.warn( - "elliptic_curve_public_key_from_numbers is deprecated and will be " - "removed in a future version.", - utils.DeprecatedIn06, - stacklevel=2 - ) - return self.load_elliptic_curve_public_numbers(numbers) - - def load_elliptic_curve_public_numbers(self, numbers): - curve_nid = self._elliptic_curve_to_nid(numbers.curve) - - ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid) - assert ec_cdata != self._ffi.NULL - ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) - - ec_cdata = self._ec_key_set_public_key_affine_coordinates( - ec_cdata, numbers.x, numbers.y) - - return _EllipticCurvePublicKey(self, ec_cdata) - - def _elliptic_curve_to_nid(self, curve): - """ - Get the NID for a curve name. - """ - - curve_aliases = { - "secp192r1": "prime192v1", - "secp256r1": "prime256v1" - } - - curve_name = curve_aliases.get(curve.name, curve.name) - - curve_nid = self._lib.OBJ_sn2nid(curve_name.encode()) - if curve_nid == self._lib.NID_undef: - raise UnsupportedAlgorithm( - "{0} is not a supported elliptic curve".format(curve.name), - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE - ) - return curve_nid - - @contextmanager - def _tmp_bn_ctx(self): - bn_ctx = self._lib.BN_CTX_new() - assert bn_ctx != self._ffi.NULL - bn_ctx = self._ffi.gc(bn_ctx, self._lib.BN_CTX_free) - self._lib.BN_CTX_start(bn_ctx) - try: - yield bn_ctx - finally: - self._lib.BN_CTX_end(bn_ctx) - - def _ec_key_determine_group_get_set_funcs(self, ctx): - """ - Given an EC_KEY determine the group and what methods are required to - get/set point coordinates. - """ - assert ctx != self._ffi.NULL - - nid_two_field = self._lib.OBJ_sn2nid(b"characteristic-two-field") - assert nid_two_field != self._lib.NID_undef - - group = self._lib.EC_KEY_get0_group(ctx) - assert group != self._ffi.NULL - - method = self._lib.EC_GROUP_method_of(group) - assert method != self._ffi.NULL - - nid = self._lib.EC_METHOD_get_field_type(method) - assert nid != self._lib.NID_undef - - if nid == nid_two_field and self._lib.Cryptography_HAS_EC2M: - set_func = self._lib.EC_POINT_set_affine_coordinates_GF2m - get_func = self._lib.EC_POINT_get_affine_coordinates_GF2m - else: - set_func = self._lib.EC_POINT_set_affine_coordinates_GFp - get_func = self._lib.EC_POINT_get_affine_coordinates_GFp - - assert set_func and get_func - - return set_func, get_func, group - - def _ec_key_set_public_key_affine_coordinates(self, ctx, x, y): - """ - This is a port of EC_KEY_set_public_key_affine_coordinates that was - added in 1.0.1. - - Sets the public key point in the EC_KEY context to the affine x and y - values. - """ - - if x < 0 or y < 0: - raise ValueError( - "Invalid EC key. Both x and y must be non-negative." - ) - - bn_x = self._int_to_bn(x) - bn_y = self._int_to_bn(y) - - set_func, get_func, group = ( - self._ec_key_determine_group_get_set_funcs(ctx) - ) - - point = self._lib.EC_POINT_new(group) - assert point != self._ffi.NULL - point = self._ffi.gc(point, self._lib.EC_POINT_free) - - with self._tmp_bn_ctx() as bn_ctx: - check_x = self._lib.BN_CTX_get(bn_ctx) - check_y = self._lib.BN_CTX_get(bn_ctx) - - res = set_func(group, point, bn_x, bn_y, bn_ctx) - assert res == 1 - - res = get_func(group, point, check_x, check_y, bn_ctx) - assert res == 1 - - assert self._lib.BN_cmp(bn_x, check_x) == 0 - assert self._lib.BN_cmp(bn_y, check_y) == 0 - - res = self._lib.EC_KEY_set_public_key(ctx, point) - assert res == 1 - - res = self._lib.EC_KEY_check_key(ctx) - if res != 1: - self._consume_errors() - raise ValueError("Invalid EC key.") - - return ctx - - -class GetCipherByName(object): - def __init__(self, fmt): - self._fmt = fmt - - def __call__(self, backend, cipher, mode): - cipher_name = self._fmt.format(cipher=cipher, mode=mode).lower() - return backend._lib.EVP_get_cipherbyname(cipher_name.encode("ascii")) - - -backend = Backend() diff --git a/cryptography/hazmat/backends/openssl/ciphers.py b/cryptography/hazmat/backends/openssl/ciphers.py deleted file mode 100644 index 4ec2ac89..00000000 --- a/cryptography/hazmat/backends/openssl/ciphers.py +++ /dev/null @@ -1,225 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import InvalidTag, UnsupportedAlgorithm, _Reasons -from cryptography.hazmat.primitives import interfaces -from cryptography.hazmat.primitives.ciphers.modes import GCM - - -@utils.register_interface(interfaces.CipherContext) -@utils.register_interface(interfaces.AEADCipherContext) -@utils.register_interface(interfaces.AEADEncryptionContext) -class _CipherContext(object): - _ENCRYPT = 1 - _DECRYPT = 0 - - def __init__(self, backend, cipher, mode, operation): - self._backend = backend - self._cipher = cipher - self._mode = mode - self._operation = operation - self._tag = None - - if isinstance(self._cipher, interfaces.BlockCipherAlgorithm): - self._block_size = self._cipher.block_size - else: - self._block_size = 1 - - ctx = self._backend._lib.EVP_CIPHER_CTX_new() - ctx = self._backend._ffi.gc( - ctx, self._backend._lib.EVP_CIPHER_CTX_free - ) - - registry = self._backend._cipher_registry - try: - adapter = registry[type(cipher), type(mode)] - except KeyError: - raise UnsupportedAlgorithm( - "cipher {0} in {1} mode is not supported " - "by this backend.".format( - cipher.name, mode.name if mode else mode), - _Reasons.UNSUPPORTED_CIPHER - ) - - evp_cipher = adapter(self._backend, cipher, mode) - if evp_cipher == self._backend._ffi.NULL: - raise UnsupportedAlgorithm( - "cipher {0} in {1} mode is not supported " - "by this backend.".format( - cipher.name, mode.name if mode else mode), - _Reasons.UNSUPPORTED_CIPHER - ) - - if isinstance(mode, interfaces.ModeWithInitializationVector): - iv_nonce = mode.initialization_vector - elif isinstance(mode, interfaces.ModeWithNonce): - iv_nonce = mode.nonce - else: - iv_nonce = self._backend._ffi.NULL - # begin init with cipher and operation type - res = self._backend._lib.EVP_CipherInit_ex(ctx, evp_cipher, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - operation) - assert res != 0 - # set the key length to handle variable key ciphers - res = self._backend._lib.EVP_CIPHER_CTX_set_key_length( - ctx, len(cipher.key) - ) - assert res != 0 - if isinstance(mode, GCM): - res = self._backend._lib.EVP_CIPHER_CTX_ctrl( - ctx, self._backend._lib.EVP_CTRL_GCM_SET_IVLEN, - len(iv_nonce), self._backend._ffi.NULL - ) - assert res != 0 - if operation == self._DECRYPT: - res = self._backend._lib.EVP_CIPHER_CTX_ctrl( - ctx, self._backend._lib.EVP_CTRL_GCM_SET_TAG, - len(mode.tag), mode.tag - ) - assert res != 0 - - # pass key/iv - res = self._backend._lib.EVP_CipherInit_ex( - ctx, - self._backend._ffi.NULL, - self._backend._ffi.NULL, - cipher.key, - iv_nonce, - operation - ) - assert res != 0 - # We purposely disable padding here as it's handled higher up in the - # API. - self._backend._lib.EVP_CIPHER_CTX_set_padding(ctx, 0) - self._ctx = ctx - - def update(self, data): - # OpenSSL 0.9.8e has an assertion in its EVP code that causes it - # to SIGABRT if you call update with an empty byte string. This can be - # removed when we drop support for 0.9.8e (CentOS/RHEL 5). This branch - # should be taken only when length is zero and mode is not GCM because - # AES GCM can return improper tag values if you don't call update - # with empty plaintext when authenticating AAD for ...reasons. - if len(data) == 0 and not isinstance(self._mode, GCM): - return b"" - - buf = self._backend._ffi.new("unsigned char[]", - len(data) + self._block_size - 1) - outlen = self._backend._ffi.new("int *") - res = self._backend._lib.EVP_CipherUpdate(self._ctx, buf, outlen, data, - len(data)) - assert res != 0 - return self._backend._ffi.buffer(buf)[:outlen[0]] - - def finalize(self): - # OpenSSL 1.0.1 on Ubuntu 12.04 (and possibly other distributions) - # appears to have a bug where you must make at least one call to update - # even if you are only using authenticate_additional_data or the - # GCM tag will be wrong. An (empty) call to update resolves this - # and is harmless for all other versions of OpenSSL. - if isinstance(self._mode, GCM): - self.update(b"") - - buf = self._backend._ffi.new("unsigned char[]", self._block_size) - outlen = self._backend._ffi.new("int *") - res = self._backend._lib.EVP_CipherFinal_ex(self._ctx, buf, outlen) - if res == 0: - errors = self._backend._consume_errors() - - if not errors and isinstance(self._mode, GCM): - raise InvalidTag - - assert errors - - if errors[0][1:] == ( - self._backend._lib.ERR_LIB_EVP, - self._backend._lib.EVP_F_EVP_ENCRYPTFINAL_EX, - self._backend._lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH - ) or errors[0][1:] == ( - self._backend._lib.ERR_LIB_EVP, - self._backend._lib.EVP_F_EVP_DECRYPTFINAL_EX, - self._backend._lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH - ): - raise ValueError( - "The length of the provided data is not a multiple of " - "the block length." - ) - else: - raise self._backend._unknown_error(errors[0]) - - if (isinstance(self._mode, GCM) and - self._operation == self._ENCRYPT): - block_byte_size = self._block_size // 8 - tag_buf = self._backend._ffi.new( - "unsigned char[]", block_byte_size - ) - res = self._backend._lib.EVP_CIPHER_CTX_ctrl( - self._ctx, self._backend._lib.EVP_CTRL_GCM_GET_TAG, - block_byte_size, tag_buf - ) - assert res != 0 - self._tag = self._backend._ffi.buffer(tag_buf)[:] - - res = self._backend._lib.EVP_CIPHER_CTX_cleanup(self._ctx) - assert res == 1 - return self._backend._ffi.buffer(buf)[:outlen[0]] - - def authenticate_additional_data(self, data): - outlen = self._backend._ffi.new("int *") - res = self._backend._lib.EVP_CipherUpdate( - self._ctx, self._backend._ffi.NULL, outlen, data, len(data) - ) - assert res != 0 - - tag = utils.read_only_property("_tag") - - -@utils.register_interface(interfaces.CipherContext) -class _AESCTRCipherContext(object): - """ - This is needed to provide support for AES CTR mode in OpenSSL 0.9.8. It can - be removed when we drop 0.9.8 support (RHEL5 extended life ends 2020). - """ - def __init__(self, backend, cipher, mode): - self._backend = backend - - self._key = self._backend._ffi.new("AES_KEY *") - assert self._key != self._backend._ffi.NULL - res = self._backend._lib.AES_set_encrypt_key( - cipher.key, len(cipher.key) * 8, self._key - ) - assert res == 0 - self._ecount = self._backend._ffi.new("char[]", 16) - self._nonce = self._backend._ffi.new("char[16]", mode.nonce) - self._num = self._backend._ffi.new("unsigned int *", 0) - - def update(self, data): - buf = self._backend._ffi.new("unsigned char[]", len(data)) - self._backend._lib.AES_ctr128_encrypt( - data, buf, len(data), self._key, self._nonce, - self._ecount, self._num - ) - return self._backend._ffi.buffer(buf)[:] - - def finalize(self): - self._key = None - self._ecount = None - self._nonce = None - self._num = None - return b"" diff --git a/cryptography/hazmat/backends/openssl/cmac.py b/cryptography/hazmat/backends/openssl/cmac.py deleted file mode 100644 index 1ad6055b..00000000 --- a/cryptography/hazmat/backends/openssl/cmac.py +++ /dev/null @@ -1,89 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - - -from cryptography import utils -from cryptography.exceptions import ( - InvalidSignature, UnsupportedAlgorithm, _Reasons -) -from cryptography.hazmat.primitives import constant_time, interfaces -from cryptography.hazmat.primitives.ciphers.modes import CBC - - -@utils.register_interface(interfaces.MACContext) -class _CMACContext(object): - def __init__(self, backend, algorithm, ctx=None): - if not backend.cmac_algorithm_supported(algorithm): - raise UnsupportedAlgorithm("This backend does not support CMAC.", - _Reasons.UNSUPPORTED_CIPHER) - - self._backend = backend - self._key = algorithm.key - self._algorithm = algorithm - self._output_length = algorithm.block_size // 8 - - if ctx is None: - registry = self._backend._cipher_registry - adapter = registry[type(algorithm), CBC] - - evp_cipher = adapter(self._backend, algorithm, CBC) - - ctx = self._backend._lib.CMAC_CTX_new() - - assert ctx != self._backend._ffi.NULL - ctx = self._backend._ffi.gc(ctx, self._backend._lib.CMAC_CTX_free) - - self._backend._lib.CMAC_Init( - ctx, self._key, len(self._key), - evp_cipher, self._backend._ffi.NULL - ) - - self._ctx = ctx - - algorithm = utils.read_only_property("_algorithm") - - def update(self, data): - res = self._backend._lib.CMAC_Update(self._ctx, data, len(data)) - assert res == 1 - - def finalize(self): - buf = self._backend._ffi.new("unsigned char[]", self._output_length) - length = self._backend._ffi.new("size_t *", self._output_length) - res = self._backend._lib.CMAC_Final( - self._ctx, buf, length - ) - assert res == 1 - - self._ctx = None - - return self._backend._ffi.buffer(buf)[:] - - def copy(self): - copied_ctx = self._backend._lib.CMAC_CTX_new() - copied_ctx = self._backend._ffi.gc( - copied_ctx, self._backend._lib.CMAC_CTX_free - ) - res = self._backend._lib.CMAC_CTX_copy( - copied_ctx, self._ctx - ) - assert res == 1 - return _CMACContext( - self._backend, self._algorithm, ctx=copied_ctx - ) - - def verify(self, signature): - digest = self.finalize() - if not constant_time.bytes_eq(digest, signature): - raise InvalidSignature("Signature did not match digest.") diff --git a/cryptography/hazmat/backends/openssl/dsa.py b/cryptography/hazmat/backends/openssl/dsa.py deleted file mode 100644 index 8652d50b..00000000 --- a/cryptography/hazmat/backends/openssl/dsa.py +++ /dev/null @@ -1,207 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import InvalidSignature -from cryptography.hazmat.backends.openssl.utils import _truncate_digest -from cryptography.hazmat.primitives import hashes, interfaces -from cryptography.hazmat.primitives.asymmetric import dsa -from cryptography.hazmat.primitives.interfaces import ( - DSAParametersWithNumbers, DSAPrivateKeyWithNumbers, DSAPublicKeyWithNumbers -) - - -def _truncate_digest_for_dsa(dsa_cdata, digest, backend): - """ - This function truncates digests that are longer than a given DS - key's length so they can be signed. OpenSSL does this for us in - 1.0.0c+ and it isn't needed in 0.9.8, but that leaves us with three - releases (1.0.0, 1.0.0a, and 1.0.0b) where this is a problem. This - truncation is not required in 0.9.8 because DSA is limited to SHA-1. - """ - - order_bits = backend._lib.BN_num_bits(dsa_cdata.q) - return _truncate_digest(digest, order_bits) - - -@utils.register_interface(interfaces.AsymmetricVerificationContext) -class _DSAVerificationContext(object): - def __init__(self, backend, public_key, signature, algorithm): - self._backend = backend - self._public_key = public_key - self._signature = signature - self._algorithm = algorithm - - self._hash_ctx = hashes.Hash(self._algorithm, self._backend) - - def update(self, data): - self._hash_ctx.update(data) - - def verify(self): - self._dsa_cdata = self._backend._ffi.gc(self._public_key._dsa_cdata, - self._backend._lib.DSA_free) - - data_to_verify = self._hash_ctx.finalize() - - data_to_verify = _truncate_digest_for_dsa( - self._dsa_cdata, data_to_verify, self._backend - ) - - # The first parameter passed to DSA_verify is unused by OpenSSL but - # must be an integer. - res = self._backend._lib.DSA_verify( - 0, data_to_verify, len(data_to_verify), self._signature, - len(self._signature), self._public_key._dsa_cdata) - - if res != 1: - errors = self._backend._consume_errors() - assert errors - if res == -1: - assert errors[0].lib == self._backend._lib.ERR_LIB_ASN1 - - raise InvalidSignature - - -@utils.register_interface(interfaces.AsymmetricSignatureContext) -class _DSASignatureContext(object): - def __init__(self, backend, private_key, algorithm): - self._backend = backend - self._private_key = private_key - self._algorithm = algorithm - self._hash_ctx = hashes.Hash(self._algorithm, self._backend) - - def update(self, data): - self._hash_ctx.update(data) - - def finalize(self): - data_to_sign = self._hash_ctx.finalize() - data_to_sign = _truncate_digest_for_dsa( - self._private_key._dsa_cdata, data_to_sign, self._backend - ) - sig_buf_len = self._backend._lib.DSA_size(self._private_key._dsa_cdata) - sig_buf = self._backend._ffi.new("unsigned char[]", sig_buf_len) - buflen = self._backend._ffi.new("unsigned int *") - - # The first parameter passed to DSA_sign is unused by OpenSSL but - # must be an integer. - res = self._backend._lib.DSA_sign( - 0, data_to_sign, len(data_to_sign), sig_buf, - buflen, self._private_key._dsa_cdata) - assert res == 1 - assert buflen[0] - - return self._backend._ffi.buffer(sig_buf)[:buflen[0]] - - -@utils.register_interface(DSAParametersWithNumbers) -class _DSAParameters(object): - def __init__(self, backend, dsa_cdata): - self._backend = backend - self._dsa_cdata = dsa_cdata - - def parameter_numbers(self): - return dsa.DSAParameterNumbers( - p=self._backend._bn_to_int(self._dsa_cdata.p), - q=self._backend._bn_to_int(self._dsa_cdata.q), - g=self._backend._bn_to_int(self._dsa_cdata.g) - ) - - def generate_private_key(self): - return self._backend.generate_dsa_private_key(self) - - -@utils.register_interface(DSAPrivateKeyWithNumbers) -class _DSAPrivateKey(object): - def __init__(self, backend, dsa_cdata): - self._backend = backend - self._dsa_cdata = dsa_cdata - self._key_size = self._backend._lib.BN_num_bits(self._dsa_cdata.p) - - key_size = utils.read_only_property("_key_size") - - def signer(self, signature_algorithm): - return _DSASignatureContext(self._backend, self, signature_algorithm) - - def private_numbers(self): - return dsa.DSAPrivateNumbers( - public_numbers=dsa.DSAPublicNumbers( - parameter_numbers=dsa.DSAParameterNumbers( - p=self._backend._bn_to_int(self._dsa_cdata.p), - q=self._backend._bn_to_int(self._dsa_cdata.q), - g=self._backend._bn_to_int(self._dsa_cdata.g) - ), - y=self._backend._bn_to_int(self._dsa_cdata.pub_key) - ), - x=self._backend._bn_to_int(self._dsa_cdata.priv_key) - ) - - def public_key(self): - dsa_cdata = self._backend._lib.DSA_new() - assert dsa_cdata != self._backend._ffi.NULL - dsa_cdata = self._backend._ffi.gc( - dsa_cdata, self._backend._lib.DSA_free - ) - dsa_cdata.p = self._backend._lib.BN_dup(self._dsa_cdata.p) - dsa_cdata.q = self._backend._lib.BN_dup(self._dsa_cdata.q) - dsa_cdata.g = self._backend._lib.BN_dup(self._dsa_cdata.g) - dsa_cdata.pub_key = self._backend._lib.BN_dup(self._dsa_cdata.pub_key) - return _DSAPublicKey(self._backend, dsa_cdata) - - def parameters(self): - dsa_cdata = self._backend._lib.DSA_new() - assert dsa_cdata != self._backend._ffi.NULL - dsa_cdata = self._backend._ffi.gc( - dsa_cdata, self._backend._lib.DSA_free - ) - dsa_cdata.p = self._backend._lib.BN_dup(self._dsa_cdata.p) - dsa_cdata.q = self._backend._lib.BN_dup(self._dsa_cdata.q) - dsa_cdata.g = self._backend._lib.BN_dup(self._dsa_cdata.g) - return _DSAParameters(self._backend, dsa_cdata) - - -@utils.register_interface(DSAPublicKeyWithNumbers) -class _DSAPublicKey(object): - def __init__(self, backend, dsa_cdata): - self._backend = backend - self._dsa_cdata = dsa_cdata - self._key_size = self._backend._lib.BN_num_bits(self._dsa_cdata.p) - - key_size = utils.read_only_property("_key_size") - - def verifier(self, signature, signature_algorithm): - return _DSAVerificationContext( - self._backend, self, signature, signature_algorithm - ) - - def public_numbers(self): - return dsa.DSAPublicNumbers( - parameter_numbers=dsa.DSAParameterNumbers( - p=self._backend._bn_to_int(self._dsa_cdata.p), - q=self._backend._bn_to_int(self._dsa_cdata.q), - g=self._backend._bn_to_int(self._dsa_cdata.g) - ), - y=self._backend._bn_to_int(self._dsa_cdata.pub_key) - ) - - def parameters(self): - dsa_cdata = self._backend._lib.DSA_new() - assert dsa_cdata != self._backend._ffi.NULL - dsa_cdata = self._backend._ffi.gc( - dsa_cdata, self._backend._lib.DSA_free - ) - dsa_cdata.p = self._backend._lib.BN_dup(self._dsa_cdata.p) - dsa_cdata.q = self._backend._lib.BN_dup(self._dsa_cdata.q) - dsa_cdata.g = self._backend._lib.BN_dup(self._dsa_cdata.g) - return _DSAParameters(self._backend, dsa_cdata) diff --git a/cryptography/hazmat/backends/openssl/ec.py b/cryptography/hazmat/backends/openssl/ec.py deleted file mode 100644 index 13b0ddbb..00000000 --- a/cryptography/hazmat/backends/openssl/ec.py +++ /dev/null @@ -1,234 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import ( - InvalidSignature, UnsupportedAlgorithm, _Reasons -) -from cryptography.hazmat.backends.openssl.utils import _truncate_digest -from cryptography.hazmat.primitives import hashes, interfaces -from cryptography.hazmat.primitives.asymmetric import ec - - -def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend): - """ - This function truncates digests that are longer than a given elliptic - curve key's length so they can be signed. Since elliptic curve keys are - much shorter than RSA keys many digests (e.g. SHA-512) may require - truncation. - """ - - _lib = backend._lib - _ffi = backend._ffi - - group = _lib.EC_KEY_get0_group(ec_key_cdata) - - with backend._tmp_bn_ctx() as bn_ctx: - order = _lib.BN_CTX_get(bn_ctx) - assert order != _ffi.NULL - - res = _lib.EC_GROUP_get_order(group, order, bn_ctx) - assert res == 1 - - order_bits = _lib.BN_num_bits(order) - - return _truncate_digest(digest, order_bits) - - -def _ec_key_curve_sn(backend, ec_key): - group = backend._lib.EC_KEY_get0_group(ec_key) - assert group != backend._ffi.NULL - - nid = backend._lib.EC_GROUP_get_curve_name(group) - assert nid != backend._lib.NID_undef - - curve_name = backend._lib.OBJ_nid2sn(nid) - assert curve_name != backend._ffi.NULL - - sn = backend._ffi.string(curve_name).decode('ascii') - return sn - - -def _sn_to_elliptic_curve(backend, sn): - try: - return ec._CURVE_TYPES[sn]() - except KeyError: - raise UnsupportedAlgorithm( - "{0} is not a supported elliptic curve".format(sn), - _Reasons.UNSUPPORTED_ELLIPTIC_CURVE - ) - - -@utils.register_interface(interfaces.AsymmetricSignatureContext) -class _ECDSASignatureContext(object): - def __init__(self, backend, private_key, algorithm): - self._backend = backend - self._private_key = private_key - self._digest = hashes.Hash(algorithm, backend) - - def update(self, data): - self._digest.update(data) - - def finalize(self): - ec_key = self._private_key._ec_key - - digest = self._digest.finalize() - - digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend) - - max_size = self._backend._lib.ECDSA_size(ec_key) - assert max_size > 0 - - sigbuf = self._backend._ffi.new("char[]", max_size) - siglen_ptr = self._backend._ffi.new("unsigned int[]", 1) - res = self._backend._lib.ECDSA_sign( - 0, - digest, - len(digest), - sigbuf, - siglen_ptr, - ec_key - ) - assert res == 1 - return self._backend._ffi.buffer(sigbuf)[:siglen_ptr[0]] - - -@utils.register_interface(interfaces.AsymmetricVerificationContext) -class _ECDSAVerificationContext(object): - def __init__(self, backend, public_key, signature, algorithm): - self._backend = backend - self._public_key = public_key - self._signature = signature - self._digest = hashes.Hash(algorithm, backend) - - def update(self, data): - self._digest.update(data) - - def verify(self): - ec_key = self._public_key._ec_key - - digest = self._digest.finalize() - - digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend) - - res = self._backend._lib.ECDSA_verify( - 0, - digest, - len(digest), - self._signature, - len(self._signature), - ec_key - ) - if res != 1: - self._backend._consume_errors() - raise InvalidSignature - return True - - -@utils.register_interface(interfaces.EllipticCurvePrivateKeyWithNumbers) -class _EllipticCurvePrivateKey(object): - def __init__(self, backend, ec_key_cdata): - self._backend = backend - self._ec_key = ec_key_cdata - - sn = _ec_key_curve_sn(backend, ec_key_cdata) - self._curve = _sn_to_elliptic_curve(backend, sn) - - curve = utils.read_only_property("_curve") - - def signer(self, signature_algorithm): - if isinstance(signature_algorithm, ec.ECDSA): - return _ECDSASignatureContext( - self._backend, self, signature_algorithm.algorithm - ) - else: - raise UnsupportedAlgorithm( - "Unsupported elliptic curve signature algorithm.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def public_key(self): - group = self._backend._lib.EC_KEY_get0_group(self._ec_key) - assert group != self._backend._ffi.NULL - - curve_nid = self._backend._lib.EC_GROUP_get_curve_name(group) - - public_ec_key = self._backend._lib.EC_KEY_new_by_curve_name(curve_nid) - assert public_ec_key != self._backend._ffi.NULL - public_ec_key = self._backend._ffi.gc( - public_ec_key, self._backend._lib.EC_KEY_free - ) - - point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) - assert point != self._backend._ffi.NULL - - res = self._backend._lib.EC_KEY_set_public_key(public_ec_key, point) - assert res == 1 - - return _EllipticCurvePublicKey( - self._backend, public_ec_key - ) - - def private_numbers(self): - bn = self._backend._lib.EC_KEY_get0_private_key(self._ec_key) - private_value = self._backend._bn_to_int(bn) - return ec.EllipticCurvePrivateNumbers( - private_value=private_value, - public_numbers=self.public_key().public_numbers() - ) - - -@utils.register_interface(interfaces.EllipticCurvePublicKeyWithNumbers) -class _EllipticCurvePublicKey(object): - def __init__(self, backend, ec_key_cdata): - self._backend = backend - self._ec_key = ec_key_cdata - - sn = _ec_key_curve_sn(backend, ec_key_cdata) - self._curve = _sn_to_elliptic_curve(backend, sn) - - curve = utils.read_only_property("_curve") - - def verifier(self, signature, signature_algorithm): - if isinstance(signature_algorithm, ec.ECDSA): - return _ECDSAVerificationContext( - self._backend, self, signature, signature_algorithm.algorithm - ) - else: - raise UnsupportedAlgorithm( - "Unsupported elliptic curve signature algorithm.", - _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) - - def public_numbers(self): - set_func, get_func, group = ( - self._backend._ec_key_determine_group_get_set_funcs(self._ec_key) - ) - point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) - assert point != self._backend._ffi.NULL - - with self._backend._tmp_bn_ctx() as bn_ctx: - bn_x = self._backend._lib.BN_CTX_get(bn_ctx) - bn_y = self._backend._lib.BN_CTX_get(bn_ctx) - - res = get_func(group, point, bn_x, bn_y, bn_ctx) - assert res == 1 - - x = self._backend._bn_to_int(bn_x) - y = self._backend._bn_to_int(bn_y) - - return ec.EllipticCurvePublicNumbers( - x=x, - y=y, - curve=self._curve - ) diff --git a/cryptography/hazmat/backends/openssl/hashes.py b/cryptography/hazmat/backends/openssl/hashes.py deleted file mode 100644 index 591c014a..00000000 --- a/cryptography/hazmat/backends/openssl/hashes.py +++ /dev/null @@ -1,71 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - - -from cryptography import utils -from cryptography.exceptions import UnsupportedAlgorithm, _Reasons -from cryptography.hazmat.primitives import interfaces - - -@utils.register_interface(interfaces.HashContext) -class _HashContext(object): - def __init__(self, backend, algorithm, ctx=None): - self._algorithm = algorithm - - self._backend = backend - - if ctx is None: - ctx = self._backend._lib.EVP_MD_CTX_create() - ctx = self._backend._ffi.gc(ctx, - self._backend._lib.EVP_MD_CTX_destroy) - evp_md = self._backend._lib.EVP_get_digestbyname( - algorithm.name.encode("ascii")) - if evp_md == self._backend._ffi.NULL: - raise UnsupportedAlgorithm( - "{0} is not a supported hash on this backend.".format( - algorithm.name), - _Reasons.UNSUPPORTED_HASH - ) - res = self._backend._lib.EVP_DigestInit_ex(ctx, evp_md, - self._backend._ffi.NULL) - assert res != 0 - - self._ctx = ctx - - algorithm = utils.read_only_property("_algorithm") - - def copy(self): - copied_ctx = self._backend._lib.EVP_MD_CTX_create() - copied_ctx = self._backend._ffi.gc( - copied_ctx, self._backend._lib.EVP_MD_CTX_destroy - ) - res = self._backend._lib.EVP_MD_CTX_copy_ex(copied_ctx, self._ctx) - assert res != 0 - return _HashContext(self._backend, self.algorithm, ctx=copied_ctx) - - def update(self, data): - res = self._backend._lib.EVP_DigestUpdate(self._ctx, data, len(data)) - assert res != 0 - - def finalize(self): - buf = self._backend._ffi.new("unsigned char[]", - self._backend._lib.EVP_MAX_MD_SIZE) - outlen = self._backend._ffi.new("unsigned int *") - res = self._backend._lib.EVP_DigestFinal_ex(self._ctx, buf, outlen) - assert res != 0 - assert outlen[0] == self.algorithm.digest_size - res = self._backend._lib.EVP_MD_CTX_cleanup(self._ctx) - assert res == 1 - return self._backend._ffi.buffer(buf)[:outlen[0]] diff --git a/cryptography/hazmat/backends/openssl/hmac.py b/cryptography/hazmat/backends/openssl/hmac.py deleted file mode 100644 index c324bd8c..00000000 --- a/cryptography/hazmat/backends/openssl/hmac.py +++ /dev/null @@ -1,90 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - - -from cryptography import utils -from cryptography.exceptions import ( - InvalidSignature, UnsupportedAlgorithm, _Reasons -) -from cryptography.hazmat.primitives import constant_time, interfaces - - -@utils.register_interface(interfaces.MACContext) -@utils.register_interface(interfaces.HashContext) -class _HMACContext(object): - def __init__(self, backend, key, algorithm, ctx=None): - self._algorithm = algorithm - self._backend = backend - - if ctx is None: - ctx = self._backend._ffi.new("HMAC_CTX *") - self._backend._lib.HMAC_CTX_init(ctx) - ctx = self._backend._ffi.gc( - ctx, self._backend._lib.HMAC_CTX_cleanup - ) - evp_md = self._backend._lib.EVP_get_digestbyname( - algorithm.name.encode('ascii')) - if evp_md == self._backend._ffi.NULL: - raise UnsupportedAlgorithm( - "{0} is not a supported hash on this backend.".format( - algorithm.name), - _Reasons.UNSUPPORTED_HASH - ) - res = self._backend._lib.Cryptography_HMAC_Init_ex( - ctx, key, len(key), evp_md, self._backend._ffi.NULL - ) - assert res != 0 - - self._ctx = ctx - self._key = key - - algorithm = utils.read_only_property("_algorithm") - - def copy(self): - copied_ctx = self._backend._ffi.new("HMAC_CTX *") - self._backend._lib.HMAC_CTX_init(copied_ctx) - copied_ctx = self._backend._ffi.gc( - copied_ctx, self._backend._lib.HMAC_CTX_cleanup - ) - res = self._backend._lib.Cryptography_HMAC_CTX_copy( - copied_ctx, self._ctx - ) - assert res != 0 - return _HMACContext( - self._backend, self._key, self.algorithm, ctx=copied_ctx - ) - - def update(self, data): - res = self._backend._lib.Cryptography_HMAC_Update( - self._ctx, data, len(data) - ) - assert res != 0 - - def finalize(self): - buf = self._backend._ffi.new("unsigned char[]", - self._backend._lib.EVP_MAX_MD_SIZE) - outlen = self._backend._ffi.new("unsigned int *") - res = self._backend._lib.Cryptography_HMAC_Final( - self._ctx, buf, outlen - ) - assert res != 0 - assert outlen[0] == self.algorithm.digest_size - self._backend._lib.HMAC_CTX_cleanup(self._ctx) - return self._backend._ffi.buffer(buf)[:outlen[0]] - - def verify(self, signature): - digest = self.finalize() - if not constant_time.bytes_eq(digest, signature): - raise InvalidSignature("Signature did not match digest.") diff --git a/cryptography/hazmat/backends/openssl/rsa.py b/cryptography/hazmat/backends/openssl/rsa.py deleted file mode 100644 index 0a2a7f96..00000000 --- a/cryptography/hazmat/backends/openssl/rsa.py +++ /dev/null @@ -1,603 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import math - -from cryptography import utils -from cryptography.exceptions import ( - AlreadyFinalized, InvalidSignature, UnsupportedAlgorithm, _Reasons -) -from cryptography.hazmat.primitives import hashes, interfaces -from cryptography.hazmat.primitives.asymmetric import rsa -from cryptography.hazmat.primitives.asymmetric.padding import ( - MGF1, OAEP, PKCS1v15, PSS -) -from cryptography.hazmat.primitives.interfaces import ( - RSAPrivateKeyWithNumbers, RSAPublicKeyWithNumbers -) - - -def _get_rsa_pss_salt_length(pss, key_size, digest_size): - salt = pss._salt_length - - if salt is MGF1.MAX_LENGTH or salt is PSS.MAX_LENGTH: - # bit length - 1 per RFC 3447 - emlen = int(math.ceil((key_size - 1) / 8.0)) - salt_length = emlen - digest_size - 2 - assert salt_length >= 0 - return salt_length - else: - return salt - - -def _enc_dec_rsa(backend, key, data, padding): - if not isinstance(padding, interfaces.AsymmetricPadding): - raise TypeError("Padding must be an instance of AsymmetricPadding.") - - if isinstance(padding, PKCS1v15): - padding_enum = backend._lib.RSA_PKCS1_PADDING - elif isinstance(padding, OAEP): - padding_enum = backend._lib.RSA_PKCS1_OAEP_PADDING - if not isinstance(padding._mgf, MGF1): - raise UnsupportedAlgorithm( - "Only MGF1 is supported by this backend.", - _Reasons.UNSUPPORTED_MGF - ) - - if not isinstance(padding._mgf._algorithm, hashes.SHA1): - raise UnsupportedAlgorithm( - "This backend supports only SHA1 inside MGF1 when " - "using OAEP.", - _Reasons.UNSUPPORTED_HASH - ) - - if padding._label is not None and padding._label != b"": - raise ValueError("This backend does not support OAEP labels.") - - if not isinstance(padding._algorithm, hashes.SHA1): - raise UnsupportedAlgorithm( - "This backend only supports SHA1 when using OAEP.", - _Reasons.UNSUPPORTED_HASH - ) - else: - raise UnsupportedAlgorithm( - "{0} is not supported by this backend.".format( - padding.name - ), - _Reasons.UNSUPPORTED_PADDING - ) - - if backend._lib.Cryptography_HAS_PKEY_CTX: - return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum) - else: - return _enc_dec_rsa_098(backend, key, data, padding_enum) - - -def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum): - if isinstance(key, _RSAPublicKey): - init = backend._lib.EVP_PKEY_encrypt_init - crypt = backend._lib.Cryptography_EVP_PKEY_encrypt - else: - init = backend._lib.EVP_PKEY_decrypt_init - crypt = backend._lib.Cryptography_EVP_PKEY_decrypt - - pkey_ctx = backend._lib.EVP_PKEY_CTX_new( - key._evp_pkey, backend._ffi.NULL - ) - assert pkey_ctx != backend._ffi.NULL - pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free) - res = init(pkey_ctx) - assert res == 1 - res = backend._lib.EVP_PKEY_CTX_set_rsa_padding( - pkey_ctx, padding_enum) - assert res > 0 - buf_size = backend._lib.EVP_PKEY_size(key._evp_pkey) - assert buf_size > 0 - outlen = backend._ffi.new("size_t *", buf_size) - buf = backend._ffi.new("char[]", buf_size) - res = crypt(pkey_ctx, buf, outlen, data, len(data)) - if res <= 0: - _handle_rsa_enc_dec_error(backend, key) - - return backend._ffi.buffer(buf)[:outlen[0]] - - -def _enc_dec_rsa_098(backend, key, data, padding_enum): - if isinstance(key, _RSAPublicKey): - crypt = backend._lib.RSA_public_encrypt - else: - crypt = backend._lib.RSA_private_decrypt - - key_size = backend._lib.RSA_size(key._rsa_cdata) - assert key_size > 0 - buf = backend._ffi.new("unsigned char[]", key_size) - res = crypt(len(data), data, buf, key._rsa_cdata, padding_enum) - if res < 0: - _handle_rsa_enc_dec_error(backend, key) - - return backend._ffi.buffer(buf)[:res] - - -def _handle_rsa_enc_dec_error(backend, key): - errors = backend._consume_errors() - assert errors - assert errors[0].lib == backend._lib.ERR_LIB_RSA - if isinstance(key, _RSAPublicKey): - assert (errors[0].reason == - backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE) - raise ValueError( - "Data too long for key size. Encrypt less data or use a " - "larger key size." - ) - else: - decoding_errors = [ - backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_01, - backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_02, - ] - if backend._lib.Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR: - decoding_errors.append(backend._lib.RSA_R_PKCS_DECODING_ERROR) - - assert errors[0].reason in decoding_errors - raise ValueError("Decryption failed.") - - -@utils.register_interface(interfaces.AsymmetricSignatureContext) -class _RSASignatureContext(object): - def __init__(self, backend, private_key, padding, algorithm): - self._backend = backend - self._private_key = private_key - - if not isinstance(padding, interfaces.AsymmetricPadding): - raise TypeError( - "Expected provider of interfaces.AsymmetricPadding.") - - self._pkey_size = self._backend._lib.EVP_PKEY_size( - self._private_key._evp_pkey - ) - - if isinstance(padding, PKCS1v15): - if self._backend._lib.Cryptography_HAS_PKEY_CTX: - self._finalize_method = self._finalize_pkey_ctx - self._padding_enum = self._backend._lib.RSA_PKCS1_PADDING - else: - self._finalize_method = self._finalize_pkcs1 - elif isinstance(padding, PSS): - if not isinstance(padding._mgf, MGF1): - raise UnsupportedAlgorithm( - "Only MGF1 is supported by this backend.", - _Reasons.UNSUPPORTED_MGF - ) - - # Size of key in bytes - 2 is the maximum - # PSS signature length (salt length is checked later) - assert self._pkey_size > 0 - if self._pkey_size - algorithm.digest_size - 2 < 0: - raise ValueError("Digest too large for key size. Use a larger " - "key.") - - if not self._backend._mgf1_hash_supported(padding._mgf._algorithm): - raise UnsupportedAlgorithm( - "When OpenSSL is older than 1.0.1 then only SHA1 is " - "supported with MGF1.", - _Reasons.UNSUPPORTED_HASH - ) - - if self._backend._lib.Cryptography_HAS_PKEY_CTX: - self._finalize_method = self._finalize_pkey_ctx - self._padding_enum = self._backend._lib.RSA_PKCS1_PSS_PADDING - else: - self._finalize_method = self._finalize_pss - else: - raise UnsupportedAlgorithm( - "{0} is not supported by this backend.".format(padding.name), - _Reasons.UNSUPPORTED_PADDING - ) - - self._padding = padding - self._algorithm = algorithm - self._hash_ctx = hashes.Hash(self._algorithm, self._backend) - - def update(self, data): - self._hash_ctx.update(data) - - def finalize(self): - evp_md = self._backend._lib.EVP_get_digestbyname( - self._algorithm.name.encode("ascii")) - assert evp_md != self._backend._ffi.NULL - - return self._finalize_method(evp_md) - - def _finalize_pkey_ctx(self, evp_md): - pkey_ctx = self._backend._lib.EVP_PKEY_CTX_new( - self._private_key._evp_pkey, self._backend._ffi.NULL - ) - assert pkey_ctx != self._backend._ffi.NULL - pkey_ctx = self._backend._ffi.gc(pkey_ctx, - self._backend._lib.EVP_PKEY_CTX_free) - res = self._backend._lib.EVP_PKEY_sign_init(pkey_ctx) - assert res == 1 - res = self._backend._lib.EVP_PKEY_CTX_set_signature_md( - pkey_ctx, evp_md) - assert res > 0 - - res = self._backend._lib.EVP_PKEY_CTX_set_rsa_padding( - pkey_ctx, self._padding_enum) - assert res > 0 - if isinstance(self._padding, PSS): - res = self._backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen( - pkey_ctx, - _get_rsa_pss_salt_length( - self._padding, - self._private_key.key_size, - self._hash_ctx.algorithm.digest_size - ) - ) - assert res > 0 - - if self._backend._lib.Cryptography_HAS_MGF1_MD: - # MGF1 MD is configurable in OpenSSL 1.0.1+ - mgf1_md = self._backend._lib.EVP_get_digestbyname( - self._padding._mgf._algorithm.name.encode("ascii")) - assert mgf1_md != self._backend._ffi.NULL - res = self._backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md( - pkey_ctx, mgf1_md - ) - assert res > 0 - data_to_sign = self._hash_ctx.finalize() - buflen = self._backend._ffi.new("size_t *") - res = self._backend._lib.EVP_PKEY_sign( - pkey_ctx, - self._backend._ffi.NULL, - buflen, - data_to_sign, - len(data_to_sign) - ) - assert res == 1 - buf = self._backend._ffi.new("unsigned char[]", buflen[0]) - res = self._backend._lib.EVP_PKEY_sign( - pkey_ctx, buf, buflen, data_to_sign, len(data_to_sign)) - if res != 1: - errors = self._backend._consume_errors() - assert errors[0].lib == self._backend._lib.ERR_LIB_RSA - reason = None - if (errors[0].reason == - self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE): - reason = ("Salt length too long for key size. Try using " - "MAX_LENGTH instead.") - elif (errors[0].reason == - self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY): - reason = "Digest too large for key size. Use a larger key." - assert reason is not None - raise ValueError(reason) - - return self._backend._ffi.buffer(buf)[:] - - def _finalize_pkcs1(self, evp_md): - if self._hash_ctx._ctx is None: - raise AlreadyFinalized("Context has already been finalized.") - - sig_buf = self._backend._ffi.new("char[]", self._pkey_size) - sig_len = self._backend._ffi.new("unsigned int *") - res = self._backend._lib.EVP_SignFinal( - self._hash_ctx._ctx._ctx, - sig_buf, - sig_len, - self._private_key._evp_pkey - ) - self._hash_ctx.finalize() - if res == 0: - errors = self._backend._consume_errors() - assert errors[0].lib == self._backend._lib.ERR_LIB_RSA - assert (errors[0].reason == - self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY) - raise ValueError("Digest too large for key size. Use a larger " - "key.") - - return self._backend._ffi.buffer(sig_buf)[:sig_len[0]] - - def _finalize_pss(self, evp_md): - data_to_sign = self._hash_ctx.finalize() - padded = self._backend._ffi.new("unsigned char[]", self._pkey_size) - res = self._backend._lib.RSA_padding_add_PKCS1_PSS( - self._private_key._rsa_cdata, - padded, - data_to_sign, - evp_md, - _get_rsa_pss_salt_length( - self._padding, - self._private_key.key_size, - len(data_to_sign) - ) - ) - if res != 1: - errors = self._backend._consume_errors() - assert errors[0].lib == self._backend._lib.ERR_LIB_RSA - assert (errors[0].reason == - self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE) - raise ValueError("Salt length too long for key size. Try using " - "MAX_LENGTH instead.") - - sig_buf = self._backend._ffi.new("char[]", self._pkey_size) - sig_len = self._backend._lib.RSA_private_encrypt( - self._pkey_size, - padded, - sig_buf, - self._private_key._rsa_cdata, - self._backend._lib.RSA_NO_PADDING - ) - assert sig_len != -1 - return self._backend._ffi.buffer(sig_buf)[:sig_len] - - -@utils.register_interface(interfaces.AsymmetricVerificationContext) -class _RSAVerificationContext(object): - def __init__(self, backend, public_key, signature, padding, algorithm): - self._backend = backend - self._public_key = public_key - self._signature = signature - - if not isinstance(padding, interfaces.AsymmetricPadding): - raise TypeError( - "Expected provider of interfaces.AsymmetricPadding.") - - self._pkey_size = self._backend._lib.EVP_PKEY_size( - self._public_key._evp_pkey - ) - - if isinstance(padding, PKCS1v15): - if self._backend._lib.Cryptography_HAS_PKEY_CTX: - self._verify_method = self._verify_pkey_ctx - self._padding_enum = self._backend._lib.RSA_PKCS1_PADDING - else: - self._verify_method = self._verify_pkcs1 - elif isinstance(padding, PSS): - if not isinstance(padding._mgf, MGF1): - raise UnsupportedAlgorithm( - "Only MGF1 is supported by this backend.", - _Reasons.UNSUPPORTED_MGF - ) - - # Size of key in bytes - 2 is the maximum - # PSS signature length (salt length is checked later) - assert self._pkey_size > 0 - if self._pkey_size - algorithm.digest_size - 2 < 0: - raise ValueError( - "Digest too large for key size. Check that you have the " - "correct key and digest algorithm." - ) - - if not self._backend._mgf1_hash_supported(padding._mgf._algorithm): - raise UnsupportedAlgorithm( - "When OpenSSL is older than 1.0.1 then only SHA1 is " - "supported with MGF1.", - _Reasons.UNSUPPORTED_HASH - ) - - if self._backend._lib.Cryptography_HAS_PKEY_CTX: - self._verify_method = self._verify_pkey_ctx - self._padding_enum = self._backend._lib.RSA_PKCS1_PSS_PADDING - else: - self._verify_method = self._verify_pss - else: - raise UnsupportedAlgorithm( - "{0} is not supported by this backend.".format(padding.name), - _Reasons.UNSUPPORTED_PADDING - ) - - self._padding = padding - self._algorithm = algorithm - self._hash_ctx = hashes.Hash(self._algorithm, self._backend) - - def update(self, data): - self._hash_ctx.update(data) - - def verify(self): - evp_md = self._backend._lib.EVP_get_digestbyname( - self._algorithm.name.encode("ascii")) - assert evp_md != self._backend._ffi.NULL - - self._verify_method(evp_md) - - def _verify_pkey_ctx(self, evp_md): - pkey_ctx = self._backend._lib.EVP_PKEY_CTX_new( - self._public_key._evp_pkey, self._backend._ffi.NULL - ) - assert pkey_ctx != self._backend._ffi.NULL - pkey_ctx = self._backend._ffi.gc(pkey_ctx, - self._backend._lib.EVP_PKEY_CTX_free) - res = self._backend._lib.EVP_PKEY_verify_init(pkey_ctx) - assert res == 1 - res = self._backend._lib.EVP_PKEY_CTX_set_signature_md( - pkey_ctx, evp_md) - assert res > 0 - - res = self._backend._lib.EVP_PKEY_CTX_set_rsa_padding( - pkey_ctx, self._padding_enum) - assert res > 0 - if isinstance(self._padding, PSS): - res = self._backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen( - pkey_ctx, - _get_rsa_pss_salt_length( - self._padding, - self._public_key.key_size, - self._hash_ctx.algorithm.digest_size - ) - ) - assert res > 0 - if self._backend._lib.Cryptography_HAS_MGF1_MD: - # MGF1 MD is configurable in OpenSSL 1.0.1+ - mgf1_md = self._backend._lib.EVP_get_digestbyname( - self._padding._mgf._algorithm.name.encode("ascii")) - assert mgf1_md != self._backend._ffi.NULL - res = self._backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md( - pkey_ctx, mgf1_md - ) - assert res > 0 - - data_to_verify = self._hash_ctx.finalize() - res = self._backend._lib.EVP_PKEY_verify( - pkey_ctx, - self._signature, - len(self._signature), - data_to_verify, - len(data_to_verify) - ) - # The previous call can return negative numbers in the event of an - # error. This is not a signature failure but we need to fail if it - # occurs. - assert res >= 0 - if res == 0: - errors = self._backend._consume_errors() - assert errors - raise InvalidSignature - - def _verify_pkcs1(self, evp_md): - if self._hash_ctx._ctx is None: - raise AlreadyFinalized("Context has already been finalized.") - - res = self._backend._lib.EVP_VerifyFinal( - self._hash_ctx._ctx._ctx, - self._signature, - len(self._signature), - self._public_key._evp_pkey - ) - self._hash_ctx.finalize() - # The previous call can return negative numbers in the event of an - # error. This is not a signature failure but we need to fail if it - # occurs. - assert res >= 0 - if res == 0: - errors = self._backend._consume_errors() - assert errors - raise InvalidSignature - - def _verify_pss(self, evp_md): - buf = self._backend._ffi.new("unsigned char[]", self._pkey_size) - res = self._backend._lib.RSA_public_decrypt( - len(self._signature), - self._signature, - buf, - self._public_key._rsa_cdata, - self._backend._lib.RSA_NO_PADDING - ) - if res != self._pkey_size: - errors = self._backend._consume_errors() - assert errors - raise InvalidSignature - - data_to_verify = self._hash_ctx.finalize() - res = self._backend._lib.RSA_verify_PKCS1_PSS( - self._public_key._rsa_cdata, - data_to_verify, - evp_md, - buf, - _get_rsa_pss_salt_length( - self._padding, - self._public_key.key_size, - len(data_to_verify) - ) - ) - if res != 1: - errors = self._backend._consume_errors() - assert errors - raise InvalidSignature - - -@utils.register_interface(RSAPrivateKeyWithNumbers) -class _RSAPrivateKey(object): - def __init__(self, backend, rsa_cdata): - self._backend = backend - self._rsa_cdata = rsa_cdata - - evp_pkey = self._backend._lib.EVP_PKEY_new() - assert evp_pkey != self._backend._ffi.NULL - evp_pkey = self._backend._ffi.gc( - evp_pkey, self._backend._lib.EVP_PKEY_free - ) - res = self._backend._lib.EVP_PKEY_set1_RSA(evp_pkey, rsa_cdata) - assert res == 1 - self._evp_pkey = evp_pkey - - self._key_size = self._backend._lib.BN_num_bits(self._rsa_cdata.n) - - key_size = utils.read_only_property("_key_size") - - def signer(self, padding, algorithm): - return _RSASignatureContext(self._backend, self, padding, algorithm) - - def decrypt(self, ciphertext, padding): - key_size_bytes = int(math.ceil(self.key_size / 8.0)) - if key_size_bytes != len(ciphertext): - raise ValueError("Ciphertext length must be equal to key size.") - - return _enc_dec_rsa(self._backend, self, ciphertext, padding) - - def public_key(self): - ctx = self._backend._lib.RSA_new() - assert ctx != self._backend._ffi.NULL - ctx = self._backend._ffi.gc(ctx, self._backend._lib.RSA_free) - ctx.e = self._backend._lib.BN_dup(self._rsa_cdata.e) - ctx.n = self._backend._lib.BN_dup(self._rsa_cdata.n) - res = self._backend._lib.RSA_blinding_on(ctx, self._backend._ffi.NULL) - assert res == 1 - return _RSAPublicKey(self._backend, ctx) - - def private_numbers(self): - return rsa.RSAPrivateNumbers( - p=self._backend._bn_to_int(self._rsa_cdata.p), - q=self._backend._bn_to_int(self._rsa_cdata.q), - d=self._backend._bn_to_int(self._rsa_cdata.d), - dmp1=self._backend._bn_to_int(self._rsa_cdata.dmp1), - dmq1=self._backend._bn_to_int(self._rsa_cdata.dmq1), - iqmp=self._backend._bn_to_int(self._rsa_cdata.iqmp), - public_numbers=rsa.RSAPublicNumbers( - e=self._backend._bn_to_int(self._rsa_cdata.e), - n=self._backend._bn_to_int(self._rsa_cdata.n), - ) - ) - - -@utils.register_interface(RSAPublicKeyWithNumbers) -class _RSAPublicKey(object): - def __init__(self, backend, rsa_cdata): - self._backend = backend - self._rsa_cdata = rsa_cdata - - evp_pkey = self._backend._lib.EVP_PKEY_new() - assert evp_pkey != self._backend._ffi.NULL - evp_pkey = self._backend._ffi.gc( - evp_pkey, self._backend._lib.EVP_PKEY_free - ) - res = self._backend._lib.EVP_PKEY_set1_RSA(evp_pkey, rsa_cdata) - assert res == 1 - self._evp_pkey = evp_pkey - - self._key_size = self._backend._lib.BN_num_bits(self._rsa_cdata.n) - - key_size = utils.read_only_property("_key_size") - - def verifier(self, signature, padding, algorithm): - return _RSAVerificationContext( - self._backend, self, signature, padding, algorithm - ) - - def encrypt(self, plaintext, padding): - return _enc_dec_rsa(self._backend, self, plaintext, padding) - - def public_numbers(self): - return rsa.RSAPublicNumbers( - e=self._backend._bn_to_int(self._rsa_cdata.e), - n=self._backend._bn_to_int(self._rsa_cdata.n), - ) diff --git a/cryptography/hazmat/backends/openssl/utils.py b/cryptography/hazmat/backends/openssl/utils.py deleted file mode 100644 index 408b6146..00000000 --- a/cryptography/hazmat/backends/openssl/utils.py +++ /dev/null @@ -1,35 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import six - - -def _truncate_digest(digest, order_bits): - digest_len = len(digest) - - if 8 * digest_len > order_bits: - digest_len = (order_bits + 7) // 8 - digest = digest[:digest_len] - - if 8 * digest_len > order_bits: - rshift = 8 - (order_bits & 0x7) - assert rshift > 0 and rshift < 8 - - mask = 0xFF >> rshift << rshift - - # Set the bottom rshift bits to 0 - digest = digest[:-1] + six.int2byte(six.indexbytes(digest, -1) & mask) - - return digest diff --git a/cryptography/hazmat/bindings/__init__.py b/cryptography/hazmat/bindings/__init__.py deleted file mode 100644 index 2f420574..00000000 --- a/cryptography/hazmat/bindings/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function diff --git a/cryptography/hazmat/bindings/commoncrypto/__init__.py b/cryptography/hazmat/bindings/commoncrypto/__init__.py deleted file mode 100644 index 2f420574..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function diff --git a/cryptography/hazmat/bindings/commoncrypto/binding.py b/cryptography/hazmat/bindings/commoncrypto/binding.py deleted file mode 100644 index bb950aac..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/binding.py +++ /dev/null @@ -1,60 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography.hazmat.bindings.utils import ( - build_ffi_for_binding, load_library_for_binding, -) - - -class Binding(object): - """ - CommonCrypto API wrapper. - """ - _module_prefix = "cryptography.hazmat.bindings.commoncrypto." - _modules = [ - "cf", - "common_digest", - "common_hmac", - "common_key_derivation", - "common_cryptor", - "secimport", - "secitem", - "seckey", - "seckeychain", - "sectransform", - ] - - ffi = build_ffi_for_binding( - module_prefix=_module_prefix, - modules=_modules, - extra_link_args=[ - "-framework", "Security", "-framework", "CoreFoundation" - ], - ) - lib = None - - def __init__(self): - self._ensure_ffi_initialized() - - @classmethod - def _ensure_ffi_initialized(cls): - if cls.lib is not None: - return - - cls.lib = load_library_for_binding( - cls.ffi, - module_prefix=cls._module_prefix, - modules=cls._modules, - ) diff --git a/cryptography/hazmat/bindings/commoncrypto/cf.py b/cryptography/hazmat/bindings/commoncrypto/cf.py deleted file mode 100644 index 671963a3..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/cf.py +++ /dev/null @@ -1,114 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -TYPES = """ -typedef bool Boolean; -typedef signed long OSStatus; -typedef unsigned char UInt8; -typedef uint32_t UInt32; - -typedef const void * CFAllocatorRef; -const CFAllocatorRef kCFAllocatorDefault; -typedef const void * CFDataRef; -typedef signed long long CFIndex; -typedef ... *CFStringRef; -typedef ... *CFArrayRef; -typedef ... *CFBooleanRef; -typedef ... *CFErrorRef; -typedef ... *CFNumberRef; -typedef ... *CFTypeRef; -typedef ... *CFDictionaryRef; -typedef ... *CFMutableDictionaryRef; -typedef struct { - ...; -} CFDictionaryKeyCallBacks; -typedef struct { - ...; -} CFDictionaryValueCallBacks; -typedef struct { - ...; -} CFRange; - -typedef UInt32 CFStringEncoding; -enum { - kCFStringEncodingASCII = 0x0600 -}; - -enum { - kCFNumberSInt8Type = 1, - kCFNumberSInt16Type = 2, - kCFNumberSInt32Type = 3, - kCFNumberSInt64Type = 4, - kCFNumberFloat32Type = 5, - kCFNumberFloat64Type = 6, - kCFNumberCharType = 7, - kCFNumberShortType = 8, - kCFNumberIntType = 9, - kCFNumberLongType = 10, - kCFNumberLongLongType = 11, - kCFNumberFloatType = 12, - kCFNumberDoubleType = 13, - kCFNumberCFIndexType = 14, - kCFNumberNSIntegerType = 15, - kCFNumberCGFloatType = 16, - kCFNumberMaxType = 16 -}; -typedef int CFNumberType; - -const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; -const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; - -const CFBooleanRef kCFBooleanTrue; -const CFBooleanRef kCFBooleanFalse; -""" - -FUNCTIONS = """ -CFDataRef CFDataCreate(CFAllocatorRef, const UInt8 *, CFIndex); -CFStringRef CFStringCreateWithCString(CFAllocatorRef, const char *, - CFStringEncoding); -CFDictionaryRef CFDictionaryCreate(CFAllocatorRef, const void **, - const void **, CFIndex, - const CFDictionaryKeyCallBacks *, - const CFDictionaryValueCallBacks *); -CFMutableDictionaryRef CFDictionaryCreateMutable( - CFAllocatorRef, - CFIndex, - const CFDictionaryKeyCallBacks *, - const CFDictionaryValueCallBacks * -); -void CFDictionarySetValue(CFMutableDictionaryRef, const void *, const void *); -CFIndex CFArrayGetCount(CFArrayRef); -const void *CFArrayGetValueAtIndex(CFArrayRef, CFIndex); -CFIndex CFDataGetLength(CFDataRef); -void CFDataGetBytes(CFDataRef, CFRange, UInt8 *); -CFRange CFRangeMake(CFIndex, CFIndex); -void CFShow(CFTypeRef); -Boolean CFBooleanGetValue(CFBooleanRef); -CFNumberRef CFNumberCreate(CFAllocatorRef, CFNumberType, const void *); -void CFRelease(CFTypeRef); -CFTypeRef CFRetain(CFTypeRef); -""" - -MACROS = """ -""" - -CUSTOMIZATIONS = """ -""" - -CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py b/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py deleted file mode 100644 index 713bc566..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py +++ /dev/null @@ -1,110 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/commoncrypto/common_digest.py b/cryptography/hazmat/bindings/commoncrypto/common_digest.py deleted file mode 100644 index c59200cb..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/common_digest.py +++ /dev/null @@ -1,69 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/commoncrypto/common_hmac.py b/cryptography/hazmat/bindings/commoncrypto/common_hmac.py deleted file mode 100644 index 4f54b62b..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/common_hmac.py +++ /dev/null @@ -1,48 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py b/cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py deleted file mode 100644 index e8cc03ef..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py +++ /dev/null @@ -1,50 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/commoncrypto/secimport.py b/cryptography/hazmat/bindings/commoncrypto/secimport.py deleted file mode 100644 index add62c79..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/secimport.py +++ /dev/null @@ -1,95 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -TYPES = """ -typedef ... *SecAccessRef; - -CFStringRef kSecImportExportPassphrase; -CFStringRef kSecImportExportKeychain; -CFStringRef kSecImportExportAccess; - -typedef uint32_t SecExternalItemType; -enum { - kSecItemTypeUnknown, - kSecItemTypePrivateKey, - kSecItemTypePublicKey, - kSecItemTypeSessionKey, - kSecItemTypeCertificate, - kSecItemTypeAggregate -}; - - -typedef uint32_t SecExternalFormat; -enum { - kSecFormatUnknown = 0, - kSecFormatOpenSSL, - kSecFormatSSH, - kSecFormatBSAFE, - kSecFormatRawKey, - kSecFormatWrappedPKCS8, - kSecFormatWrappedOpenSSL, - kSecFormatWrappedSSH, - kSecFormatWrappedLSH, - kSecFormatX509Cert, - kSecFormatPEMSequence, - kSecFormatPKCS7, - kSecFormatPKCS12, - kSecFormatNetscapeCertSequence, - kSecFormatSSHv2 -}; - -typedef uint32_t SecItemImportExportFlags; -enum { - kSecKeyImportOnlyOne = 0x00000001, - kSecKeySecurePassphrase = 0x00000002, - kSecKeyNoAccessControl = 0x00000004 -}; -typedef uint32_t SecKeyImportExportFlags; - -typedef struct { - /* for import and export */ - uint32_t version; - SecKeyImportExportFlags flags; - CFTypeRef passphrase; - CFStringRef alertTitle; - CFStringRef alertPrompt; - - /* for import only */ - SecAccessRef accessRef; - CFArrayRef keyUsage; - - CFArrayRef keyAttributes; -} SecItemImportExportKeyParameters; -""" - -FUNCTIONS = """ -OSStatus SecItemImport(CFDataRef, CFStringRef, SecExternalFormat *, - SecExternalItemType *, SecItemImportExportFlags, - const SecItemImportExportKeyParameters *, - SecKeychainRef, CFArrayRef *); -OSStatus SecPKCS12Import(CFDataRef, CFDictionaryRef, CFArrayRef *); -""" - -MACROS = """ -""" - -CUSTOMIZATIONS = """ -""" - -CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/commoncrypto/secitem.py b/cryptography/hazmat/bindings/commoncrypto/secitem.py deleted file mode 100644 index ac3dad3f..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/secitem.py +++ /dev/null @@ -1,38 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -TYPES = """ -const CFTypeRef kSecAttrKeyType; -const CFTypeRef kSecAttrKeySizeInBits; -const CFTypeRef kSecAttrIsPermanent; -const CFTypeRef kSecAttrKeyTypeRSA; -const CFTypeRef kSecAttrKeyTypeDSA; -const CFTypeRef kSecUseKeychain; -""" - -FUNCTIONS = """ -""" - -MACROS = """ -""" - -CUSTOMIZATIONS = """ -""" - -CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/commoncrypto/seckey.py b/cryptography/hazmat/bindings/commoncrypto/seckey.py deleted file mode 100644 index 5e4b6dac..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/seckey.py +++ /dev/null @@ -1,35 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -TYPES = """ -typedef ... *SecKeyRef; -""" - -FUNCTIONS = """ -OSStatus SecKeyGeneratePair(CFDictionaryRef, SecKeyRef *, SecKeyRef *); -size_t SecKeyGetBlockSize(SecKeyRef); -""" - -MACROS = """ -""" - -CUSTOMIZATIONS = """ -""" - -CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/commoncrypto/seckeychain.py b/cryptography/hazmat/bindings/commoncrypto/seckeychain.py deleted file mode 100644 index c045c347..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/seckeychain.py +++ /dev/null @@ -1,36 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -TYPES = """ -typedef ... *SecKeychainRef; -""" - -FUNCTIONS = """ -OSStatus SecKeychainCreate(const char *, UInt32, const void *, Boolean, - SecAccessRef, SecKeychainRef *); -OSStatus SecKeychainDelete(SecKeychainRef); -""" - -MACROS = """ -""" - -CUSTOMIZATIONS = """ -""" - -CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/commoncrypto/sectransform.py b/cryptography/hazmat/bindings/commoncrypto/sectransform.py deleted file mode 100644 index d6dbc5f6..00000000 --- a/cryptography/hazmat/bindings/commoncrypto/sectransform.py +++ /dev/null @@ -1,79 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -#include -#include -""" - -TYPES = """ -typedef ... *SecTransformRef; - -CFStringRef kSecImportExportPassphrase; -CFStringRef kSecImportExportKeychain; -CFStringRef kSecImportExportAccess; - -CFStringRef kSecEncryptionMode; -CFStringRef kSecEncryptKey; -CFStringRef kSecIVKey; -CFStringRef kSecModeCBCKey; -CFStringRef kSecModeCFBKey; -CFStringRef kSecModeECBKey; -CFStringRef kSecModeNoneKey; -CFStringRef kSecModeOFBKey; -CFStringRef kSecOAEPEncodingParametersAttributeName; -CFStringRef kSecPaddingKey; -CFStringRef kSecPaddingNoneKey; -CFStringRef kSecPaddingOAEPKey; -CFStringRef kSecPaddingPKCS1Key; -CFStringRef kSecPaddingPKCS5Key; -CFStringRef kSecPaddingPKCS7Key; - -const CFStringRef kSecTransformInputAttributeName; -const CFStringRef kSecTransformOutputAttributeName; -const CFStringRef kSecTransformDebugAttributeName; -const CFStringRef kSecTransformTransformName; -const CFStringRef kSecTransformAbortAttributeName; - -CFStringRef kSecInputIsAttributeName; -CFStringRef kSecInputIsPlainText; -CFStringRef kSecInputIsDigest; -CFStringRef kSecInputIsRaw; - -const CFStringRef kSecDigestTypeAttribute; -const CFStringRef kSecDigestLengthAttribute; -const CFStringRef kSecDigestMD5; -const CFStringRef kSecDigestSHA1; -const CFStringRef kSecDigestSHA2; -""" - -FUNCTIONS = """ -Boolean SecTransformSetAttribute(SecTransformRef, CFStringRef, CFTypeRef, - CFErrorRef *); -SecTransformRef SecDecryptTransformCreate(SecKeyRef, CFErrorRef *); -SecTransformRef SecEncryptTransformCreate(SecKeyRef, CFErrorRef *); -SecTransformRef SecVerifyTransformCreate(SecKeyRef, CFDataRef, CFErrorRef *); -SecTransformRef SecSignTransformCreate(SecKeyRef, CFErrorRef *) ; -CFTypeRef SecTransformExecute(SecTransformRef, CFErrorRef *); -""" - -MACROS = """ -""" - -CUSTOMIZATIONS = """ -""" - -CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/openssl/__init__.py b/cryptography/hazmat/bindings/openssl/__init__.py deleted file mode 100644 index 2f420574..00000000 --- a/cryptography/hazmat/bindings/openssl/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function diff --git a/cryptography/hazmat/bindings/openssl/aes.py b/cryptography/hazmat/bindings/openssl/aes.py deleted file mode 100644 index e4071523..00000000 --- a/cryptography/hazmat/bindings/openssl/aes.py +++ /dev/null @@ -1,70 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -TYPES = """ -static const int Cryptography_HAS_AES_WRAP; - -struct aes_key_st { - ...; -}; -typedef struct aes_key_st AES_KEY; -""" - -FUNCTIONS = """ -int AES_set_encrypt_key(const unsigned char *, const int, AES_KEY *); -int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *); -""" - -MACROS = """ -/* these can be moved back to FUNCTIONS once we drop support for 0.9.8h. - This should be when we drop RHEL/CentOS 5, which is on 0.9.8e. */ -int AES_wrap_key(AES_KEY *, const unsigned char *, unsigned char *, - const unsigned char *, unsigned int); -int AES_unwrap_key(AES_KEY *, const unsigned char *, unsigned char *, - const unsigned char *, unsigned int); - -/* The ctr128_encrypt function is only useful in 0.9.8. You should use EVP for - this in 1.0.0+. It is defined in macros because the function signature - changed after 0.9.8 */ -void AES_ctr128_encrypt(const unsigned char *, unsigned char *, - const size_t, const AES_KEY *, - unsigned char[], unsigned char[], unsigned int *); - -""" - -CUSTOMIZATIONS = """ -/* OpenSSL 0.9.8h+ */ -#if OPENSSL_VERSION_NUMBER >= 0x0090808fL -static const long Cryptography_HAS_AES_WRAP = 1; -#else -static const long Cryptography_HAS_AES_WRAP = 0; -int (*AES_wrap_key)(AES_KEY *, const unsigned char *, unsigned char *, - const unsigned char *, unsigned int) = NULL; -int (*AES_unwrap_key)(AES_KEY *, const unsigned char *, unsigned char *, - const unsigned char *, unsigned int) = NULL; -#endif - -""" - -CONDITIONAL_NAMES = { - "Cryptography_HAS_AES_WRAP": [ - "AES_wrap_key", - "AES_unwrap_key", - ], -} diff --git a/cryptography/hazmat/bindings/openssl/asn1.py b/cryptography/hazmat/bindings/openssl/asn1.py deleted file mode 100644 index 2edfd2d8..00000000 --- a/cryptography/hazmat/bindings/openssl/asn1.py +++ /dev/null @@ -1,152 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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: - * - * I think you want to declare your value too large (e.g. long) - * that way you'll never pass garbage - */ -typedef intptr_t time_t; - -typedef int ASN1_BOOLEAN; -typedef ... ASN1_INTEGER; - -struct asn1_string_st { - int length; - int type; - unsigned char *data; - long flags; -}; - -typedef struct asn1_string_st ASN1_OCTET_STRING; -typedef struct asn1_string_st ASN1_IA5STRING; -typedef ... ASN1_OBJECT; -typedef ... ASN1_STRING; -typedef ... ASN1_TYPE; -typedef ... ASN1_GENERALIZEDTIME; -typedef ... ASN1_ENUMERATED; -typedef ... ASN1_ITEM; -typedef ... ASN1_VALUE; - -typedef struct { - ...; -} ASN1_TIME; -typedef ... ASN1_ITEM_EXP; - -typedef ... ASN1_UTCTIME; - -static const int V_ASN1_GENERALIZEDTIME; - -static const int MBSTRING_UTF8; -""" - -FUNCTIONS = """ -ASN1_OBJECT *ASN1_OBJECT_new(void); -void ASN1_OBJECT_free(ASN1_OBJECT *); - -/* ASN1 OBJECT IDENTIFIER */ -ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **, const unsigned char **, long); -int i2d_ASN1_OBJECT(ASN1_OBJECT *, unsigned char **); - -/* ASN1 STRING */ -ASN1_STRING *ASN1_STRING_new(void); -ASN1_STRING *ASN1_STRING_type_new(int); -void ASN1_STRING_free(ASN1_STRING *); -unsigned char *ASN1_STRING_data(ASN1_STRING *); -int ASN1_STRING_set(ASN1_STRING *, const void *, int); -int ASN1_STRING_type(ASN1_STRING *); -int ASN1_STRING_to_UTF8(unsigned char **, ASN1_STRING *); - -/* ASN1 OCTET STRING */ -ASN1_OCTET_STRING *ASN1_OCTET_STRING_new(void); -void ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *); -int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *, const unsigned char *, int); - -/* ASN1 INTEGER */ -ASN1_INTEGER *ASN1_INTEGER_new(void); -void ASN1_INTEGER_free(ASN1_INTEGER *); -int ASN1_INTEGER_set(ASN1_INTEGER *, long); -int i2a_ASN1_INTEGER(BIO *, ASN1_INTEGER *); - -/* ASN1 TIME */ -ASN1_TIME *ASN1_TIME_new(void); -void ASN1_TIME_free(ASN1_TIME *); -ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *, - ASN1_GENERALIZEDTIME **); - -/* ASN1 UTCTIME */ -int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *, time_t); - -/* ASN1 GENERALIZEDTIME */ -int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *, const char *); -void ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *); - -/* ASN1 ENUMERATED */ -ASN1_ENUMERATED *ASN1_ENUMERATED_new(void); -void ASN1_ENUMERATED_free(ASN1_ENUMERATED *); -int ASN1_ENUMERATED_set(ASN1_ENUMERATED *, long); - -ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **, const unsigned char **, long, - const ASN1_ITEM *); -""" - -MACROS = """ -ASN1_TIME *M_ASN1_TIME_dup(void *); -const ASN1_ITEM *ASN1_ITEM_ptr(ASN1_ITEM_EXP *); - -/* These aren't macros these arguments are all const X on openssl > 1.0.x */ - -int ASN1_STRING_length(ASN1_STRING *); -ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *); -int ASN1_STRING_cmp(ASN1_STRING *, ASN1_STRING *); - -ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *); -int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *, ASN1_OCTET_STRING *); - -ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *); -int ASN1_INTEGER_cmp(ASN1_INTEGER *, ASN1_INTEGER *); -long ASN1_INTEGER_get(ASN1_INTEGER *); - -BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *, BIGNUM *); -ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *, ASN1_INTEGER *); - -/* These isn't a macro the arg is const on openssl 1.0.2+ */ -int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *); - -/* Not a macro, const on openssl 1.0 */ -int ASN1_STRING_set_default_mask_asc(char *); -""" - -CUSTOMIZATIONS = """ -""" - -CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/openssl/bignum.py b/cryptography/hazmat/bindings/openssl/bignum.py deleted file mode 100644 index 1d944ee9..00000000 --- a/cryptography/hazmat/bindings/openssl/bignum.py +++ /dev/null @@ -1,114 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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: - * - * I think you want to declare your value too large (e.g. long) - * 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 = {} diff --git a/cryptography/hazmat/bindings/openssl/binding.py b/cryptography/hazmat/bindings/openssl/binding.py deleted file mode 100644 index ff9039cf..00000000 --- a/cryptography/hazmat/bindings/openssl/binding.py +++ /dev/null @@ -1,176 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import os -import sys -import threading - -from cryptography.hazmat.bindings.utils import ( - build_ffi_for_binding, load_library_for_binding, -) - - -_OSX_PRE_INCLUDE = """ -#ifdef __APPLE__ -#include -#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 -""" - - -def _get_libraries(platform): - # OpenSSL goes by a different library name on different operating systems. - if platform != "win32": - # In some circumstances, the order in which these libs are - # specified on the linker command-line is significant; - # libssl must come before libcrypto - # (http://marc.info/?l=openssl-users&m=135361825921871) - return ["ssl", "crypto"] - else: - link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static") - return _get_windows_libraries(link_type) - - -def _get_windows_libraries(link_type): - if link_type == "dynamic": - return ["libeay32", "ssleay32", "advapi32"] - elif link_type == "static" or link_type == "": - return ["libeay32mt", "ssleay32mt", "advapi32", - "crypt32", "gdi32", "user32", "ws2_32"] - else: - raise ValueError( - "PYCA_WINDOWS_LINK_TYPE must be 'static' or 'dynamic'" - ) - - -class Binding(object): - """ - OpenSSL API wrapper. - """ - _module_prefix = "cryptography.hazmat.bindings.openssl." - _modules = [ - "aes", - "asn1", - "bignum", - "bio", - "cmac", - "cms", - "conf", - "crypto", - "dh", - "dsa", - "ec", - "ecdh", - "ecdsa", - "engine", - "err", - "evp", - "hmac", - "nid", - "objects", - "opensslv", - "osrandom_engine", - "pem", - "pkcs7", - "pkcs12", - "rand", - "rsa", - "ssl", - "x509", - "x509name", - "x509v3", - "x509_vfy" - ] - - _locks = None - _lock_cb_handle = None - _lock_init_lock = threading.Lock() - - ffi = build_ffi_for_binding( - module_prefix=_module_prefix, - modules=_modules, - pre_include=_OSX_PRE_INCLUDE, - post_include=_OSX_POST_INCLUDE, - libraries=_get_libraries(sys.platform) - ) - lib = None - - def __init__(self): - self._ensure_ffi_initialized() - - @classmethod - def _ensure_ffi_initialized(cls): - if cls.lib is not None: - return - - cls.lib = load_library_for_binding( - cls.ffi, - cls._module_prefix, - cls._modules, - ) - - res = cls.lib.Cryptography_add_osrandom_engine() - assert res != 0 - - @classmethod - def init_static_locks(cls): - with cls._lock_init_lock: - cls._ensure_ffi_initialized() - - if not cls._lock_cb_handle: - cls._lock_cb_handle = cls.ffi.callback( - "void(int, int, const char *, int)", - cls._lock_cb - ) - - # Use Python's implementation if available, importing _ssl triggers - # the setup for this. - __import__("_ssl") - - if cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL: - return - - # If nothing else has setup a locking callback already, we set up - # our own - num_locks = cls.lib.CRYPTO_num_locks() - cls._locks = [threading.Lock() for n in range(num_locks)] - - cls.lib.CRYPTO_set_locking_callback(cls._lock_cb_handle) - - @classmethod - def _lock_cb(cls, mode, n, file, line): - lock = cls._locks[n] - - if mode & cls.lib.CRYPTO_LOCK: - lock.acquire() - elif mode & cls.lib.CRYPTO_UNLOCK: - lock.release() - else: - raise RuntimeError( - "Unknown lock mode {0}: lock={1}, file={2}, line={3}.".format( - mode, n, file, line - ) - ) diff --git a/cryptography/hazmat/bindings/openssl/bio.py b/cryptography/hazmat/bindings/openssl/bio.py deleted file mode 100644 index cfe6034f..00000000 --- a/cryptography/hazmat/bindings/openssl/bio.py +++ /dev/null @@ -1,181 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/openssl/cmac.py b/cryptography/hazmat/bindings/openssl/cmac.py deleted file mode 100644 index c8bcc824..00000000 --- a/cryptography/hazmat/bindings/openssl/cmac.py +++ /dev/null @@ -1,65 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#if OPENSSL_VERSION_NUMBER >= 0x10001000L -#include -#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", - ], -} diff --git a/cryptography/hazmat/bindings/openssl/cms.py b/cryptography/hazmat/bindings/openssl/cms.py deleted file mode 100644 index cbf4b283..00000000 --- a/cryptography/hazmat/bindings/openssl/cms.py +++ /dev/null @@ -1,100 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#if !defined(OPENSSL_NO_CMS) && OPENSSL_VERSION_NUMBER >= 0x0090808fL -/* The next define should really be in the OpenSSL header, but it is missing. - Failing to include this on Windows causes compilation failures. */ -#if defined(OPENSSL_SYS_WINDOWS) -#include -#endif -#include -#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", - ] -} diff --git a/cryptography/hazmat/bindings/openssl/conf.py b/cryptography/hazmat/bindings/openssl/conf.py deleted file mode 100644 index 001a0707..00000000 --- a/cryptography/hazmat/bindings/openssl/conf.py +++ /dev/null @@ -1,35 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -TYPES = """ -typedef ... CONF; -""" - -FUNCTIONS = """ -void OPENSSL_config(const char *); -void OPENSSL_no_config(void); -""" - -MACROS = """ -""" - -CUSTOMIZATIONS = """ -""" - -CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/openssl/crypto.py b/cryptography/hazmat/bindings/openssl/crypto.py deleted file mode 100644 index 99e1a61d..00000000 --- a/cryptography/hazmat/bindings/openssl/crypto.py +++ /dev/null @@ -1,67 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/openssl/dh.py b/cryptography/hazmat/bindings/openssl/dh.py deleted file mode 100644 index e2e8976e..00000000 --- a/cryptography/hazmat/bindings/openssl/dh.py +++ /dev/null @@ -1,57 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/openssl/dsa.py b/cryptography/hazmat/bindings/openssl/dsa.py deleted file mode 100644 index c9aa8882..00000000 --- a/cryptography/hazmat/bindings/openssl/dsa.py +++ /dev/null @@ -1,65 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -TYPES = """ -typedef struct dsa_st { - /* Prime number (public) */ - BIGNUM *p; - /* Subprime (160-bit, q | p-1, public) */ - BIGNUM *q; - /* Generator of subgroup (public) */ - BIGNUM *g; - /* Private key x */ - BIGNUM *priv_key; - /* Public key y = g^x */ - BIGNUM *pub_key; - ...; -} DSA; -typedef struct { - BIGNUM *r; - BIGNUM *s; -} DSA_SIG; -""" - -FUNCTIONS = """ -DSA *DSA_generate_parameters(int, unsigned char *, int, int *, unsigned long *, - void (*)(int, int, void *), void *); -int DSA_generate_key(DSA *); -DSA *DSA_new(void); -void DSA_free(DSA *); -DSA_SIG *DSA_SIG_new(void); -void DSA_SIG_free(DSA_SIG *); -int i2d_DSA_SIG(const DSA_SIG *, unsigned char **); -DSA_SIG *d2i_DSA_SIG(DSA_SIG **, const unsigned char **, long); -int DSA_size(const DSA *); -int DSA_sign(int, const unsigned char *, int, unsigned char *, unsigned int *, - DSA *); -int DSA_verify(int, const unsigned char *, int, const unsigned char *, int, - DSA *); -""" - -MACROS = """ -int DSA_generate_parameters_ex(DSA *, int, unsigned char *, int, - int *, unsigned long *, BN_GENCB *); -""" - -CUSTOMIZATIONS = """ -""" - -CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/openssl/ec.py b/cryptography/hazmat/bindings/openssl/ec.py deleted file mode 100644 index 26fc8ff0..00000000 --- a/cryptography/hazmat/bindings/openssl/ec.py +++ /dev/null @@ -1,490 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#ifndef OPENSSL_NO_EC -#include -#endif - -#include -""" - -TYPES = """ -static const int Cryptography_HAS_EC; -static const int Cryptography_HAS_EC_1_0_1; -static const int Cryptography_HAS_EC_NISTP_64_GCC_128; -static const int Cryptography_HAS_EC2M; - -static const int OPENSSL_EC_NAMED_CURVE; - -typedef ... EC_KEY; -typedef ... EC_GROUP; -typedef ... EC_POINT; -typedef ... EC_METHOD; -typedef struct { - int nid; - const char *comment; -} EC_builtin_curve; -typedef enum { ... } point_conversion_form_t; -""" - -FUNCTIONS = """ -""" - -MACROS = """ -EC_GROUP *EC_GROUP_new(const EC_METHOD *); -void EC_GROUP_free(EC_GROUP *); -void EC_GROUP_clear_free(EC_GROUP *); - -EC_GROUP *EC_GROUP_new_curve_GFp( - const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); -EC_GROUP *EC_GROUP_new_curve_GF2m( - const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); -EC_GROUP *EC_GROUP_new_by_curve_name(int); - -int EC_GROUP_set_curve_GFp( - EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); -int EC_GROUP_get_curve_GFp( - const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *); -int EC_GROUP_set_curve_GF2m( - EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); -int EC_GROUP_get_curve_GF2m( - const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *); - -int EC_GROUP_get_degree(const EC_GROUP *); - -const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); -const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *); -int EC_GROUP_get_curve_name(const EC_GROUP *); - -size_t EC_get_builtin_curves(EC_builtin_curve *, size_t); - -void EC_KEY_free(EC_KEY *); - -int EC_KEY_get_flags(const EC_KEY *); -void EC_KEY_set_flags(EC_KEY *, int); -void EC_KEY_clear_flags(EC_KEY *, int); -EC_KEY *EC_KEY_new_by_curve_name(int); -EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *); -EC_KEY *EC_KEY_dup(const EC_KEY *); -int EC_KEY_up_ref(EC_KEY *); -const EC_GROUP *EC_KEY_get0_group(const EC_KEY *); -int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *, BN_CTX *); -int EC_KEY_set_group(EC_KEY *, const EC_GROUP *); -const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *); -int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *); -const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *); -int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *); -unsigned int EC_KEY_get_enc_flags(const EC_KEY *); -void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int); -point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *); -void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t); -void *EC_KEY_get_key_method_data( - EC_KEY *, - void *(*)(void *), - void (*)(void *), - void (*)(void *) -); -void EC_KEY_insert_key_method_data( - EC_KEY *, - void *, - void *(*)(void *), - void (*)(void *), - void (*)(void *) -); -void EC_KEY_set_asn1_flag(EC_KEY *, int); -int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *); -int EC_KEY_generate_key(EC_KEY *); -int EC_KEY_check_key(const EC_KEY *); -int EC_KEY_set_public_key_affine_coordinates(EC_KEY *, BIGNUM *, BIGNUM *); - -EC_POINT *EC_POINT_new(const EC_GROUP *); -void EC_POINT_free(EC_POINT *); -void EC_POINT_clear_free(EC_POINT *); -int EC_POINT_copy(EC_POINT *, const EC_POINT *); -EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *); -const EC_METHOD *EC_POINT_method_of(const EC_POINT *); - -int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *); - -int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *, - const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); - -int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *, - const EC_POINT *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *); - -int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *, - const BIGNUM *, const BIGNUM *, BN_CTX *); - -int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, - const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *); - -int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *, - const BIGNUM *, int, BN_CTX *); - -int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *, - const BIGNUM *, const BIGNUM *, BN_CTX *); - -int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, - const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *); - -int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *, - const BIGNUM *, int, BN_CTX *); - -size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t, - unsigned char *, size_t, BN_CTX *); - -int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *, - const unsigned char *, size_t, BN_CTX *); - -BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, BIGNUM *, BN_CTX *); - -EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, - EC_POINT *, BN_CTX *); - -char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, BN_CTX *); - -EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, - EC_POINT *, BN_CTX *); - -int EC_POINT_add(const EC_GROUP *, EC_POINT *, const EC_POINT *, - const EC_POINT *, BN_CTX *); - -int EC_POINT_dbl(const EC_GROUP *, EC_POINT *, const EC_POINT *, BN_CTX *); -int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); -int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *); -int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); - -int EC_POINT_cmp( - const EC_GROUP *, const EC_POINT *, const EC_POINT *, BN_CTX *); - -int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); -int EC_POINTs_make_affine(const EC_GROUP *, size_t, EC_POINT *[], BN_CTX *); - -int EC_POINTs_mul( - const EC_GROUP *, EC_POINT *, const BIGNUM *, - size_t, const EC_POINT *[], const BIGNUM *[], BN_CTX *); - -int EC_POINT_mul(const EC_GROUP *, EC_POINT *, const BIGNUM *, - const EC_POINT *, const BIGNUM *, BN_CTX *); - -int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *); -int EC_GROUP_have_precompute_mult(const EC_GROUP *); - -const EC_METHOD *EC_GFp_simple_method(); -const EC_METHOD *EC_GFp_mont_method(); -const EC_METHOD *EC_GFp_nist_method(); - -const EC_METHOD *EC_GFp_nistp224_method(); -const EC_METHOD *EC_GFp_nistp256_method(); -const EC_METHOD *EC_GFp_nistp521_method(); - -const EC_METHOD *EC_GF2m_simple_method(); - -int EC_METHOD_get_field_type(const EC_METHOD *); -""" - -CUSTOMIZATIONS = """ -#ifdef OPENSSL_NO_EC -static const long Cryptography_HAS_EC = 0; - -typedef void EC_KEY; -typedef void EC_GROUP; -typedef void EC_POINT; -typedef void EC_METHOD; -typedef struct { - int nid; - const char *comment; -} EC_builtin_curve; -typedef long point_conversion_form_t; - -static const int OPENSSL_EC_NAMED_CURVE = 0; - -void (*EC_KEY_free)(EC_KEY *) = NULL; -size_t (*EC_get_builtin_curves)(EC_builtin_curve *, size_t) = NULL; -EC_KEY *(*EC_KEY_new_by_curve_name)(int) = NULL; -EC_KEY *(*EC_KEY_copy)(EC_KEY *, const EC_KEY *) = NULL; -EC_KEY *(*EC_KEY_dup)(const EC_KEY *) = NULL; -int (*EC_KEY_up_ref)(EC_KEY *) = NULL; -const EC_GROUP *(*EC_KEY_get0_group)(const EC_KEY *) = NULL; -int (*EC_GROUP_get_order)(const EC_GROUP *, BIGNUM *, BN_CTX *) = NULL; -int (*EC_KEY_set_group)(EC_KEY *, const EC_GROUP *) = NULL; -const BIGNUM *(*EC_KEY_get0_private_key)(const EC_KEY *) = NULL; -int (*EC_KEY_set_private_key)(EC_KEY *, const BIGNUM *) = NULL; -const EC_POINT *(*EC_KEY_get0_public_key)(const EC_KEY *) = NULL; -int (*EC_KEY_set_public_key)(EC_KEY *, const EC_POINT *) = NULL; -unsigned int (*EC_KEY_get_enc_flags)(const EC_KEY *) = NULL; -void (*EC_KEY_set_enc_flags)(EC_KEY *eckey, unsigned int) = NULL; -point_conversion_form_t (*EC_KEY_get_conv_form)(const EC_KEY *) = NULL; -void (*EC_KEY_set_conv_form)(EC_KEY *, point_conversion_form_t) = NULL; -void *(*EC_KEY_get_key_method_data)( - EC_KEY *, void *(*)(void *), void (*)(void *), void (*)(void *)) = NULL; -void (*EC_KEY_insert_key_method_data)( - EC_KEY *, void *, - void *(*)(void *), void (*)(void *), void (*)(void *)) = NULL; -void (*EC_KEY_set_asn1_flag)(EC_KEY *, int) = NULL; -int (*EC_KEY_precompute_mult)(EC_KEY *, BN_CTX *) = NULL; -int (*EC_KEY_generate_key)(EC_KEY *) = NULL; -int (*EC_KEY_check_key)(const EC_KEY *) = NULL; - -EC_GROUP *(*EC_GROUP_new)(const EC_METHOD *); -void (*EC_GROUP_free)(EC_GROUP *); -void (*EC_GROUP_clear_free)(EC_GROUP *); - -EC_GROUP *(*EC_GROUP_new_curve_GFp)( - const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); - -EC_GROUP *(*EC_GROUP_new_by_curve_name)(int); - -int (*EC_GROUP_set_curve_GFp)( - EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); - -int (*EC_GROUP_get_curve_GFp)( - const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *); - -int (*EC_GROUP_get_degree)(const EC_GROUP *) = NULL; - -const EC_METHOD *(*EC_GROUP_method_of)(const EC_GROUP *) = NULL; -const EC_POINT *(*EC_GROUP_get0_generator)(const EC_GROUP *) = NULL; -int (*EC_GROUP_get_curve_name)(const EC_GROUP *) = NULL; - -EC_POINT *(*EC_POINT_new)(const EC_GROUP *) = NULL; -void (*EC_POINT_free)(EC_POINT *) = NULL; -void (*EC_POINT_clear_free)(EC_POINT *) = NULL; -int (*EC_POINT_copy)(EC_POINT *, const EC_POINT *) = NULL; -EC_POINT *(*EC_POINT_dup)(const EC_POINT *, const EC_GROUP *) = NULL; -const EC_METHOD *(*EC_POINT_method_of)(const EC_POINT *) = NULL; -int (*EC_POINT_set_to_infinity)(const EC_GROUP *, EC_POINT *) = NULL; -int (*EC_POINT_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *, - const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL; - -int (*EC_POINT_get_Jprojective_coordinates_GFp)(const EC_GROUP *, - const EC_POINT *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL; - -int (*EC_POINT_set_affine_coordinates_GFp)(const EC_GROUP *, EC_POINT *, - const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL; - -int (*EC_POINT_get_affine_coordinates_GFp)(const EC_GROUP *, - const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL; - -int (*EC_POINT_set_compressed_coordinates_GFp)(const EC_GROUP *, EC_POINT *, - const BIGNUM *, int, BN_CTX *) = NULL; - -size_t (*EC_POINT_point2oct)(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t, - unsigned char *, size_t, BN_CTX *) = NULL; - -int (*EC_POINT_oct2point)(const EC_GROUP *, EC_POINT *, - const unsigned char *, size_t, BN_CTX *) = NULL; - -BIGNUM *(*EC_POINT_point2bn)(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, BIGNUM *, BN_CTX *) = NULL; - -EC_POINT *(*EC_POINT_bn2point)(const EC_GROUP *, const BIGNUM *, - EC_POINT *, BN_CTX *) = NULL; - -char *(*EC_POINT_point2hex)(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, BN_CTX *) = NULL; - -EC_POINT *(*EC_POINT_hex2point)(const EC_GROUP *, const char *, - EC_POINT *, BN_CTX *) = NULL; - -int (*EC_POINT_add)(const EC_GROUP *, EC_POINT *, const EC_POINT *, - const EC_POINT *, BN_CTX *) = NULL; - -int (*EC_POINT_dbl)(const EC_GROUP *, EC_POINT *, const EC_POINT *, - BN_CTX *) = NULL; - -int (*EC_POINT_invert)(const EC_GROUP *, EC_POINT *, BN_CTX *) = NULL; -int (*EC_POINT_is_at_infinity)(const EC_GROUP *, const EC_POINT *) = NULL; - -int (*EC_POINT_is_on_curve)(const EC_GROUP *, const EC_POINT *, - BN_CTX *) = NULL; - -int (*EC_POINT_cmp)( - const EC_GROUP *, const EC_POINT *, const EC_POINT *, BN_CTX *) = NULL; - -int (*EC_POINT_make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *) = NULL; - -int (*EC_POINTs_make_affine)(const EC_GROUP *, size_t, EC_POINT *[], - BN_CTX *) = NULL; - -int (*EC_POINTs_mul)( - const EC_GROUP *, EC_POINT *, const BIGNUM *, - size_t, const EC_POINT *[], const BIGNUM *[], BN_CTX *) = NULL; - -int (*EC_POINT_mul)(const EC_GROUP *, EC_POINT *, const BIGNUM *, - const EC_POINT *, const BIGNUM *, BN_CTX *) = NULL; - -int (*EC_GROUP_precompute_mult)(EC_GROUP *, BN_CTX *) = NULL; -int (*EC_GROUP_have_precompute_mult)(const EC_GROUP *) = NULL; - -const EC_METHOD *(*EC_GFp_simple_method)() = NULL; -const EC_METHOD *(*EC_GFp_mont_method)() = NULL; -const EC_METHOD *(*EC_GFp_nist_method)() = NULL; - -int (*EC_METHOD_get_field_type)(const EC_METHOD *) = NULL; - -#else -static const long Cryptography_HAS_EC = 1; -#endif - -#if defined(OPENSSL_NO_EC) || OPENSSL_VERSION_NUMBER < 0x1000100f -static const long Cryptography_HAS_EC_1_0_1 = 0; - -int (*EC_KEY_get_flags)(const EC_KEY *) = NULL; -void (*EC_KEY_set_flags)(EC_KEY *, int) = NULL; -void (*EC_KEY_clear_flags)(EC_KEY *, int) = NULL; - -int (*EC_KEY_set_public_key_affine_coordinates)( - EC_KEY *, BIGNUM *, BIGNUM *) = NULL; -#else -static const long Cryptography_HAS_EC_1_0_1 = 1; -#endif - - -#if defined(OPENSSL_NO_EC) || OPENSSL_VERSION_NUMBER < 0x1000100f || \ - defined(OPENSSL_NO_EC_NISTP_64_GCC_128) -static const long Cryptography_HAS_EC_NISTP_64_GCC_128 = 0; - -const EC_METHOD *(*EC_GFp_nistp224_method)(void) = NULL; -const EC_METHOD *(*EC_GFp_nistp256_method)(void) = NULL; -const EC_METHOD *(*EC_GFp_nistp521_method)(void) = NULL; -#else -static const long Cryptography_HAS_EC_NISTP_64_GCC_128 = 1; -#endif - -#if defined(OPENSSL_NO_EC) || defined(OPENSSL_NO_EC2M) -static const long Cryptography_HAS_EC2M = 0; - -const EC_METHOD *(*EC_GF2m_simple_method)() = NULL; - -int (*EC_POINT_set_affine_coordinates_GF2m)(const EC_GROUP *, EC_POINT *, - const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL; - -int (*EC_POINT_get_affine_coordinates_GF2m)(const EC_GROUP *, - const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL; - -int (*EC_POINT_set_compressed_coordinates_GF2m)(const EC_GROUP *, EC_POINT *, - const BIGNUM *, int, BN_CTX *) = NULL; - -int (*EC_GROUP_set_curve_GF2m)( - EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); - -int (*EC_GROUP_get_curve_GF2m)( - const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *); - -EC_GROUP *(*EC_GROUP_new_curve_GF2m)( - const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); -#else -static const long Cryptography_HAS_EC2M = 1; -#endif -""" - -CONDITIONAL_NAMES = { - "Cryptography_HAS_EC": [ - "OPENSSL_EC_NAMED_CURVE", - "EC_GROUP_new", - "EC_GROUP_free", - "EC_GROUP_clear_free", - "EC_GROUP_new_curve_GFp", - "EC_GROUP_new_by_curve_name", - "EC_GROUP_set_curve_GFp", - "EC_GROUP_get_curve_GFp", - "EC_GROUP_method_of", - "EC_GROUP_get0_generator", - "EC_GROUP_get_curve_name", - "EC_GROUP_get_degree", - "EC_KEY_free", - "EC_get_builtin_curves", - "EC_KEY_new_by_curve_name", - "EC_KEY_copy", - "EC_KEY_dup", - "EC_KEY_up_ref", - "EC_KEY_set_group", - "EC_KEY_get0_private_key", - "EC_KEY_set_private_key", - "EC_KEY_set_public_key", - "EC_KEY_get_enc_flags", - "EC_KEY_set_enc_flags", - "EC_KEY_set_conv_form", - "EC_KEY_get_key_method_data", - "EC_KEY_insert_key_method_data", - "EC_KEY_set_asn1_flag", - "EC_KEY_precompute_mult", - "EC_KEY_generate_key", - "EC_KEY_check_key", - "EC_POINT_new", - "EC_POINT_free", - "EC_POINT_clear_free", - "EC_POINT_copy", - "EC_POINT_dup", - "EC_POINT_method_of", - "EC_POINT_set_to_infinity", - "EC_POINT_set_Jprojective_coordinates_GFp", - "EC_POINT_get_Jprojective_coordinates_GFp", - "EC_POINT_set_affine_coordinates_GFp", - "EC_POINT_get_affine_coordinates_GFp", - "EC_POINT_set_compressed_coordinates_GFp", - "EC_POINT_point2oct", - "EC_POINT_oct2point", - "EC_POINT_point2bn", - "EC_POINT_bn2point", - "EC_POINT_point2hex", - "EC_POINT_hex2point", - "EC_POINT_add", - "EC_POINT_dbl", - "EC_POINT_invert", - "EC_POINT_is_at_infinity", - "EC_POINT_is_on_curve", - "EC_POINT_cmp", - "EC_POINT_make_affine", - "EC_POINTs_make_affine", - "EC_POINTs_mul", - "EC_POINT_mul", - "EC_GROUP_precompute_mult", - "EC_GROUP_have_precompute_mult", - "EC_GFp_simple_method", - "EC_GFp_mont_method", - "EC_GFp_nist_method", - "EC_METHOD_get_field_type", - ], - - "Cryptography_HAS_EC_1_0_1": [ - "EC_KEY_get_flags", - "EC_KEY_set_flags", - "EC_KEY_clear_flags", - "EC_KEY_set_public_key_affine_coordinates", - ], - - "Cryptography_HAS_EC_NISTP_64_GCC_128": [ - "EC_GFp_nistp224_method", - "EC_GFp_nistp256_method", - "EC_GFp_nistp521_method", - ], - - "Cryptography_HAS_EC2M": [ - "EC_GF2m_simple_method", - "EC_POINT_set_affine_coordinates_GF2m", - "EC_POINT_get_affine_coordinates_GF2m", - "EC_POINT_set_compressed_coordinates_GF2m", - "EC_GROUP_set_curve_GF2m", - "EC_GROUP_get_curve_GF2m", - "EC_GROUP_new_curve_GF2m", - ], -} diff --git a/cryptography/hazmat/bindings/openssl/ecdh.py b/cryptography/hazmat/bindings/openssl/ecdh.py deleted file mode 100644 index 960d46fb..00000000 --- a/cryptography/hazmat/bindings/openssl/ecdh.py +++ /dev/null @@ -1,68 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#ifndef OPENSSL_NO_ECDH -#include -#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", - ], -} diff --git a/cryptography/hazmat/bindings/openssl/ecdsa.py b/cryptography/hazmat/bindings/openssl/ecdsa.py deleted file mode 100644 index bfa67206..00000000 --- a/cryptography/hazmat/bindings/openssl/ecdsa.py +++ /dev/null @@ -1,130 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#ifndef OPENSSL_NO_ECDSA -#include -#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", - ], -} diff --git a/cryptography/hazmat/bindings/openssl/engine.py b/cryptography/hazmat/bindings/openssl/engine.py deleted file mode 100644 index 364232e0..00000000 --- a/cryptography/hazmat/bindings/openssl/engine.py +++ /dev/null @@ -1,165 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/openssl/err.py b/cryptography/hazmat/bindings/openssl/err.py deleted file mode 100644 index 4e44a2eb..00000000 --- a/cryptography/hazmat/bindings/openssl/err.py +++ /dev/null @@ -1,365 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -TYPES = """ -static const int Cryptography_HAS_REMOVE_THREAD_STATE; -static const int Cryptography_HAS_098H_ERROR_CODES; -static const int Cryptography_HAS_098C_CAMELLIA_CODES; -static const int Cryptography_HAS_EC_CODES; -static const int Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR; - -struct ERR_string_data_st { - unsigned long error; - const char *string; -}; -typedef struct ERR_string_data_st ERR_STRING_DATA; - -static const int ERR_LIB_EVP; -static const int ERR_LIB_EC; -static const int ERR_LIB_PEM; -static const int ERR_LIB_ASN1; -static const int ERR_LIB_RSA; -static const int ERR_LIB_PKCS12; - -static const int ASN1_F_ASN1_ENUMERATED_TO_BN; -static const int ASN1_F_ASN1_EX_C2I; -static const int ASN1_F_ASN1_FIND_END; -static const int ASN1_F_ASN1_GENERALIZEDTIME_SET; -static const int ASN1_F_ASN1_GENERATE_V3; -static const int ASN1_F_ASN1_GET_OBJECT; -static const int ASN1_F_ASN1_ITEM_I2D_FP; -static const int ASN1_F_ASN1_ITEM_PACK; -static const int ASN1_F_ASN1_ITEM_SIGN; -static const int ASN1_F_ASN1_ITEM_UNPACK; -static const int ASN1_F_ASN1_ITEM_VERIFY; -static const int ASN1_F_ASN1_MBSTRING_NCOPY; -static const int ASN1_F_ASN1_TEMPLATE_EX_D2I; -static const int ASN1_F_ASN1_TEMPLATE_NEW; -static const int ASN1_F_ASN1_TEMPLATE_NOEXP_D2I; -static const int ASN1_F_ASN1_TIME_SET; -static const int ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING; -static const int ASN1_F_ASN1_TYPE_GET_OCTETSTRING; -static const int ASN1_F_ASN1_UNPACK_STRING; -static const int ASN1_F_ASN1_UTCTIME_SET; -static const int ASN1_F_ASN1_VERIFY; -static const int ASN1_F_BITSTR_CB; -static const int ASN1_F_BN_TO_ASN1_ENUMERATED; -static const int ASN1_F_BN_TO_ASN1_INTEGER; -static const int ASN1_F_D2I_ASN1_TYPE_BYTES; -static const int ASN1_F_D2I_ASN1_UINTEGER; -static const int ASN1_F_D2I_ASN1_UTCTIME; -static const int ASN1_F_D2I_NETSCAPE_RSA; -static const int ASN1_F_D2I_NETSCAPE_RSA_2; -static const int ASN1_F_D2I_PRIVATEKEY; -static const int ASN1_F_D2I_X509; -static const int ASN1_F_D2I_X509_CINF; -static const int ASN1_F_D2I_X509_PKEY; -static const int ASN1_F_I2D_ASN1_SET; -static const int ASN1_F_I2D_ASN1_TIME; -static const int ASN1_F_I2D_DSA_PUBKEY; -static const int ASN1_F_LONG_C2I; -static const int ASN1_F_OID_MODULE_INIT; -static const int ASN1_F_PARSE_TAGGING; -static const int ASN1_F_PKCS5_PBE_SET; -static const int ASN1_F_X509_CINF_NEW; - -static const int ASN1_R_BOOLEAN_IS_WRONG_LENGTH; -static const int ASN1_R_BUFFER_TOO_SMALL; -static const int ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER; -static const int ASN1_R_DATA_IS_WRONG; -static const int ASN1_R_DECODE_ERROR; -static const int ASN1_R_DECODING_ERROR; -static const int ASN1_R_DEPTH_EXCEEDED; -static const int ASN1_R_ENCODE_ERROR; -static const int ASN1_R_ERROR_GETTING_TIME; -static const int ASN1_R_ERROR_LOADING_SECTION; -static const int ASN1_R_MSTRING_WRONG_TAG; -static const int ASN1_R_NESTED_ASN1_STRING; -static const int ASN1_R_NO_MATCHING_CHOICE_TYPE; -static const int ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM; -static const int ASN1_R_UNKNOWN_OBJECT_TYPE; -static const int ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE; -static const int ASN1_R_UNKNOWN_TAG; -static const int ASN1_R_UNKOWN_FORMAT; -static const int ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE; -static const int ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM; -static const int ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE; -static const int ASN1_R_UNSUPPORTED_TYPE; -static const int ASN1_R_WRONG_TAG; -static const int ASN1_R_WRONG_TYPE; - -static const int EVP_F_AES_INIT_KEY; -static const int EVP_F_D2I_PKEY; -static const int EVP_F_DSA_PKEY2PKCS8; -static const int EVP_F_DSAPKEY2PKCS8; -static const int EVP_F_ECDSA_PKEY2PKCS8; -static const int EVP_F_ECKEY_PKEY2PKCS8; -static const int EVP_F_EVP_CIPHER_CTX_CTRL; -static const int EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH; -static const int EVP_F_EVP_CIPHERINIT_EX; -static const int EVP_F_EVP_DECRYPTFINAL_EX; -static const int EVP_F_EVP_DIGESTINIT_EX; -static const int EVP_F_EVP_ENCRYPTFINAL_EX; -static const int EVP_F_EVP_MD_CTX_COPY_EX; -static const int EVP_F_EVP_OPENINIT; -static const int EVP_F_EVP_PBE_ALG_ADD; -static const int EVP_F_EVP_PBE_CIPHERINIT; -static const int EVP_F_EVP_PKCS82PKEY; -static const int EVP_F_EVP_PKEY2PKCS8_BROKEN; -static const int EVP_F_EVP_PKEY_COPY_PARAMETERS; -static const int EVP_F_EVP_PKEY_DECRYPT; -static const int EVP_F_EVP_PKEY_ENCRYPT; -static const int EVP_F_EVP_PKEY_GET1_DH; -static const int EVP_F_EVP_PKEY_GET1_DSA; -static const int EVP_F_EVP_PKEY_GET1_ECDSA; -static const int EVP_F_EVP_PKEY_GET1_EC_KEY; -static const int EVP_F_EVP_PKEY_GET1_RSA; -static const int EVP_F_EVP_PKEY_NEW; -static const int EVP_F_EVP_RIJNDAEL; -static const int EVP_F_EVP_SIGNFINAL; -static const int EVP_F_EVP_VERIFYFINAL; -static const int EVP_F_PKCS5_PBE_KEYIVGEN; -static const int EVP_F_PKCS5_V2_PBE_KEYIVGEN; -static const int EVP_F_PKCS8_SET_BROKEN; -static const int EVP_F_RC2_MAGIC_TO_METH; -static const int EVP_F_RC5_CTRL; - -static const int EVP_R_AES_KEY_SETUP_FAILED; -static const int EVP_R_ASN1_LIB; -static const int EVP_R_BAD_BLOCK_LENGTH; -static const int EVP_R_BAD_DECRYPT; -static const int EVP_R_BAD_KEY_LENGTH; -static const int EVP_R_BN_DECODE_ERROR; -static const int EVP_R_BN_PUBKEY_ERROR; -static const int EVP_R_CIPHER_PARAMETER_ERROR; -static const int EVP_R_CTRL_NOT_IMPLEMENTED; -static const int EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED; -static const int EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH; -static const int EVP_R_DECODE_ERROR; -static const int EVP_R_DIFFERENT_KEY_TYPES; -static const int EVP_R_ENCODE_ERROR; -static const int EVP_R_INITIALIZATION_ERROR; -static const int EVP_R_INPUT_NOT_INITIALIZED; -static const int EVP_R_INVALID_KEY_LENGTH; -static const int EVP_R_IV_TOO_LARGE; -static const int EVP_R_KEYGEN_FAILURE; -static const int EVP_R_MISSING_PARAMETERS; -static const int EVP_R_NO_CIPHER_SET; -static const int EVP_R_NO_DIGEST_SET; -static const int EVP_R_NO_DSA_PARAMETERS; -static const int EVP_R_NO_SIGN_FUNCTION_CONFIGURED; -static const int EVP_R_NO_VERIFY_FUNCTION_CONFIGURED; -static const int EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE; -static const int EVP_R_PUBLIC_KEY_NOT_RSA; -static const int EVP_R_UNKNOWN_PBE_ALGORITHM; -static const int EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS; -static const int EVP_R_UNSUPPORTED_CIPHER; -static const int EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION; -static const int EVP_R_UNSUPPORTED_KEYLENGTH; -static const int EVP_R_UNSUPPORTED_SALT_TYPE; -static const int EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM; -static const int EVP_R_WRONG_FINAL_BLOCK_LENGTH; -static const int EVP_R_WRONG_PUBLIC_KEY_TYPE; - -static const int EC_F_EC_GROUP_NEW_BY_CURVE_NAME; - -static const int EC_R_UNKNOWN_GROUP; - -static const int PEM_F_D2I_PKCS8PRIVATEKEY_BIO; -static const int PEM_F_D2I_PKCS8PRIVATEKEY_FP; -static const int PEM_F_DO_PK8PKEY; -static const int PEM_F_DO_PK8PKEY_FP; -static const int PEM_F_LOAD_IV; -static const int PEM_F_PEM_ASN1_READ; -static const int PEM_F_PEM_ASN1_READ_BIO; -static const int PEM_F_PEM_ASN1_WRITE; -static const int PEM_F_PEM_ASN1_WRITE_BIO; -static const int PEM_F_PEM_DEF_CALLBACK; -static const int PEM_F_PEM_DO_HEADER; -static const int PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY; -static const int PEM_F_PEM_GET_EVP_CIPHER_INFO; -static const int PEM_F_PEM_PK8PKEY; -static const int PEM_F_PEM_READ; -static const int PEM_F_PEM_READ_BIO; -static const int PEM_F_PEM_READ_BIO_PRIVATEKEY; -static const int PEM_F_PEM_READ_PRIVATEKEY; -static const int PEM_F_PEM_SEALFINAL; -static const int PEM_F_PEM_SEALINIT; -static const int PEM_F_PEM_SIGNFINAL; -static const int PEM_F_PEM_WRITE; -static const int PEM_F_PEM_WRITE_BIO; -static const int PEM_F_PEM_X509_INFO_READ; -static const int PEM_F_PEM_X509_INFO_READ_BIO; -static const int PEM_F_PEM_X509_INFO_WRITE_BIO; - -static const int PEM_R_BAD_BASE64_DECODE; -static const int PEM_R_BAD_DECRYPT; -static const int PEM_R_BAD_END_LINE; -static const int PEM_R_BAD_IV_CHARS; -static const int PEM_R_BAD_PASSWORD_READ; -static const int PEM_R_ERROR_CONVERTING_PRIVATE_KEY; -static const int PEM_R_NO_START_LINE; -static const int PEM_R_NOT_DEK_INFO; -static const int PEM_R_NOT_ENCRYPTED; -static const int PEM_R_NOT_PROC_TYPE; -static const int PEM_R_PROBLEMS_GETTING_PASSWORD; -static const int PEM_R_PUBLIC_KEY_NO_RSA; -static const int PEM_R_READ_KEY; -static const int PEM_R_SHORT_HEADER; -static const int PEM_R_UNSUPPORTED_CIPHER; -static const int PEM_R_UNSUPPORTED_ENCRYPTION; - -static const int PKCS12_F_PKCS12_PBE_CRYPT; - -static const int PKCS12_R_PKCS12_CIPHERFINAL_ERROR; - -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; -static const int RSA_R_PKCS_DECODING_ERROR; -""" - -FUNCTIONS = """ -void ERR_load_crypto_strings(void); -void ERR_load_SSL_strings(void); -void ERR_free_strings(void); -char* ERR_error_string(unsigned long, char *); -void ERR_error_string_n(unsigned long, char *, size_t); -const char* ERR_lib_error_string(unsigned long); -const char* ERR_func_error_string(unsigned long); -const char* ERR_reason_error_string(unsigned long); -void ERR_print_errors(BIO *); -void ERR_print_errors_fp(FILE *); -unsigned long ERR_get_error(void); -unsigned long ERR_peek_error(void); -unsigned long ERR_peek_last_error(void); -unsigned long ERR_get_error_line(const char **, int *); -unsigned long ERR_peek_error_line(const char **, int *); -unsigned long ERR_peek_last_error_line(const char **, int *); -unsigned long ERR_get_error_line_data(const char **, int *, - const char **, int *); -unsigned long ERR_peek_error_line_data(const char **, - int *, const char **, int *); -unsigned long ERR_peek_last_error_line_data(const char **, - int *, const char **, int *); -void ERR_put_error(int, int, int, const char *, int); -void ERR_add_error_data(int, ...); -int ERR_get_next_error_library(void); -""" - -MACROS = """ -unsigned long ERR_PACK(int, int, int); -int ERR_GET_LIB(unsigned long); -int ERR_GET_FUNC(unsigned long); -int ERR_GET_REASON(unsigned long); -int ERR_FATAL_ERROR(unsigned long); -/* introduced in 1.0.0 so we have to handle this specially to continue - * supporting 0.9.8 - */ -void ERR_remove_thread_state(const CRYPTO_THREADID *); - -/* These were added in OpenSSL 0.9.8h. When we drop support for RHEL/CentOS 5 - we should be able to move these back to TYPES. */ -static const int ASN1_F_B64_READ_ASN1; -static const int ASN1_F_B64_WRITE_ASN1; -static const int ASN1_F_SMIME_READ_ASN1; -static const int ASN1_F_SMIME_TEXT; -static const int ASN1_R_NO_CONTENT_TYPE; -static const int ASN1_R_NO_MULTIPART_BODY_FAILURE; -static const int ASN1_R_NO_MULTIPART_BOUNDARY; -/* These were added in OpenSSL 0.9.8c. */ -static const int EVP_F_CAMELLIA_INIT_KEY; -static const int EVP_R_CAMELLIA_KEY_SETUP_FAILED; -""" - -CUSTOMIZATIONS = """ -#if OPENSSL_VERSION_NUMBER >= 0x10000000L -static const long Cryptography_HAS_REMOVE_THREAD_STATE = 1; -#else -static const long Cryptography_HAS_REMOVE_THREAD_STATE = 0; -typedef uint32_t CRYPTO_THREADID; -void (*ERR_remove_thread_state)(const CRYPTO_THREADID *) = NULL; -#endif - -/* OpenSSL 0.9.8h+ */ -#if OPENSSL_VERSION_NUMBER >= 0x0090808fL -static const long Cryptography_HAS_098H_ERROR_CODES = 1; -#else -static const long Cryptography_HAS_098H_ERROR_CODES = 0; -static const int ASN1_F_B64_READ_ASN1 = 0; -static const int ASN1_F_B64_WRITE_ASN1 = 0; -static const int ASN1_F_SMIME_READ_ASN1 = 0; -static const int ASN1_F_SMIME_TEXT = 0; -static const int ASN1_R_NO_CONTENT_TYPE = 0; -static const int ASN1_R_NO_MULTIPART_BODY_FAILURE = 0; -static const int ASN1_R_NO_MULTIPART_BOUNDARY = 0; -#endif - -/* OpenSSL 0.9.8c+ */ -#ifdef EVP_F_CAMELLIA_INIT_KEY -static const long Cryptography_HAS_098C_CAMELLIA_CODES = 1; -#else -static const long Cryptography_HAS_098C_CAMELLIA_CODES = 0; -static const int EVP_F_CAMELLIA_INIT_KEY = 0; -static const int EVP_R_CAMELLIA_KEY_SETUP_FAILED = 0; -#endif - -// OpenSSL without EC. e.g. RHEL -#ifndef OPENSSL_NO_EC -static const long Cryptography_HAS_EC_CODES = 1; -#else -static const long Cryptography_HAS_EC_CODES = 0; -static const int EC_R_UNKNOWN_GROUP = 0; -static const int EC_F_EC_GROUP_NEW_BY_CURVE_NAME = 0; -#endif - -#ifdef RSA_R_PKCS_DECODING_ERROR -static const long Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR = 1; -#else -static const long Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR = 0; -static const long RSA_R_PKCS_DECODING_ERROR = 0; -#endif -""" - -CONDITIONAL_NAMES = { - "Cryptography_HAS_REMOVE_THREAD_STATE": [ - "ERR_remove_thread_state" - ], - "Cryptography_HAS_098H_ERROR_CODES": [ - "ASN1_F_B64_READ_ASN1", - "ASN1_F_B64_WRITE_ASN1", - "ASN1_F_SMIME_READ_ASN1", - "ASN1_F_SMIME_TEXT", - "ASN1_R_NO_CONTENT_TYPE", - "ASN1_R_NO_MULTIPART_BODY_FAILURE", - "ASN1_R_NO_MULTIPART_BOUNDARY", - ], - "Cryptography_HAS_098C_CAMELLIA_CODES": [ - "EVP_F_CAMELLIA_INIT_KEY", - "EVP_R_CAMELLIA_KEY_SETUP_FAILED" - ], - "Cryptography_HAS_EC_CODES": [ - "EC_R_UNKNOWN_GROUP", - "EC_F_EC_GROUP_NEW_BY_CURVE_NAME" - ], - "Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR": [ - "RSA_R_PKCS_DECODING_ERROR" - ] -} diff --git a/cryptography/hazmat/bindings/openssl/evp.py b/cryptography/hazmat/bindings/openssl/evp.py deleted file mode 100644 index 033b083b..00000000 --- a/cryptography/hazmat/bindings/openssl/evp.py +++ /dev/null @@ -1,263 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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); - -int EVP_PKEY_cmp(const EVP_PKEY *, const EVP_PKEY *); -""" - -MACROS = """ -void OpenSSL_add_all_algorithms(void); -int EVP_PKEY_assign_RSA(EVP_PKEY *, RSA *); -int EVP_PKEY_assign_DSA(EVP_PKEY *, DSA *); - -int EVP_PKEY_assign_EC_KEY(EVP_PKEY *, EC_KEY *); -EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *); -int EVP_PKEY_set1_EC_KEY(EVP_PKEY *, EC_KEY *); - -int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *); -int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *, int, int, void *); - -int PKCS5_PBKDF2_HMAC(const char *, int, const unsigned char *, int, int, - const EVP_MD *, int, unsigned char *); - -int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *, const EVP_MD *); - -/* These aren't macros, but must be in this section because they're not - available in 0.9.8. */ -EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *, ENGINE *); -EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int, ENGINE *); -EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *); -void EVP_PKEY_CTX_free(EVP_PKEY_CTX *); -int EVP_PKEY_sign_init(EVP_PKEY_CTX *); -int EVP_PKEY_sign(EVP_PKEY_CTX *, unsigned char *, size_t *, - const unsigned char *, size_t); -int EVP_PKEY_verify_init(EVP_PKEY_CTX *); -int EVP_PKEY_verify(EVP_PKEY_CTX *, const unsigned char *, size_t, - const unsigned char *, size_t); -int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *); -int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *); - -/* The following were macros in 0.9.8e. Once we drop support for RHEL/CentOS 5 - we should move these back to FUNCTIONS. */ -const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *); -int EVP_CIPHER_block_size(const EVP_CIPHER *); -const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *); -int EVP_MD_size(const EVP_MD *); - -/* Must be in macros because EVP_PKEY_CTX is undefined in 0.9.8 */ -int Cryptography_EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t inlen); -int Cryptography_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t inlen); -""" - -CUSTOMIZATIONS = """ -#ifdef EVP_CTRL_GCM_SET_TAG -const long Cryptography_HAS_GCM = 1; -#else -const long Cryptography_HAS_GCM = 0; -const long EVP_CTRL_GCM_GET_TAG = -1; -const long EVP_CTRL_GCM_SET_TAG = -1; -const long EVP_CTRL_GCM_SET_IVLEN = -1; -#endif -#if OPENSSL_VERSION_NUMBER >= 0x10000000L -const long Cryptography_HAS_PBKDF2_HMAC = 1; -const long Cryptography_HAS_PKEY_CTX = 1; - -/* OpenSSL 0.9.8 defines EVP_PKEY_encrypt and EVP_PKEY_decrypt functions, - but they are a completely different signature from the ones in 1.0.0+. - These wrapper functions allows us to safely declare them on any version and - conditionally remove them on 0.9.8. */ -int Cryptography_EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t inlen) { - return EVP_PKEY_encrypt(ctx, out, outlen, in, inlen); -} -int Cryptography_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t inlen) { - return EVP_PKEY_decrypt(ctx, out, outlen, in, inlen); -} -#else -const long Cryptography_HAS_PBKDF2_HMAC = 0; -int (*PKCS5_PBKDF2_HMAC)(const char *, int, const unsigned char *, int, int, - const EVP_MD *, int, unsigned char *) = NULL; -const long Cryptography_HAS_PKEY_CTX = 0; -typedef void EVP_PKEY_CTX; -int (*EVP_PKEY_CTX_set_signature_md)(EVP_PKEY_CTX *, const EVP_MD *) = NULL; -int (*EVP_PKEY_sign_init)(EVP_PKEY_CTX *) = NULL; -int (*EVP_PKEY_sign)(EVP_PKEY_CTX *, unsigned char *, size_t *, - const unsigned char *, size_t) = NULL; -int (*EVP_PKEY_verify_init)(EVP_PKEY_CTX *) = NULL; -int (*EVP_PKEY_verify)(EVP_PKEY_CTX *, const unsigned char *, size_t, - const unsigned char *, size_t) = NULL; -EVP_PKEY_CTX *(*EVP_PKEY_CTX_new)(EVP_PKEY *, ENGINE *) = NULL; -EVP_PKEY_CTX *(*EVP_PKEY_CTX_new_id)(int, ENGINE *) = NULL; -EVP_PKEY_CTX *(*EVP_PKEY_CTX_dup)(EVP_PKEY_CTX *) = NULL; -void (*EVP_PKEY_CTX_free)(EVP_PKEY_CTX *) = NULL; -int (*EVP_PKEY_encrypt_init)(EVP_PKEY_CTX *) = NULL; -int (*EVP_PKEY_decrypt_init)(EVP_PKEY_CTX *) = NULL; -int (*Cryptography_EVP_PKEY_encrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *, - const unsigned char *, size_t) = NULL; -int (*Cryptography_EVP_PKEY_decrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *, - const unsigned char *, size_t) = NULL; -#endif -#ifdef OPENSSL_NO_EC -int (*EVP_PKEY_assign_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL; -EC_KEY *(*EVP_PKEY_get1_EC_KEY)(EVP_PKEY *) = NULL; -int (*EVP_PKEY_set1_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL; -#endif - -""" - -CONDITIONAL_NAMES = { - "Cryptography_HAS_GCM": [ - "EVP_CTRL_GCM_GET_TAG", - "EVP_CTRL_GCM_SET_TAG", - "EVP_CTRL_GCM_SET_IVLEN", - ], - "Cryptography_HAS_PBKDF2_HMAC": [ - "PKCS5_PBKDF2_HMAC" - ], - "Cryptography_HAS_PKEY_CTX": [ - "EVP_PKEY_CTX_new", - "EVP_PKEY_CTX_new_id", - "EVP_PKEY_CTX_dup", - "EVP_PKEY_CTX_free", - "EVP_PKEY_sign", - "EVP_PKEY_sign_init", - "EVP_PKEY_verify", - "EVP_PKEY_verify_init", - "Cryptography_EVP_PKEY_encrypt", - "EVP_PKEY_encrypt_init", - "Cryptography_EVP_PKEY_decrypt", - "EVP_PKEY_decrypt_init", - "EVP_PKEY_CTX_set_signature_md", - ], - "Cryptography_HAS_EC": [ - "EVP_PKEY_assign_EC_KEY", - "EVP_PKEY_get1_EC_KEY", - "EVP_PKEY_set1_EC_KEY", - ] -} diff --git a/cryptography/hazmat/bindings/openssl/hmac.py b/cryptography/hazmat/bindings/openssl/hmac.py deleted file mode 100644 index 6a64b92c..00000000 --- a/cryptography/hazmat/bindings/openssl/hmac.py +++ /dev/null @@ -1,94 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/openssl/nid.py b/cryptography/hazmat/bindings/openssl/nid.py deleted file mode 100644 index b2e61492..00000000 --- a/cryptography/hazmat/bindings/openssl/nid.py +++ /dev/null @@ -1,241 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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_pbe_WithSHA1And3_Key_TripleDES_CBC; -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; - -static const int NID_subject_key_identifier; -static const int NID_authority_key_identifier; -static const int NID_policy_constraints; -static const int NID_ext_key_usage; -static const int NID_info_access; -static const int NID_key_usage; -static const int NID_subject_alt_name; -static const int NID_issuer_alt_name; -static const int NID_basic_constraints; -static const int NID_issuing_distribution_point; -static const int NID_certificate_issuer; -static const int NID_name_constraints; -static const int NID_crl_distribution_points; -static const int NID_certificate_policies; -static const int NID_inhibit_any_policy; - -static const int NID_private_key_usage_period; -static const int NID_crl_number; -static const int NID_crl_reason; -static const int NID_invalidity_date; -static const int NID_delta_crl; -static const int NID_any_policy; -static const int NID_policy_mappings; -static const int NID_target_information; -static const int NID_no_rev_avail; -""" - -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", - ], -} diff --git a/cryptography/hazmat/bindings/openssl/objects.py b/cryptography/hazmat/bindings/openssl/objects.py deleted file mode 100644 index 557c0158..00000000 --- a/cryptography/hazmat/bindings/openssl/objects.py +++ /dev/null @@ -1,45 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/openssl/opensslv.py b/cryptography/hazmat/bindings/openssl/opensslv.py deleted file mode 100644 index ef6e057b..00000000 --- a/cryptography/hazmat/bindings/openssl/opensslv.py +++ /dev/null @@ -1,36 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -TYPES = """ -/* Note that these will be resolved when cryptography is compiled and are NOT - guaranteed to be the version that it actually loads. */ -static const int OPENSSL_VERSION_NUMBER; -static const char *const OPENSSL_VERSION_TEXT; -""" - -FUNCTIONS = """ -""" - -MACROS = """ -""" - -CUSTOMIZATIONS = """ -""" - -CONDITIONAL_NAMES = {} diff --git a/cryptography/hazmat/bindings/openssl/osrandom_engine.py b/cryptography/hazmat/bindings/openssl/osrandom_engine.py deleted file mode 100644 index 462997cc..00000000 --- a/cryptography/hazmat/bindings/openssl/osrandom_engine.py +++ /dev/null @@ -1,218 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#ifdef _WIN32 -#include -#else -#include -#include -#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 = {} diff --git a/cryptography/hazmat/bindings/openssl/pem.py b/cryptography/hazmat/bindings/openssl/pem.py deleted file mode 100644 index 752f1987..00000000 --- a/cryptography/hazmat/bindings/openssl/pem.py +++ /dev/null @@ -1,89 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 *); - -PKCS7 *d2i_PKCS7_bio(BIO *, PKCS7 **); -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 = {} diff --git a/cryptography/hazmat/bindings/openssl/pkcs12.py b/cryptography/hazmat/bindings/openssl/pkcs12.py deleted file mode 100644 index a8f106f6..00000000 --- a/cryptography/hazmat/bindings/openssl/pkcs12.py +++ /dev/null @@ -1,41 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/openssl/pkcs7.py b/cryptography/hazmat/bindings/openssl/pkcs7.py deleted file mode 100644 index 1343e566..00000000 --- a/cryptography/hazmat/bindings/openssl/pkcs7.py +++ /dev/null @@ -1,41 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/openssl/rand.py b/cryptography/hazmat/bindings/openssl/rand.py deleted file mode 100644 index 7b1be9df..00000000 --- a/cryptography/hazmat/bindings/openssl/rand.py +++ /dev/null @@ -1,45 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/openssl/rsa.py b/cryptography/hazmat/bindings/openssl/rsa.py deleted file mode 100644 index cb8e701e..00000000 --- a/cryptography/hazmat/bindings/openssl/rsa.py +++ /dev/null @@ -1,108 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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", - ], -} diff --git a/cryptography/hazmat/bindings/openssl/ssl.py b/cryptography/hazmat/bindings/openssl/ssl.py deleted file mode 100644 index 7d805e78..00000000 --- a/cryptography/hazmat/bindings/openssl/ssl.py +++ /dev/null @@ -1,620 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include - -typedef STACK_OF(SSL_CIPHER) Cryptography_STACK_OF_SSL_CIPHER; -""" - -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; -static const long Cryptography_HAS_SECURE_RENEGOTIATION; - -/* 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 Cryptography_HAS_ALPN; - -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_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; -static const long SSL_OP_LEGACY_SERVER_CONNECT; -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 ... 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; -typedef ... Cryptography_STACK_OF_SSL_CIPHER; -typedef ... COMP_METHOD; -""" - -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); -Cryptography_STACK_OF_SSL_CIPHER *SSL_get_ciphers(const SSL *); - -const COMP_METHOD *SSL_get_current_compression(SSL *); -const COMP_METHOD *SSL_get_current_expansion(SSL *); -const char *SSL_COMP_get_name(const COMP_METHOD *); - -/* 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 *); - -/* 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 *); -long SSL_get_secure_renegotiation_support(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 *); - -int sk_SSL_CIPHER_num(Cryptography_STACK_OF_SSL_CIPHER *); -SSL_CIPHER *sk_SSL_CIPHER_value(Cryptography_STACK_OF_SSL_CIPHER *, int); - -/* ALPN APIs were introduced in OpenSSL 1.0.2. To continue to support earlier - * versions some special handling of these is necessary. - */ -int SSL_CTX_set_alpn_protos(SSL_CTX *, const unsigned char*, unsigned); -int SSL_set_alpn_protos(SSL *, const unsigned char*, unsigned); -void SSL_CTX_set_alpn_select_cb(SSL_CTX *, - int (*) (SSL *, - const unsigned char **, - unsigned char *, - const unsigned char *, - unsigned int, - void *), - void *); -void SSL_get0_alpn_selected(const SSL *, const unsigned char **, unsigned *); -""" - -CUSTOMIZATIONS = """ -/** Secure renegotiation is supported in OpenSSL >= 0.9.8m - * But some Linux distributions have back ported some features. - */ -#ifndef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION -static const long Cryptography_HAS_SECURE_RENEGOTIATION = 0; -long (*SSL_get_secure_renegotiation_support)(SSL *) = NULL; -const long SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = 0; -const long SSL_OP_LEGACY_SERVER_CONNECT = 0; -#else -static const long Cryptography_HAS_SECURE_RENEGOTIATION = 1; -#endif -#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 -# 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 - -/* ALPN was added in OpenSSL 1.0.2. */ -#if OPENSSL_VERSION_NUMBER < 0x10002001L -int (*SSL_CTX_set_alpn_protos)(SSL_CTX *, - const unsigned char*, - unsigned) = NULL; -int (*SSL_set_alpn_protos)(SSL *, const unsigned char*, unsigned) = NULL; -void (*SSL_CTX_set_alpn_select_cb)(SSL_CTX *, - int (*) (SSL *, - const unsigned char **, - unsigned char *, - const unsigned char *, - unsigned int, - void *), - void *) = NULL; -void (*SSL_get0_alpn_selected)(const SSL *, - const unsigned char **, - unsigned *) = NULL; -static const long Cryptography_HAS_ALPN = 0; -#else -static const long Cryptography_HAS_ALPN = 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", - ], - - "Cryptography_HAS_SECURE_RENEGOTIATION": [ - "SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", - "SSL_OP_LEGACY_SERVER_CONNECT", - "SSL_get_secure_renegotiation_support", - ], - - "Cryptography_HAS_ALPN": [ - "SSL_CTX_set_alpn_protos", - "SSL_set_alpn_protos", - "SSL_CTX_set_alpn_select_cb", - "SSL_get0_alpn_selected", - ] -} diff --git a/cryptography/hazmat/bindings/openssl/x509.py b/cryptography/hazmat/bindings/openssl/x509.py deleted file mode 100644 index 95bc7c3b..00000000 --- a/cryptography/hazmat/bindings/openssl/x509.py +++ /dev/null @@ -1,273 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include - -/* - * 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_CRL) Cryptography_STACK_OF_X509_CRL; -typedef STACK_OF(X509_REVOKED) Cryptography_STACK_OF_X509_REVOKED; -""" - -TYPES = """ -typedef ... Cryptography_STACK_OF_X509; -typedef ... Cryptography_STACK_OF_X509_CRL; -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 ... 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 *); -int X509_REQ_digest(const X509_REQ *, const EVP_MD *, - unsigned char *, unsigned int *); -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 *); - -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", - ] -} diff --git a/cryptography/hazmat/bindings/openssl/x509_vfy.py b/cryptography/hazmat/bindings/openssl/x509_vfy.py deleted file mode 100644 index 601926c9..00000000 --- a/cryptography/hazmat/bindings/openssl/x509_vfy.py +++ /dev/null @@ -1,336 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include - -/* - * 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(ASN1_OBJECT) Cryptography_STACK_OF_ASN1_OBJECT; -""" - -TYPES = """ -static const long Cryptography_HAS_102_VERIFICATION_ERROR_CODES; -static const long Cryptography_HAS_102_VERIFICATION_PARAMS; -static const long Cryptography_HAS_X509_V_FLAG_TRUSTED_FIRST; -static const long Cryptography_HAS_X509_V_FLAG_PARTIAL_CHAIN; -static const long Cryptography_HAS_100_VERIFICATION_ERROR_CODES; -static const long Cryptography_HAS_100_VERIFICATION_PARAMS; -static const long Cryptography_HAS_X509_V_FLAG_CHECK_SS_SIGNATURE; - -typedef ... Cryptography_STACK_OF_ASN1_OBJECT; - -typedef ... X509_STORE; -typedef ... X509_STORE_CTX; -typedef ... X509_VERIFY_PARAM; - -/* While these are defined in the source as ints, they're tagged here - as longs, just in case they ever grow to large, such as what we saw - with OP_ALL. */ - -/* Verification error codes */ -static const int X509_V_OK; -static const int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; -static const int X509_V_ERR_UNABLE_TO_GET_CRL; -static const int X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE; -static const int X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE; -static const int X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; -static const int X509_V_ERR_CERT_SIGNATURE_FAILURE; -static const int X509_V_ERR_CRL_SIGNATURE_FAILURE; -static const int X509_V_ERR_CERT_NOT_YET_VALID; -static const int X509_V_ERR_CERT_HAS_EXPIRED; -static const int X509_V_ERR_CRL_NOT_YET_VALID; -static const int X509_V_ERR_CRL_HAS_EXPIRED; -static const int X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; -static const int X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; -static const int X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; -static const int X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; -static const int X509_V_ERR_OUT_OF_MEM; -static const int X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; -static const int X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; -static const int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; -static const int X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; -static const int X509_V_ERR_CERT_CHAIN_TOO_LONG; -static const int X509_V_ERR_CERT_REVOKED; -static const int X509_V_ERR_INVALID_CA; -static const int X509_V_ERR_PATH_LENGTH_EXCEEDED; -static const int X509_V_ERR_INVALID_PURPOSE; -static const int X509_V_ERR_CERT_UNTRUSTED; -static const int X509_V_ERR_CERT_REJECTED; -static const int X509_V_ERR_SUBJECT_ISSUER_MISMATCH; -static const int X509_V_ERR_AKID_SKID_MISMATCH; -static const int X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; -static const int X509_V_ERR_KEYUSAGE_NO_CERTSIGN; -static const int X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; -static const int X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; -static const int X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; -static const int X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; -static const int X509_V_ERR_INVALID_NON_CA; -static const int X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; -static const int X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; -static const int X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; -static const int X509_V_ERR_INVALID_EXTENSION; -static const int X509_V_ERR_INVALID_POLICY_EXTENSION; -static const int X509_V_ERR_NO_EXPLICIT_POLICY; -static const int X509_V_ERR_DIFFERENT_CRL_SCOPE; -static const int X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE; -static const int X509_V_ERR_UNNESTED_RESOURCE; -static const int X509_V_ERR_PERMITTED_VIOLATION; -static const int X509_V_ERR_EXCLUDED_VIOLATION; -static const int X509_V_ERR_SUBTREE_MINMAX; -static const int X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; -static const int X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; -static const int X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; -static const int X509_V_ERR_CRL_PATH_VALIDATION_ERROR; -static const int X509_V_ERR_SUITE_B_INVALID_VERSION; -static const int X509_V_ERR_SUITE_B_INVALID_ALGORITHM; -static const int X509_V_ERR_SUITE_B_INVALID_CURVE; -static const int X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; -static const int X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; -static const int X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256; -static const int X509_V_ERR_HOSTNAME_MISMATCH; -static const int X509_V_ERR_EMAIL_MISMATCH; -static const int X509_V_ERR_IP_ADDRESS_MISMATCH; -static const int X509_V_ERR_APPLICATION_VERIFICATION; - -/* Verification parameters */ -static const long X509_V_FLAG_CB_ISSUER_CHECK; -static const long X509_V_FLAG_USE_CHECK_TIME; -static const long X509_V_FLAG_CRL_CHECK; -static const long X509_V_FLAG_CRL_CHECK_ALL; -static const long X509_V_FLAG_IGNORE_CRITICAL; -static const long X509_V_FLAG_X509_STRICT; -static const long X509_V_FLAG_ALLOW_PROXY_CERTS; -static const long X509_V_FLAG_POLICY_CHECK; -static const long X509_V_FLAG_EXPLICIT_POLICY; -static const long X509_V_FLAG_INHIBIT_ANY; -static const long X509_V_FLAG_INHIBIT_MAP; -static const long X509_V_FLAG_NOTIFY_POLICY; -static const long X509_V_FLAG_EXTENDED_CRL_SUPPORT; -static const long X509_V_FLAG_USE_DELTAS; -static const long X509_V_FLAG_CHECK_SS_SIGNATURE; -static const long X509_V_FLAG_TRUSTED_FIRST; -static const long X509_V_FLAG_SUITEB_128_LOS_ONLY; -static const long X509_V_FLAG_SUITEB_192_LOS; -static const long X509_V_FLAG_SUITEB_128_LOS; -static const long X509_V_FLAG_PARTIAL_CHAIN; -""" - -FUNCTIONS = """ -int X509_verify_cert(X509_STORE_CTX *); - -/* X509_STORE */ -X509_STORE *X509_STORE_new(void); -void X509_STORE_free(X509_STORE *); -int X509_STORE_add_cert(X509_STORE *, X509 *); - -/* X509_STORE_CTX */ -X509_STORE_CTX *X509_STORE_CTX_new(void); -void X509_STORE_CTX_cleanup(X509_STORE_CTX *); -void X509_STORE_CTX_free(X509_STORE_CTX *); -int X509_STORE_CTX_init(X509_STORE_CTX *, X509_STORE *, X509 *, - Cryptography_STACK_OF_X509 *); -void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *, - Cryptography_STACK_OF_X509 *); -void X509_STORE_CTX_set_cert(X509_STORE_CTX *, X509 *); -void X509_STORE_CTX_set_chain(X509_STORE_CTX *,Cryptography_STACK_OF_X509 *); -X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *); -void X509_STORE_CTX_set0_param(X509_STORE_CTX *, X509_VERIFY_PARAM *); -int X509_STORE_CTX_set_default(X509_STORE_CTX *, const char *); -void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *, - int (*)(int, X509_STORE_CTX *)); -Cryptography_STACK_OF_X509 *X509_STORE_CTX_get_chain(X509_STORE_CTX *); -Cryptography_STACK_OF_X509 *X509_STORE_CTX_get1_chain(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); - -/* X509_VERIFY_PARAM */ -X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); -int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *, unsigned long); -int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *, unsigned long); -unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *); -int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *, int); -int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *, int); -void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *, time_t); -int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *, ASN1_OBJECT *); -int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *, - Cryptography_STACK_OF_ASN1_OBJECT *); -void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *, int); -int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *); -""" - -MACROS = """ -/* X509_STORE_CTX */ -void X509_STORE_CTX_set0_crls(X509_STORE_CTX *, - Cryptography_STACK_OF_X509_CRL *); - -/* X509_VERIFY_PARAM */ -int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *, const char *, - size_t); -void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *, unsigned int); -int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *, const char *, - size_t); -int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *, const unsigned char *, - size_t); -int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *, const char *); -""" - -CUSTOMIZATIONS = """ -/* OpenSSL 1.0.2+ verification error codes */ -#if OPENSSL_VERSION_NUMBER >= 0x10002000L -static const long Cryptography_HAS_102_VERIFICATION_ERROR_CODES = 1; -#else -static const long Cryptography_HAS_102_VERIFICATION_ERROR_CODES = 0; -static const long X509_V_ERR_SUITE_B_INVALID_VERSION = 0; -static const long X509_V_ERR_SUITE_B_INVALID_ALGORITHM = 0; -static const long X509_V_ERR_SUITE_B_INVALID_CURVE = 0; -static const long X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM = 0; -static const long X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED = 0; -static const long X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 = 0; -static const long X509_V_ERR_HOSTNAME_MISMATCH = 0; -static const long X509_V_ERR_EMAIL_MISMATCH = 0; -static const long X509_V_ERR_IP_ADDRESS_MISMATCH = 0; -#endif - -/* OpenSSL 1.0.2+ verification parameters */ -#if OPENSSL_VERSION_NUMBER >= 0x10002000L -static const long Cryptography_HAS_102_VERIFICATION_PARAMS = 1; -#else -static const long Cryptography_HAS_102_VERIFICATION_PARAMS = 0; -/* X509_V_FLAG_TRUSTED_FIRST is also new in 1.0.2+, but it is added separately - below because it shows up in some earlier 3rd party OpenSSL packages. */ -static const long X509_V_FLAG_SUITEB_128_LOS_ONLY = 0; -static const long X509_V_FLAG_SUITEB_192_LOS = 0; -static const long X509_V_FLAG_SUITEB_128_LOS = 0; - -int (*X509_VERIFY_PARAM_set1_host)(X509_VERIFY_PARAM *, const char *, - size_t) = NULL; -int (*X509_VERIFY_PARAM_set1_email)(X509_VERIFY_PARAM *, const char *, - size_t) = NULL; -int (*X509_VERIFY_PARAM_set1_ip)(X509_VERIFY_PARAM *, const unsigned char *, - size_t) = NULL; -int (*X509_VERIFY_PARAM_set1_ip_asc)(X509_VERIFY_PARAM *, const char *) = NULL; -void (*X509_VERIFY_PARAM_set_hostflags)(X509_VERIFY_PARAM *, - unsigned int) = NULL; -#endif - -/* OpenSSL 1.0.2+ or Solaris's backport */ -#ifdef X509_V_FLAG_PARTIAL_CHAIN -static const long Cryptography_HAS_X509_V_FLAG_PARTIAL_CHAIN = 1; -#else -static const long Cryptography_HAS_X509_V_FLAG_PARTIAL_CHAIN = 0; -static const long X509_V_FLAG_PARTIAL_CHAIN = 0; -#endif - -/* OpenSSL 1.0.2+, *or* Fedora 20's flavor of OpenSSL 1.0.1e... */ -#ifdef X509_V_FLAG_TRUSTED_FIRST -static const long Cryptography_HAS_X509_V_FLAG_TRUSTED_FIRST = 1; -#else -static const long Cryptography_HAS_X509_V_FLAG_TRUSTED_FIRST = 0; -static const long X509_V_FLAG_TRUSTED_FIRST = 0; -#endif - -/* OpenSSL 1.0.0+ verification error codes */ -#if OPENSSL_VERSION_NUMBER >= 0x10000000L -static const long Cryptography_HAS_100_VERIFICATION_ERROR_CODES = 1; -#else -static const long Cryptography_HAS_100_VERIFICATION_ERROR_CODES = 0; -static const long X509_V_ERR_DIFFERENT_CRL_SCOPE = 0; -static const long X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE = 0; -static const long X509_V_ERR_PERMITTED_VIOLATION = 0; -static const long X509_V_ERR_EXCLUDED_VIOLATION = 0; -static const long X509_V_ERR_SUBTREE_MINMAX = 0; -static const long X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE = 0; -static const long X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX = 0; -static const long X509_V_ERR_UNSUPPORTED_NAME_SYNTAX = 0; -static const long X509_V_ERR_CRL_PATH_VALIDATION_ERROR = 0; -#endif - -/* OpenSSL 1.0.0+ verification parameters */ -#if OPENSSL_VERSION_NUMBER >= 0x10000000L -static const long Cryptography_HAS_100_VERIFICATION_PARAMS = 1; -#else -static const long Cryptography_HAS_100_VERIFICATION_PARAMS = 0; -static const long X509_V_FLAG_EXTENDED_CRL_SUPPORT = 0; -static const long X509_V_FLAG_USE_DELTAS = 0; -#endif - -/* OpenSSL 0.9.8recent+ */ -#ifdef X509_V_FLAG_CHECK_SS_SIGNATURE -static const long Cryptography_HAS_X509_V_FLAG_CHECK_SS_SIGNATURE = 1; -#else -static const long Cryptography_HAS_X509_V_FLAG_CHECK_SS_SIGNATURE = 0; -static const long X509_V_FLAG_CHECK_SS_SIGNATURE = 0; -#endif -""" - -CONDITIONAL_NAMES = { - "Cryptography_HAS_102_VERIFICATION_ERROR_CODES": [ - 'X509_V_ERR_SUITE_B_INVALID_VERSION', - 'X509_V_ERR_SUITE_B_INVALID_ALGORITHM', - 'X509_V_ERR_SUITE_B_INVALID_CURVE', - 'X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM', - 'X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED', - 'X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256', - 'X509_V_ERR_HOSTNAME_MISMATCH', - 'X509_V_ERR_EMAIL_MISMATCH', - 'X509_V_ERR_IP_ADDRESS_MISMATCH' - ], - "Cryptography_HAS_102_VERIFICATION_PARAMS": [ - "X509_V_FLAG_SUITEB_128_LOS_ONLY", - "X509_V_FLAG_SUITEB_192_LOS", - "X509_V_FLAG_SUITEB_128_LOS", - "X509_VERIFY_PARAM_set1_host", - "X509_VERIFY_PARAM_set1_email", - "X509_VERIFY_PARAM_set1_ip", - "X509_VERIFY_PARAM_set1_ip_asc", - "X509_VERIFY_PARAM_set_hostflags", - ], - "Cryptography_HAS_X509_V_FLAG_TRUSTED_FIRST": [ - "X509_V_FLAG_TRUSTED_FIRST", - ], - "Cryptography_HAS_X509_V_FLAG_PARTIAL_CHAIN": [ - "X509_V_FLAG_PARTIAL_CHAIN", - ], - "Cryptography_HAS_100_VERIFICATION_ERROR_CODES": [ - 'X509_V_ERR_DIFFERENT_CRL_SCOPE', - 'X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE', - 'X509_V_ERR_UNNESTED_RESOURCE', - 'X509_V_ERR_PERMITTED_VIOLATION', - 'X509_V_ERR_EXCLUDED_VIOLATION', - 'X509_V_ERR_SUBTREE_MINMAX', - 'X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE', - 'X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX', - 'X509_V_ERR_UNSUPPORTED_NAME_SYNTAX', - 'X509_V_ERR_CRL_PATH_VALIDATION_ERROR', - ], - "Cryptography_HAS_100_VERIFICATION_PARAMS": [ - "Cryptography_HAS_100_VERIFICATION_PARAMS", - "X509_V_FLAG_EXTENDED_CRL_SUPPORT", - "X509_V_FLAG_USE_DELTAS", - ], - "Cryptography_HAS_X509_V_FLAG_CHECK_SS_SIGNATURE": [ - "X509_V_FLAG_CHECK_SS_SIGNATURE", - ] -} diff --git a/cryptography/hazmat/bindings/openssl/x509name.py b/cryptography/hazmat/bindings/openssl/x509name.py deleted file mode 100644 index 50abee2a..00000000 --- a/cryptography/hazmat/bindings/openssl/x509name.py +++ /dev/null @@ -1,61 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include - -/* - * 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 = {} diff --git a/cryptography/hazmat/bindings/openssl/x509v3.py b/cryptography/hazmat/bindings/openssl/x509v3.py deleted file mode 100644 index cf4be1fe..00000000 --- a/cryptography/hazmat/bindings/openssl/x509v3.py +++ /dev/null @@ -1,103 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -INCLUDES = """ -#include -""" - -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 *); -void GENERAL_NAMES_free(GENERAL_NAMES *); -void *X509V3_EXT_d2i(X509_EXTENSION *); -""" - -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 = {} diff --git a/cryptography/hazmat/bindings/utils.py b/cryptography/hazmat/bindings/utils.py deleted file mode 100644 index 55b61292..00000000 --- a/cryptography/hazmat/bindings/utils.py +++ /dev/null @@ -1,144 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import binascii -import sys -import threading - -from cffi import FFI -from cffi.verifier import Verifier - - -class LazyLibrary(object): - def __init__(self, ffi): - self._ffi = ffi - self._lib = None - self._lock = threading.Lock() - - def __getattr__(self, name): - if self._lib is None: - with self._lock: - if self._lib is None: - self._lib = self._ffi.verifier.load_library() - - return getattr(self._lib, name) - - -def load_library_for_binding(ffi, module_prefix, modules): - lib = ffi.verifier.load_library() - - 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 lib - - -def build_ffi_for_binding(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. - """ - 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) - - # 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); - verify_source = "\n".join( - [pre_include] + - includes + - [post_include] + - functions + - customizations - ) - ffi = build_ffi( - cdef_source="\n".join(types + functions + macros), - verify_source=verify_source, - libraries=libraries, - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - ) - - return ffi - - -def build_ffi(cdef_source, verify_source, libraries=[], extra_compile_args=[], - extra_link_args=[]): - ffi = FFI() - ffi.cdef(cdef_source) - - ffi.verifier = Verifier( - ffi, - verify_source, - tmpdir='', - modulename=_create_modulename(cdef_source, verify_source, sys.version), - libraries=libraries, - ext_package="cryptography", - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - ) - return ffi - - -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) diff --git a/cryptography/hazmat/primitives/__init__.py b/cryptography/hazmat/primitives/__init__.py deleted file mode 100644 index 2f420574..00000000 --- a/cryptography/hazmat/primitives/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function diff --git a/cryptography/hazmat/primitives/asymmetric/__init__.py b/cryptography/hazmat/primitives/asymmetric/__init__.py deleted file mode 100644 index 2f420574..00000000 --- a/cryptography/hazmat/primitives/asymmetric/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function diff --git a/cryptography/hazmat/primitives/asymmetric/dsa.py b/cryptography/hazmat/primitives/asymmetric/dsa.py deleted file mode 100644 index 83e01377..00000000 --- a/cryptography/hazmat/primitives/asymmetric/dsa.py +++ /dev/null @@ -1,108 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import six - -from cryptography import utils - - -def generate_parameters(key_size, backend): - return backend.generate_dsa_parameters(key_size) - - -def generate_private_key(key_size, backend): - return backend.generate_dsa_private_key_and_parameters(key_size) - - -def _check_dsa_parameters(parameters): - if utils.bit_length(parameters.p) not in [1024, 2048, 3072]: - raise ValueError("p must be exactly 1024, 2048, or 3072 bits long") - if utils.bit_length(parameters.q) not in [160, 256]: - raise ValueError("q must be exactly 160 or 256 bits long") - - if not (1 < parameters.g < parameters.p): - raise ValueError("g, p don't satisfy 1 < g < p.") - - -def _check_dsa_private_numbers(numbers): - parameters = numbers.public_numbers.parameter_numbers - _check_dsa_parameters(parameters) - if numbers.x <= 0 or numbers.x >= parameters.q: - raise ValueError("x must be > 0 and < q.") - - if numbers.public_numbers.y != pow(parameters.g, numbers.x, parameters.p): - raise ValueError("y must be equal to (g ** x % p).") - - -class DSAParameterNumbers(object): - def __init__(self, p, q, g): - if ( - not isinstance(p, six.integer_types) or - not isinstance(q, six.integer_types) or - not isinstance(g, six.integer_types) - ): - raise TypeError( - "DSAParameterNumbers p, q, and g arguments must be integers." - ) - - self._p = p - self._q = q - self._g = g - - p = utils.read_only_property("_p") - q = utils.read_only_property("_q") - g = utils.read_only_property("_g") - - def parameters(self, backend): - return backend.load_dsa_parameter_numbers(self) - - -class DSAPublicNumbers(object): - def __init__(self, y, parameter_numbers): - if not isinstance(y, six.integer_types): - raise TypeError("DSAPublicNumbers y argument must be an integer.") - - if not isinstance(parameter_numbers, DSAParameterNumbers): - raise TypeError( - "parameter_numbers must be a DSAParameterNumbers instance." - ) - - self._y = y - self._parameter_numbers = parameter_numbers - - y = utils.read_only_property("_y") - parameter_numbers = utils.read_only_property("_parameter_numbers") - - def public_key(self, backend): - return backend.load_dsa_public_numbers(self) - - -class DSAPrivateNumbers(object): - def __init__(self, x, public_numbers): - if not isinstance(x, six.integer_types): - raise TypeError("DSAPrivateNumbers x argument must be an integer.") - - if not isinstance(public_numbers, DSAPublicNumbers): - raise TypeError( - "public_numbers must be a DSAPublicNumbers instance." - ) - self._public_numbers = public_numbers - self._x = x - - x = utils.read_only_property("_x") - public_numbers = utils.read_only_property("_public_numbers") - - def private_key(self, backend): - return backend.load_dsa_private_numbers(self) diff --git a/cryptography/hazmat/primitives/asymmetric/ec.py b/cryptography/hazmat/primitives/asymmetric/ec.py deleted file mode 100644 index ced732fb..00000000 --- a/cryptography/hazmat/primitives/asymmetric/ec.py +++ /dev/null @@ -1,195 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import six - -from cryptography import utils -from cryptography.hazmat.primitives import interfaces - - -@utils.register_interface(interfaces.EllipticCurve) -class SECT571R1(object): - name = "sect571r1" - key_size = 571 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECT409R1(object): - name = "sect409r1" - key_size = 409 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECT283R1(object): - name = "sect283r1" - key_size = 283 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECT233R1(object): - name = "sect233r1" - key_size = 233 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECT163R2(object): - name = "sect163r2" - key_size = 163 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECT571K1(object): - name = "sect571k1" - key_size = 571 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECT409K1(object): - name = "sect409k1" - key_size = 409 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECT283K1(object): - name = "sect283k1" - key_size = 283 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECT233K1(object): - name = "sect233k1" - key_size = 233 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECT163K1(object): - name = "sect163k1" - key_size = 163 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECP521R1(object): - name = "secp521r1" - key_size = 521 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECP384R1(object): - name = "secp384r1" - key_size = 384 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECP256R1(object): - name = "secp256r1" - key_size = 256 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECP224R1(object): - name = "secp224r1" - key_size = 224 - - -@utils.register_interface(interfaces.EllipticCurve) -class SECP192R1(object): - name = "secp192r1" - key_size = 192 - - -_CURVE_TYPES = { - "prime192v1": SECP192R1, - "prime256v1": SECP256R1, - - "secp192r1": SECP192R1, - "secp224r1": SECP224R1, - "secp256r1": SECP256R1, - "secp384r1": SECP384R1, - "secp521r1": SECP521R1, - - "sect163k1": SECT163K1, - "sect233k1": SECT233K1, - "sect283k1": SECT283K1, - "sect409k1": SECT409K1, - "sect571k1": SECT571K1, - - "sect163r2": SECT163R2, - "sect233r1": SECT233R1, - "sect283r1": SECT283R1, - "sect409r1": SECT409R1, - "sect571r1": SECT571R1, -} - - -@utils.register_interface(interfaces.EllipticCurveSignatureAlgorithm) -class ECDSA(object): - def __init__(self, algorithm): - self._algorithm = algorithm - - algorithm = utils.read_only_property("_algorithm") - - -def generate_private_key(curve, backend): - return backend.generate_elliptic_curve_private_key(curve) - - -class EllipticCurvePublicNumbers(object): - def __init__(self, x, y, curve): - if ( - not isinstance(x, six.integer_types) or - not isinstance(y, six.integer_types) - ): - raise TypeError("x and y must be integers.") - - if not isinstance(curve, interfaces.EllipticCurve): - raise TypeError("curve must provide the EllipticCurve interface.") - - self._y = y - self._x = x - self._curve = curve - - def public_key(self, backend): - try: - return backend.load_elliptic_curve_public_numbers(self) - except AttributeError: - return backend.elliptic_curve_public_key_from_numbers(self) - - curve = utils.read_only_property("_curve") - x = utils.read_only_property("_x") - y = utils.read_only_property("_y") - - -class EllipticCurvePrivateNumbers(object): - def __init__(self, private_value, public_numbers): - if not isinstance(private_value, six.integer_types): - raise TypeError("private_value must be an integer.") - - if not isinstance(public_numbers, EllipticCurvePublicNumbers): - raise TypeError( - "public_numbers must be an EllipticCurvePublicNumbers " - "instance." - ) - - self._private_value = private_value - self._public_numbers = public_numbers - - def private_key(self, backend): - try: - return backend.load_elliptic_curve_private_numbers(self) - except AttributeError: - return backend.elliptic_curve_private_key_from_numbers(self) - - private_value = utils.read_only_property("_private_value") - public_numbers = utils.read_only_property("_public_numbers") diff --git a/cryptography/hazmat/primitives/asymmetric/padding.py b/cryptography/hazmat/primitives/asymmetric/padding.py deleted file mode 100644 index 3967e065..00000000 --- a/cryptography/hazmat/primitives/asymmetric/padding.py +++ /dev/null @@ -1,65 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -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): - self._mgf = mgf - - 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 - - -@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): - if not isinstance(algorithm, interfaces.HashAlgorithm): - raise TypeError("Expected instance of interfaces.HashAlgorithm.") - - self._algorithm = algorithm diff --git a/cryptography/hazmat/primitives/asymmetric/rsa.py b/cryptography/hazmat/primitives/asymmetric/rsa.py deleted file mode 100644 index db38ed55..00000000 --- a/cryptography/hazmat/primitives/asymmetric/rsa.py +++ /dev/null @@ -1,191 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import six - -from cryptography import utils -from cryptography.exceptions import UnsupportedAlgorithm, _Reasons -from cryptography.hazmat.backends.interfaces import RSABackend - - -def generate_private_key(public_exponent, key_size, backend): - if not isinstance(backend, RSABackend): - raise UnsupportedAlgorithm( - "Backend object does not implement RSABackend.", - _Reasons.BACKEND_MISSING_INTERFACE - ) - - _verify_rsa_parameters(public_exponent, key_size) - return backend.generate_rsa_private_key(public_exponent, key_size) - - -def _verify_rsa_parameters(public_exponent, key_size): - if public_exponent < 3: - raise ValueError("public_exponent must be >= 3.") - - if public_exponent & 1 == 0: - raise ValueError("public_exponent must be odd.") - - if key_size < 512: - raise ValueError("key_size must be at least 512-bits.") - - -def _check_private_key_components(p, q, private_exponent, dmp1, dmq1, iqmp, - public_exponent, modulus): - 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.") - - -def _check_public_key_components(e, n): - if n < 3: - raise ValueError("n must be >= 3.") - - if e < 3 or e >= n: - raise ValueError("e must be >= 3 and < n.") - - if e & 1 == 0: - raise ValueError("e must be odd.") - - -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) - - -class RSAPrivateNumbers(object): - def __init__(self, p, q, d, dmp1, dmq1, iqmp, - public_numbers): - if ( - not isinstance(p, six.integer_types) or - not isinstance(q, six.integer_types) or - not isinstance(d, six.integer_types) or - not isinstance(dmp1, six.integer_types) or - not isinstance(dmq1, six.integer_types) or - not isinstance(iqmp, six.integer_types) - ): - raise TypeError( - "RSAPrivateNumbers p, q, d, dmp1, dmq1, iqmp arguments must" - " all be an integers." - ) - - if not isinstance(public_numbers, RSAPublicNumbers): - raise TypeError( - "RSAPrivateNumbers public_numbers must be an RSAPublicNumbers" - " instance." - ) - - self._p = p - self._q = q - self._d = d - self._dmp1 = dmp1 - self._dmq1 = dmq1 - self._iqmp = iqmp - self._public_numbers = public_numbers - - p = utils.read_only_property("_p") - q = utils.read_only_property("_q") - d = utils.read_only_property("_d") - dmp1 = utils.read_only_property("_dmp1") - dmq1 = utils.read_only_property("_dmq1") - iqmp = utils.read_only_property("_iqmp") - public_numbers = utils.read_only_property("_public_numbers") - - def private_key(self, backend): - return backend.load_rsa_private_numbers(self) - - -class RSAPublicNumbers(object): - def __init__(self, e, n): - if ( - not isinstance(e, six.integer_types) or - not isinstance(n, six.integer_types) - ): - raise TypeError("RSAPublicNumbers arguments must be integers.") - - self._e = e - self._n = n - - e = utils.read_only_property("_e") - n = utils.read_only_property("_n") - - def public_key(self, backend): - return backend.load_rsa_public_numbers(self) - - def __repr__(self): - return "".format(self._e, self._n) diff --git a/cryptography/hazmat/primitives/ciphers/__init__.py b/cryptography/hazmat/primitives/ciphers/__init__.py deleted file mode 100644 index e5a8ca52..00000000 --- a/cryptography/hazmat/primitives/ciphers/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography.hazmat.primitives.ciphers.base import Cipher - - -__all__ = [ - "Cipher", -] diff --git a/cryptography/hazmat/primitives/ciphers/algorithms.py b/cryptography/hazmat/primitives/ciphers/algorithms.py deleted file mode 100644 index bd8437c2..00000000 --- a/cryptography/hazmat/primitives/ciphers/algorithms.py +++ /dev/null @@ -1,147 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.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 diff --git a/cryptography/hazmat/primitives/ciphers/base.py b/cryptography/hazmat/primitives/ciphers/base.py deleted file mode 100644 index e3fe5adc..00000000 --- a/cryptography/hazmat/primitives/ciphers/base.py +++ /dev/null @@ -1,132 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import ( - 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 diff --git a/cryptography/hazmat/primitives/ciphers/modes.py b/cryptography/hazmat/primitives/ciphers/modes.py deleted file mode 100644 index d995b876..00000000 --- a/cryptography/hazmat/primitives/ciphers/modes.py +++ /dev/null @@ -1,125 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.hazmat.primitives import interfaces - - -def _check_iv_length(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 CBC(object): - name = "CBC" - - def __init__(self, initialization_vector): - self._initialization_vector = initialization_vector - - initialization_vector = utils.read_only_property("_initialization_vector") - validate_for_algorithm = _check_iv_length - - -@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 - - initialization_vector = utils.read_only_property("_initialization_vector") - validate_for_algorithm = _check_iv_length - - -@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 - - initialization_vector = utils.read_only_property("_initialization_vector") - validate_for_algorithm = _check_iv_length - - -@utils.register_interface(interfaces.Mode) -@utils.register_interface(interfaces.ModeWithInitializationVector) -class CFB8(object): - name = "CFB8" - - def __init__(self, initialization_vector): - self._initialization_vector = initialization_vector - - initialization_vector = utils.read_only_property("_initialization_vector") - validate_for_algorithm = _check_iv_length - - -@utils.register_interface(interfaces.Mode) -@utils.register_interface(interfaces.ModeWithNonce) -class CTR(object): - name = "CTR" - - def __init__(self, nonce): - self._nonce = nonce - - nonce = utils.read_only_property("_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, min_tag_length=16): - # 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 min_tag_length < 4: - raise ValueError("min_tag_length must be >= 4") - if tag is not None and len(tag) < min_tag_length: - raise ValueError( - "Authentication tag must be {0} bytes or longer.".format( - min_tag_length) - ) - - self._initialization_vector = initialization_vector - self._tag = tag - - tag = utils.read_only_property("_tag") - initialization_vector = utils.read_only_property("_initialization_vector") - - def validate_for_algorithm(self, algorithm): - pass diff --git a/cryptography/hazmat/primitives/cmac.py b/cryptography/hazmat/primitives/cmac.py deleted file mode 100644 index 6f722031..00000000 --- a/cryptography/hazmat/primitives/cmac.py +++ /dev/null @@ -1,75 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import ( - AlreadyFinalized, UnsupportedAlgorithm, _Reasons -) -from cryptography.hazmat.backends.interfaces import CMACBackend -from cryptography.hazmat.primitives import interfaces - - -@utils.register_interface(interfaces.MACContext) -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 not isinstance(data, bytes): - raise TypeError("data must be bytes.") - 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 not isinstance(signature, bytes): - raise TypeError("signature must be bytes.") - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - - ctx, self._ctx = self._ctx, None - ctx.verify(signature) - - 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() - ) diff --git a/cryptography/hazmat/primitives/constant_time.py b/cryptography/hazmat/primitives/constant_time.py deleted file mode 100644 index a14eda85..00000000 --- a/cryptography/hazmat/primitives/constant_time.py +++ /dev/null @@ -1,47 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import hmac -import os - -from cryptography.hazmat.bindings.utils import LazyLibrary, build_ffi - - -with open(os.path.join(os.path.dirname(__file__), "src/constant_time.h")) as f: - TYPES = f.read() - -with open(os.path.join(os.path.dirname(__file__), "src/constant_time.c")) as f: - FUNCTIONS = f.read() - - -_ffi = build_ffi(cdef_source=TYPES, verify_source=FUNCTIONS) -_lib = LazyLibrary(_ffi) - - -if hasattr(hmac, "compare_digest"): - def bytes_eq(a, b): - if not isinstance(a, bytes) or not isinstance(b, bytes): - raise TypeError("a and b must be bytes.") - - return hmac.compare_digest(a, b) - -else: - def bytes_eq(a, b): - if not isinstance(a, bytes) or not isinstance(b, bytes): - raise TypeError("a and b must be bytes.") - - return _lib.Cryptography_constant_time_bytes_eq( - a, len(a), b, len(b) - ) == 1 diff --git a/cryptography/hazmat/primitives/hashes.py b/cryptography/hazmat/primitives/hashes.py deleted file mode 100644 index 8c2284e3..00000000 --- a/cryptography/hazmat/primitives/hashes.py +++ /dev/null @@ -1,121 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import ( - 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 - - algorithm = utils.read_only_property("_algorithm") - - def update(self, data): - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - if not isinstance(data, bytes): - raise TypeError("data must be bytes.") - 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 diff --git a/cryptography/hazmat/primitives/hmac.py b/cryptography/hazmat/primitives/hmac.py deleted file mode 100644 index 47a048ff..00000000 --- a/cryptography/hazmat/primitives/hmac.py +++ /dev/null @@ -1,78 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import ( - AlreadyFinalized, UnsupportedAlgorithm, _Reasons -) -from cryptography.hazmat.backends.interfaces import HMACBackend -from cryptography.hazmat.primitives import interfaces - - -@utils.register_interface(interfaces.MACContext) -@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 - - algorithm = utils.read_only_property("_algorithm") - - def update(self, data): - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - if not isinstance(data, bytes): - raise TypeError("data must be bytes.") - self._ctx.update(data) - - 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 not isinstance(signature, bytes): - raise TypeError("signature must be bytes.") - if self._ctx is None: - raise AlreadyFinalized("Context was already finalized.") - - ctx, self._ctx = self._ctx, None - ctx.verify(signature) diff --git a/cryptography/hazmat/primitives/interfaces.py b/cryptography/hazmat/primitives/interfaces.py deleted file mode 100644 index 370fd68a..00000000 --- a/cryptography/hazmat/primitives/interfaces.py +++ /dev/null @@ -1,499 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import abc - -import six - - -@six.add_metaclass(abc.ABCMeta) -class 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): - """ - Returns an AsymmetricSignatureContext used for signing data. - """ - - @abc.abstractmethod - def decrypt(self, ciphertext, padding): - """ - Decrypts the provided ciphertext. - """ - - @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. - """ - - -@six.add_metaclass(abc.ABCMeta) -class RSAPrivateKeyWithNumbers(RSAPrivateKey): - @abc.abstractmethod - def private_numbers(self): - """ - Returns an RSAPrivateNumbers. - """ - - -@six.add_metaclass(abc.ABCMeta) -class RSAPublicKey(object): - @abc.abstractmethod - def verifier(self, signature, padding, algorithm): - """ - Returns an AsymmetricVerificationContext used for verifying signatures. - """ - - @abc.abstractmethod - def encrypt(self, plaintext, padding): - """ - Encrypts the given plaintext. - """ - - @abc.abstractproperty - def key_size(self): - """ - The bit length of the public modulus. - """ - - -@six.add_metaclass(abc.ABCMeta) -class RSAPublicKeyWithNumbers(RSAPublicKey): - @abc.abstractmethod - def public_numbers(self): - """ - Returns an RSAPublicNumbers - """ - - -@six.add_metaclass(abc.ABCMeta) -class DSAParameters(object): - @abc.abstractmethod - def generate_private_key(self): - """ - Generates and returns a DSAPrivateKey. - """ - - -@six.add_metaclass(abc.ABCMeta) -class DSAParametersWithNumbers(DSAParameters): - @abc.abstractmethod - def parameter_numbers(self): - """ - Returns a DSAParameterNumbers. - """ - - -@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.abstractmethod - def parameters(self): - """ - The DSAParameters object associated with this private key. - """ - - @abc.abstractmethod - def signer(self, signature_algorithm): - """ - Returns an AsymmetricSignatureContext used for signing data. - """ - - -@six.add_metaclass(abc.ABCMeta) -class DSAPrivateKeyWithNumbers(DSAPrivateKey): - @abc.abstractmethod - def private_numbers(self): - """ - Returns a DSAPrivateNumbers. - """ - - -@six.add_metaclass(abc.ABCMeta) -class DSAPublicKey(object): - @abc.abstractproperty - def key_size(self): - """ - The bit length of the prime modulus. - """ - - @abc.abstractmethod - def parameters(self): - """ - The DSAParameters object associated with this public key. - """ - - @abc.abstractmethod - def verifier(self, signature, signature_algorithm): - """ - Returns an AsymmetricVerificationContext used for signing data. - """ - - -@six.add_metaclass(abc.ABCMeta) -class DSAPublicKeyWithNumbers(DSAPublicKey): - @abc.abstractmethod - def public_numbers(self): - """ - Returns a DSAPublicNumbers. - """ - - -@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 EllipticCurve(object): - @abc.abstractproperty - def name(self): - """ - The name of the curve. e.g. secp256r1. - """ - - @abc.abstractproperty - def key_size(self): - """ - The bit length of the base point of the curve. - """ - - -@six.add_metaclass(abc.ABCMeta) -class EllipticCurveSignatureAlgorithm(object): - @abc.abstractproperty - def algorithm(self): - """ - The digest algorithm used with this signature. - """ - - -@six.add_metaclass(abc.ABCMeta) -class EllipticCurvePrivateKey(object): - @abc.abstractmethod - def signer(self, signature_algorithm): - """ - Returns an AsymmetricSignatureContext used for signing data. - """ - - @abc.abstractmethod - def public_key(self): - """ - The EllipticCurvePublicKey for this private key. - """ - - @abc.abstractproperty - def curve(self): - """ - The EllipticCurve that this key is on. - """ - - -@six.add_metaclass(abc.ABCMeta) -class EllipticCurvePrivateKeyWithNumbers(EllipticCurvePrivateKey): - @abc.abstractmethod - def private_numbers(self): - """ - Returns an EllipticCurvePrivateNumbers. - """ - - -@six.add_metaclass(abc.ABCMeta) -class EllipticCurvePublicKey(object): - @abc.abstractmethod - def verifier(self, signature, signature_algorithm): - """ - Returns an AsymmetricVerificationContext used for signing data. - """ - - @abc.abstractproperty - def curve(self): - """ - The EllipticCurve that this key is on. - """ - - -@six.add_metaclass(abc.ABCMeta) -class EllipticCurvePublicKeyWithNumbers(EllipticCurvePublicKey): - @abc.abstractmethod - def public_numbers(self): - """ - Returns an EllipticCurvePublicNumbers. - """ - - -@six.add_metaclass(abc.ABCMeta) -class MACContext(object): - @abc.abstractmethod - def update(self, data): - """ - Processes the provided bytes. - """ - - @abc.abstractmethod - def finalize(self): - """ - Returns the message authentication code as bytes. - """ - - @abc.abstractmethod - def copy(self): - """ - Return a MACContext that is a copy of the current context. - """ - - @abc.abstractmethod - def verify(self, signature): - """ - Checks if the generated message authentication code matches the - signature. - """ - -# DeprecatedIn07 -CMACContext = MACContext diff --git a/cryptography/hazmat/primitives/kdf/__init__.py b/cryptography/hazmat/primitives/kdf/__init__.py deleted file mode 100644 index 2f420574..00000000 --- a/cryptography/hazmat/primitives/kdf/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function diff --git a/cryptography/hazmat/primitives/kdf/hkdf.py b/cryptography/hazmat/primitives/kdf/hkdf.py deleted file mode 100644 index 04d02b26..00000000 --- a/cryptography/hazmat/primitives/kdf/hkdf.py +++ /dev/null @@ -1,124 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import six - -from cryptography import utils -from cryptography.exceptions import ( - 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 - - if not isinstance(salt, bytes) and salt is not None: - raise TypeError("salt must be bytes.") - - if salt is None: - salt = b"\x00" * (self._algorithm.digest_size // 8) - - self._salt = salt - - self._backend = backend - - self._hkdf_expand = HKDFExpand(self._algorithm, length, info, backend) - - def _extract(self, key_material): - h = hmac.HMAC(self._salt, self._algorithm, backend=self._backend) - h.update(key_material) - return h.finalize() - - def derive(self, key_material): - if not isinstance(key_material, bytes): - raise TypeError("key_material must be bytes.") - - return self._hkdf_expand.derive(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 - - -@utils.register_interface(interfaces.KeyDerivationFunction) -class HKDFExpand(object): - def __init__(self, algorithm, length, info, backend): - if not isinstance(backend, HMACBackend): - raise UnsupportedAlgorithm( - "Backend object does not implement HMACBackend.", - _Reasons.BACKEND_MISSING_INTERFACE - ) - - self._algorithm = algorithm - - self._backend = backend - - 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 not isinstance(info, bytes) and info is not None: - raise TypeError("info must be bytes.") - - if info is None: - info = b"" - - self._info = info - - self._used = False - - 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 not isinstance(key_material, bytes): - raise TypeError("key_material must be bytes.") - - if self._used: - raise AlreadyFinalized - - self._used = True - return self._expand(key_material) - - def verify(self, key_material, expected_key): - if not constant_time.bytes_eq(self.derive(key_material), expected_key): - raise InvalidKey diff --git a/cryptography/hazmat/primitives/kdf/pbkdf2.py b/cryptography/hazmat/primitives/kdf/pbkdf2.py deleted file mode 100644 index 97b6408c..00000000 --- a/cryptography/hazmat/primitives/kdf/pbkdf2.py +++ /dev/null @@ -1,66 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography import utils -from cryptography.exceptions import ( - 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 not isinstance(salt, bytes): - raise TypeError("salt must be bytes.") - 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 not isinstance(key_material, bytes): - raise TypeError("key_material must be bytes.") - 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.") diff --git a/cryptography/hazmat/primitives/padding.py b/cryptography/hazmat/primitives/padding.py deleted file mode 100644 index 7aeeff7c..00000000 --- a/cryptography/hazmat/primitives/padding.py +++ /dev/null @@ -1,164 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import six - -from cryptography import utils -from cryptography.exceptions import AlreadyFinalized -from cryptography.hazmat.bindings.utils import LazyLibrary, build_ffi -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 = build_ffi(cdef_source=TYPES, verify_source=FUNCTIONS) -_lib = LazyLibrary(_ffi) - - -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 not isinstance(data, bytes): - raise TypeError("data must be bytes.") - - 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 not isinstance(data, bytes): - raise TypeError("data must be bytes.") - - 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 diff --git a/cryptography/hazmat/primitives/serialization.py b/cryptography/hazmat/primitives/serialization.py deleted file mode 100644 index 0fb560e0..00000000 --- a/cryptography/hazmat/primitives/serialization.py +++ /dev/null @@ -1,50 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import warnings - -from cryptography import utils - - -def load_pem_traditional_openssl_private_key(data, password, backend): - warnings.warn( - "load_pem_traditional_openssl_private_key is deprecated and will be " - "removed in a future version, use load_pem_private_key instead.", - utils.DeprecatedIn06, - stacklevel=2 - ) - - return backend.load_traditional_openssl_pem_private_key( - data, password - ) - - -def load_pem_pkcs8_private_key(data, password, backend): - warnings.warn( - "load_pem_pkcs8_private_key is deprecated and will be removed in a " - "future version, use load_pem_private_key instead.", - utils.DeprecatedIn06, - stacklevel=2 - ) - - return backend.load_pkcs8_pem_private_key(data, password) - - -def load_pem_private_key(data, password, backend): - return backend.load_pem_private_key(data, password) - - -def load_pem_public_key(data, backend): - return backend.load_pem_public_key(data) diff --git a/cryptography/hazmat/primitives/src/constant_time.c b/cryptography/hazmat/primitives/src/constant_time.c deleted file mode 100644 index 13ac4ab9..00000000 --- a/cryptography/hazmat/primitives/src/constant_time.c +++ /dev/null @@ -1,31 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -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; -} diff --git a/cryptography/hazmat/primitives/src/constant_time.h b/cryptography/hazmat/primitives/src/constant_time.h deleted file mode 100644 index 4f41034e..00000000 --- a/cryptography/hazmat/primitives/src/constant_time.h +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -// implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -uint8_t Cryptography_constant_time_bytes_eq(uint8_t *, size_t, uint8_t *, - size_t); diff --git a/cryptography/hazmat/primitives/twofactor/__init__.py b/cryptography/hazmat/primitives/twofactor/__init__.py deleted file mode 100644 index 2f420574..00000000 --- a/cryptography/hazmat/primitives/twofactor/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function diff --git a/cryptography/hazmat/primitives/twofactor/hotp.py b/cryptography/hazmat/primitives/twofactor/hotp.py deleted file mode 100644 index d0b476a7..00000000 --- a/cryptography/hazmat/primitives/twofactor/hotp.py +++ /dev/null @@ -1,69 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -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 = six.indexbytes(hmac_value, len(hmac_value) - 1) & 0b1111 - p = hmac_value[offset:offset + 4] - return struct.unpack(">I", p)[0] & 0x7fffffff diff --git a/cryptography/hazmat/primitives/twofactor/totp.py b/cryptography/hazmat/primitives/twofactor/totp.py deleted file mode 100644 index 854c5163..00000000 --- a/cryptography/hazmat/primitives/twofactor/totp.py +++ /dev/null @@ -1,41 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -from cryptography.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.") diff --git a/cryptography/utils.py b/cryptography/utils.py deleted file mode 100644 index 03c8c0e8..00000000 --- a/cryptography/utils.py +++ /dev/null @@ -1,64 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import, division, print_function - -import abc -import inspect -import sys - - -DeprecatedIn06 = DeprecationWarning - - -def register_interface(iface): - def register_decorator(klass): - verify_interface(iface, klass) - iface.register(klass) - return klass - return register_decorator - - -def read_only_property(name): - return property(lambda self: getattr(self, name)) - - -class InterfaceNotImplemented(Exception): - pass - - -def verify_interface(iface, klass): - for method in iface.__abstractmethods__: - if not hasattr(klass, method): - raise InterfaceNotImplemented( - "{0} is missing a {1!r} method".format(klass, method) - ) - if isinstance(getattr(iface, method), abc.abstractproperty): - # Can't properly verify these yet. - continue - spec = inspect.getargspec(getattr(iface, method)) - actual = inspect.getargspec(getattr(klass, method)) - if spec != actual: - raise InterfaceNotImplemented( - "{0}.{1}'s signature differs from the expected. Expected: " - "{2!r}. Received: {3!r}".format( - klass, method, spec, actual - ) - ) - - -def bit_length(x): - if sys.version_info >= (2, 7): - return x.bit_length() - else: - return len(bin(x)) - (2 + (x <= 0)) diff --git a/docs/conf.py b/docs/conf.py index a924fa43..4ed2caf3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -87,7 +87,7 @@ copyright = '2013-2014, Individual Contributors' base_dir = os.path.join(os.path.dirname(__file__), os.pardir) about = {} -with open(os.path.join(base_dir, "cryptography", "__about__.py")) as f: +with open(os.path.join(base_dir, "src", "cryptography", "__about__.py")) as f: exec(f.read(), about) version = release = about["__version__"] diff --git a/setup.py b/setup.py index 2a6646db..d98ffdd3 100644 --- a/setup.py +++ b/setup.py @@ -27,9 +27,14 @@ from setuptools.command.test import test base_dir = os.path.dirname(__file__) +src_dir = os.path.join(base_dir, "src") + +# When executing the setup.py, we need to be able to import ourselves, this +# means that we need to add the src/ directory to the sys.path. +sys.path.insert(0, src_dir) about = {} -with open(os.path.join(base_dir, "cryptography", "__about__.py")) as f: +with open(os.path.join(src_dir, "cryptography", "__about__.py")) as f: exec(f.read(), about) @@ -324,7 +329,8 @@ setup( "Topic :: Security :: Cryptography", ], - packages=find_packages(exclude=["tests", "tests.*"]), + package_dir={"": "src"}, + packages=find_packages(where="src", exclude=["tests", "tests.*"]), include_package_data=True, install_requires=requirements, diff --git a/src/cryptography/__about__.py b/src/cryptography/__about__.py new file mode 100644 index 00000000..3d39d18b --- /dev/null +++ b/src/cryptography/__about__.py @@ -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.7.dev1" + +__author__ = "The cryptography developers" +__email__ = "cryptography-dev@python.org" + +__license__ = "BSD or Apache License, Version 2.0" +__copyright__ = "Copyright 2013-2014 {0}".format(__author__) diff --git a/src/cryptography/__init__.py b/src/cryptography/__init__.py new file mode 100644 index 00000000..f27ba856 --- /dev/null +++ b/src/cryptography/__init__.py @@ -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__", +] diff --git a/src/cryptography/exceptions.py b/src/cryptography/exceptions.py new file mode 100644 index 00000000..c14763f7 --- /dev/null +++ b/src/cryptography/exceptions.py @@ -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 + + +class _Reasons(object): + BACKEND_MISSING_INTERFACE = object() + UNSUPPORTED_HASH = object() + UNSUPPORTED_CIPHER = object() + UNSUPPORTED_PADDING = object() + UNSUPPORTED_MGF = object() + UNSUPPORTED_PUBLIC_KEY_ALGORITHM = object() + UNSUPPORTED_ELLIPTIC_CURVE = object() + UNSUPPORTED_SERIALIZATION = object() + + +class UnsupportedAlgorithm(Exception): + def __init__(self, message, reason=None): + super(UnsupportedAlgorithm, self).__init__(message) + self._reason = reason + + +class AlreadyFinalized(Exception): + pass + + +class AlreadyUpdated(Exception): + pass + + +class NotYetFinalized(Exception): + pass + + +class InvalidTag(Exception): + pass + + +class InvalidSignature(Exception): + pass + + +class InternalError(Exception): + pass + + +class InvalidKey(Exception): + pass + + +class InvalidToken(Exception): + pass diff --git a/src/cryptography/fernet.py b/src/cryptography/fernet.py new file mode 100644 index 00000000..4f98feec --- /dev/null +++ b/src/cryptography/fernet.py @@ -0,0 +1,150 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +import base64 +import binascii +import os +import struct +import time + +import six + +from cryptography.exceptions import InvalidSignature +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import hashes, padding +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.primitives.hmac import HMAC + + +class InvalidToken(Exception): + pass + + +_MAX_CLOCK_SKEW = 60 + + +class Fernet(object): + def __init__(self, key, backend=None): + if backend is None: + backend = default_backend() + + key = base64.urlsafe_b64decode(key) + if len(key) != 32: + raise ValueError( + "Fernet key must be 32 url-safe base64-encoded bytes." + ) + + self._signing_key = key[:16] + self._encryption_key = key[16:] + self._backend = backend + + @classmethod + def generate_key(cls): + return base64.urlsafe_b64encode(os.urandom(32)) + + def encrypt(self, data): + current_time = int(time.time()) + iv = os.urandom(16) + return self._encrypt_from_parts(data, current_time, iv) + + def _encrypt_from_parts(self, data, current_time, iv): + if not isinstance(data, bytes): + raise TypeError("data must be bytes.") + + padder = padding.PKCS7(algorithms.AES.block_size).padder() + padded_data = padder.update(data) + padder.finalize() + encryptor = Cipher( + algorithms.AES(self._encryption_key), modes.CBC(iv), self._backend + ).encryptor() + ciphertext = encryptor.update(padded_data) + encryptor.finalize() + + basic_parts = ( + b"\x80" + struct.pack(">Q", current_time) + iv + ciphertext + ) + + h = HMAC(self._signing_key, hashes.SHA256(), backend=self._backend) + h.update(basic_parts) + hmac = h.finalize() + return base64.urlsafe_b64encode(basic_parts + hmac) + + def decrypt(self, token, ttl=None): + if not isinstance(token, bytes): + raise TypeError("token must be bytes.") + + current_time = int(time.time()) + + try: + data = base64.urlsafe_b64decode(token) + except (TypeError, binascii.Error): + raise InvalidToken + + if not data or 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 + + +class MultiFernet(object): + def __init__(self, fernets): + fernets = list(fernets) + if not fernets: + raise ValueError( + "MultiFernet requires at least one Fernet instance" + ) + self._fernets = fernets + + def encrypt(self, msg): + return self._fernets[0].encrypt(msg) + + def decrypt(self, msg, ttl=None): + for f in self._fernets: + try: + return f.decrypt(msg, ttl) + except InvalidToken: + pass + raise InvalidToken diff --git a/src/cryptography/hazmat/__init__.py b/src/cryptography/hazmat/__init__.py new file mode 100644 index 00000000..2f420574 --- /dev/null +++ b/src/cryptography/hazmat/__init__.py @@ -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 diff --git a/src/cryptography/hazmat/backends/__init__.py b/src/cryptography/hazmat/backends/__init__.py new file mode 100644 index 00000000..b0f663fe --- /dev/null +++ b/src/cryptography/hazmat/backends/__init__.py @@ -0,0 +1,46 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +import pkg_resources + +from cryptography.hazmat.backends.multibackend import MultiBackend + + +_available_backends_list = None + + +def _available_backends(): + global _available_backends_list + + if _available_backends_list is None: + _available_backends_list = [ + backend.load(require=False) + for backend in pkg_resources.iter_entry_points( + "cryptography.backends" + ) + ] + + return _available_backends_list + +_default_backend = None + + +def default_backend(): + global _default_backend + + if _default_backend is None: + _default_backend = MultiBackend(_available_backends()) + + return _default_backend diff --git a/src/cryptography/hazmat/backends/commoncrypto/__init__.py b/src/cryptography/hazmat/backends/commoncrypto/__init__.py new file mode 100644 index 00000000..f080394f --- /dev/null +++ b/src/cryptography/hazmat/backends/commoncrypto/__init__.py @@ -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"] diff --git a/src/cryptography/hazmat/backends/commoncrypto/backend.py b/src/cryptography/hazmat/backends/commoncrypto/backend.py new file mode 100644 index 00000000..7bab979f --- /dev/null +++ b/src/cryptography/hazmat/backends/commoncrypto/backend.py @@ -0,0 +1,253 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +from collections import namedtuple + +from cryptography import utils +from cryptography.exceptions import InternalError +from cryptography.hazmat.backends.commoncrypto.ciphers import ( + _CipherContext, _GCMCipherContext +) +from cryptography.hazmat.backends.commoncrypto.hashes import _HashContext +from cryptography.hazmat.backends.commoncrypto.hmac import _HMACContext +from cryptography.hazmat.backends.interfaces import ( + CipherBackend, HMACBackend, HashBackend, PBKDF2HMACBackend +) +from cryptography.hazmat.bindings.commoncrypto.binding import Binding +from cryptography.hazmat.primitives.ciphers.algorithms import ( + AES, ARC4, Blowfish, CAST5, TripleDES +) +from cryptography.hazmat.primitives.ciphers.modes import ( + CBC, CFB, CFB8, CTR, ECB, GCM, OFB +) + + +HashMethods = namedtuple( + "HashMethods", ["ctx", "hash_init", "hash_update", "hash_final"] +) + + +@utils.register_interface(CipherBackend) +@utils.register_interface(HashBackend) +@utils.register_interface(HMACBackend) +@utils.register_interface(PBKDF2HMACBackend) +class Backend(object): + """ + CommonCrypto API wrapper. + """ + name = "commoncrypto" + + def __init__(self): + self._binding = Binding() + self._ffi = self._binding.ffi + self._lib = self._binding.lib + + self._cipher_registry = {} + self._register_default_ciphers() + self._hash_mapping = { + "md5": HashMethods( + "CC_MD5_CTX *", self._lib.CC_MD5_Init, + self._lib.CC_MD5_Update, self._lib.CC_MD5_Final + ), + "sha1": HashMethods( + "CC_SHA1_CTX *", self._lib.CC_SHA1_Init, + self._lib.CC_SHA1_Update, self._lib.CC_SHA1_Final + ), + "sha224": HashMethods( + "CC_SHA256_CTX *", self._lib.CC_SHA224_Init, + self._lib.CC_SHA224_Update, self._lib.CC_SHA224_Final + ), + "sha256": HashMethods( + "CC_SHA256_CTX *", self._lib.CC_SHA256_Init, + self._lib.CC_SHA256_Update, self._lib.CC_SHA256_Final + ), + "sha384": HashMethods( + "CC_SHA512_CTX *", self._lib.CC_SHA384_Init, + self._lib.CC_SHA384_Update, self._lib.CC_SHA384_Final + ), + "sha512": HashMethods( + "CC_SHA512_CTX *", self._lib.CC_SHA512_Init, + self._lib.CC_SHA512_Update, self._lib.CC_SHA512_Final + ), + } + + self._supported_hmac_algorithms = { + "md5": self._lib.kCCHmacAlgMD5, + "sha1": self._lib.kCCHmacAlgSHA1, + "sha224": self._lib.kCCHmacAlgSHA224, + "sha256": self._lib.kCCHmacAlgSHA256, + "sha384": self._lib.kCCHmacAlgSHA384, + "sha512": self._lib.kCCHmacAlgSHA512, + } + + self._supported_pbkdf2_hmac_algorithms = { + "sha1": self._lib.kCCPRFHmacAlgSHA1, + "sha224": self._lib.kCCPRFHmacAlgSHA224, + "sha256": self._lib.kCCPRFHmacAlgSHA256, + "sha384": self._lib.kCCPRFHmacAlgSHA384, + "sha512": self._lib.kCCPRFHmacAlgSHA512, + } + + def hash_supported(self, algorithm): + return algorithm.name in self._hash_mapping + + def hmac_supported(self, algorithm): + return algorithm.name in self._supported_hmac_algorithms + + def create_hash_ctx(self, algorithm): + return _HashContext(self, algorithm) + + def create_hmac_ctx(self, key, algorithm): + return _HMACContext(self, key, algorithm) + + def cipher_supported(self, cipher, mode): + return (type(cipher), type(mode)) in self._cipher_registry + + def create_symmetric_encryption_ctx(self, cipher, mode): + if isinstance(mode, GCM): + return _GCMCipherContext( + self, cipher, mode, self._lib.kCCEncrypt + ) + else: + return _CipherContext(self, cipher, mode, self._lib.kCCEncrypt) + + def create_symmetric_decryption_ctx(self, cipher, mode): + if isinstance(mode, GCM): + return _GCMCipherContext( + self, cipher, mode, self._lib.kCCDecrypt + ) + else: + return _CipherContext(self, cipher, mode, self._lib.kCCDecrypt) + + def pbkdf2_hmac_supported(self, algorithm): + return algorithm.name in self._supported_pbkdf2_hmac_algorithms + + def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations, + key_material): + alg_enum = self._supported_pbkdf2_hmac_algorithms[algorithm.name] + buf = self._ffi.new("char[]", length) + res = self._lib.CCKeyDerivationPBKDF( + self._lib.kCCPBKDF2, + key_material, + len(key_material), + salt, + len(salt), + alg_enum, + iterations, + buf, + length + ) + self._check_cipher_response(res) + + return self._ffi.buffer(buf)[:] + + def _register_cipher_adapter(self, cipher_cls, cipher_const, mode_cls, + mode_const): + if (cipher_cls, mode_cls) in self._cipher_registry: + raise ValueError("Duplicate registration for: {0} {1}.".format( + cipher_cls, mode_cls) + ) + self._cipher_registry[cipher_cls, mode_cls] = (cipher_const, + mode_const) + + def _register_default_ciphers(self): + for mode_cls, mode_const in [ + (CBC, self._lib.kCCModeCBC), + (ECB, self._lib.kCCModeECB), + (CFB, self._lib.kCCModeCFB), + (CFB8, self._lib.kCCModeCFB8), + (OFB, self._lib.kCCModeOFB), + (CTR, self._lib.kCCModeCTR), + (GCM, self._lib.kCCModeGCM), + ]: + self._register_cipher_adapter( + AES, + self._lib.kCCAlgorithmAES128, + mode_cls, + mode_const + ) + for mode_cls, mode_const in [ + (CBC, self._lib.kCCModeCBC), + (ECB, self._lib.kCCModeECB), + (CFB, self._lib.kCCModeCFB), + (CFB8, self._lib.kCCModeCFB8), + (OFB, self._lib.kCCModeOFB), + ]: + self._register_cipher_adapter( + TripleDES, + self._lib.kCCAlgorithm3DES, + mode_cls, + mode_const + ) + for mode_cls, mode_const in [ + (CBC, self._lib.kCCModeCBC), + (ECB, self._lib.kCCModeECB), + (CFB, self._lib.kCCModeCFB), + (OFB, self._lib.kCCModeOFB) + ]: + self._register_cipher_adapter( + Blowfish, + self._lib.kCCAlgorithmBlowfish, + mode_cls, + mode_const + ) + for mode_cls, mode_const in [ + (CBC, self._lib.kCCModeCBC), + (ECB, self._lib.kCCModeECB), + (CFB, self._lib.kCCModeCFB), + (OFB, self._lib.kCCModeOFB), + (CTR, self._lib.kCCModeCTR) + ]: + self._register_cipher_adapter( + CAST5, + self._lib.kCCAlgorithmCAST, + mode_cls, + mode_const + ) + self._register_cipher_adapter( + ARC4, + self._lib.kCCAlgorithmRC4, + type(None), + self._lib.kCCModeRC4 + ) + + def _check_cipher_response(self, response): + if response == self._lib.kCCSuccess: + return + elif response == self._lib.kCCAlignmentError: + # This error is not currently triggered due to a bug filed as + # rdar://15589470 + raise ValueError( + "The length of the provided data is not a multiple of " + "the block length." + ) + else: + raise InternalError( + "The backend returned an unknown error, consider filing a bug." + " Code: {0}.".format(response) + ) + + def _release_cipher_ctx(self, ctx): + """ + Called by the garbage collector and used to safely dereference and + release the context. + """ + if ctx[0] != self._ffi.NULL: + res = self._lib.CCCryptorRelease(ctx[0]) + self._check_cipher_response(res) + ctx[0] = self._ffi.NULL + + +backend = Backend() diff --git a/src/cryptography/hazmat/backends/commoncrypto/ciphers.py b/src/cryptography/hazmat/backends/commoncrypto/ciphers.py new file mode 100644 index 00000000..d94746c6 --- /dev/null +++ b/src/cryptography/hazmat/backends/commoncrypto/ciphers.py @@ -0,0 +1,201 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +from cryptography import utils +from cryptography.exceptions import ( + InvalidTag, UnsupportedAlgorithm, _Reasons +) +from cryptography.hazmat.primitives import constant_time, interfaces +from cryptography.hazmat.primitives.ciphers.modes import ( + CFB, CFB8, CTR, OFB +) + + +@utils.register_interface(interfaces.CipherContext) +class _CipherContext(object): + def __init__(self, backend, cipher, mode, operation): + self._backend = backend + self._cipher = cipher + self._mode = mode + self._operation = operation + # There is a bug in CommonCrypto where block ciphers do not raise + # kCCAlignmentError when finalizing if you supply non-block aligned + # data. To work around this we need to keep track of the block + # alignment ourselves, but only for alg+mode combos that require + # block alignment. OFB, CFB, and CTR make a block cipher algorithm + # into a stream cipher so we don't need to track them (and thus their + # block size is effectively 1 byte just like OpenSSL/CommonCrypto + # treat RC4 and other stream cipher block sizes). + # This bug has been filed as rdar://15589470 + self._bytes_processed = 0 + if (isinstance(cipher, interfaces.BlockCipherAlgorithm) and not + isinstance(mode, (OFB, CFB, CFB8, CTR))): + self._byte_block_size = cipher.block_size // 8 + else: + self._byte_block_size = 1 + + registry = self._backend._cipher_registry + try: + cipher_enum, mode_enum = registry[type(cipher), type(mode)] + except KeyError: + raise UnsupportedAlgorithm( + "cipher {0} in {1} mode is not supported " + "by this backend.".format( + cipher.name, mode.name if mode else mode), + _Reasons.UNSUPPORTED_CIPHER + ) + + ctx = self._backend._ffi.new("CCCryptorRef *") + ctx = self._backend._ffi.gc(ctx, self._backend._release_cipher_ctx) + + if isinstance(mode, interfaces.ModeWithInitializationVector): + iv_nonce = mode.initialization_vector + elif isinstance(mode, interfaces.ModeWithNonce): + iv_nonce = mode.nonce + else: + iv_nonce = self._backend._ffi.NULL + + if isinstance(mode, CTR): + mode_option = self._backend._lib.kCCModeOptionCTR_BE + else: + mode_option = 0 + + res = self._backend._lib.CCCryptorCreateWithMode( + operation, + mode_enum, cipher_enum, + self._backend._lib.ccNoPadding, iv_nonce, + cipher.key, len(cipher.key), + self._backend._ffi.NULL, 0, 0, mode_option, ctx) + self._backend._check_cipher_response(res) + + self._ctx = ctx + + def update(self, data): + # Count bytes processed to handle block alignment. + self._bytes_processed += len(data) + buf = self._backend._ffi.new( + "unsigned char[]", len(data) + self._byte_block_size - 1) + outlen = self._backend._ffi.new("size_t *") + res = self._backend._lib.CCCryptorUpdate( + self._ctx[0], data, len(data), buf, + len(data) + self._byte_block_size - 1, outlen) + self._backend._check_cipher_response(res) + return self._backend._ffi.buffer(buf)[:outlen[0]] + + def finalize(self): + # Raise error if block alignment is wrong. + if self._bytes_processed % self._byte_block_size: + raise ValueError( + "The length of the provided data is not a multiple of " + "the block length." + ) + buf = self._backend._ffi.new("unsigned char[]", self._byte_block_size) + outlen = self._backend._ffi.new("size_t *") + res = self._backend._lib.CCCryptorFinal( + self._ctx[0], buf, len(buf), outlen) + self._backend._check_cipher_response(res) + self._backend._release_cipher_ctx(self._ctx) + return self._backend._ffi.buffer(buf)[:outlen[0]] + + +@utils.register_interface(interfaces.AEADCipherContext) +@utils.register_interface(interfaces.AEADEncryptionContext) +class _GCMCipherContext(object): + def __init__(self, backend, cipher, mode, operation): + self._backend = backend + self._cipher = cipher + self._mode = mode + self._operation = operation + self._tag = None + + registry = self._backend._cipher_registry + try: + cipher_enum, mode_enum = registry[type(cipher), type(mode)] + except KeyError: + raise UnsupportedAlgorithm( + "cipher {0} in {1} mode is not supported " + "by this backend.".format( + cipher.name, mode.name if mode else mode), + _Reasons.UNSUPPORTED_CIPHER + ) + + ctx = self._backend._ffi.new("CCCryptorRef *") + ctx = self._backend._ffi.gc(ctx, self._backend._release_cipher_ctx) + + self._ctx = ctx + + res = self._backend._lib.CCCryptorCreateWithMode( + operation, + mode_enum, cipher_enum, + self._backend._lib.ccNoPadding, + self._backend._ffi.NULL, + cipher.key, len(cipher.key), + self._backend._ffi.NULL, 0, 0, 0, self._ctx) + self._backend._check_cipher_response(res) + + res = self._backend._lib.CCCryptorGCMAddIV( + self._ctx[0], + mode.initialization_vector, + len(mode.initialization_vector) + ) + self._backend._check_cipher_response(res) + # CommonCrypto has a bug where calling update without at least one + # call to authenticate_additional_data will result in null byte output + # for ciphertext. The following empty byte string call prevents the + # issue, which is present in at least 10.8 and 10.9. + # Filed as rdar://18314544 + self.authenticate_additional_data(b"") + + def update(self, data): + buf = self._backend._ffi.new("unsigned char[]", len(data)) + args = (self._ctx[0], data, len(data), buf) + if self._operation == self._backend._lib.kCCEncrypt: + res = self._backend._lib.CCCryptorGCMEncrypt(*args) + else: + res = self._backend._lib.CCCryptorGCMDecrypt(*args) + + self._backend._check_cipher_response(res) + return self._backend._ffi.buffer(buf)[:] + + def finalize(self): + # CommonCrypto has a yet another bug where you must make at least one + # call to update. If you pass just AAD and call finalize without a call + # to update you'll get null bytes for tag. The following update call + # prevents this issue, which is present in at least 10.8 and 10.9. + # Filed as rdar://18314580 + self.update(b"") + tag_size = self._cipher.block_size // 8 + tag_buf = self._backend._ffi.new("unsigned char[]", tag_size) + tag_len = self._backend._ffi.new("size_t *", tag_size) + res = self._backend._lib.CCCryptorGCMFinal( + self._ctx[0], tag_buf, tag_len + ) + self._backend._check_cipher_response(res) + self._backend._release_cipher_ctx(self._ctx) + self._tag = self._backend._ffi.buffer(tag_buf)[:] + if (self._operation == self._backend._lib.kCCDecrypt and + not constant_time.bytes_eq( + self._tag[:len(self._mode.tag)], self._mode.tag + )): + raise InvalidTag + return b"" + + def authenticate_additional_data(self, data): + res = self._backend._lib.CCCryptorGCMAddAAD( + self._ctx[0], data, len(data) + ) + self._backend._check_cipher_response(res) + + tag = utils.read_only_property("_tag") diff --git a/src/cryptography/hazmat/backends/commoncrypto/hashes.py b/src/cryptography/hazmat/backends/commoncrypto/hashes.py new file mode 100644 index 00000000..217f4e8c --- /dev/null +++ b/src/cryptography/hazmat/backends/commoncrypto/hashes.py @@ -0,0 +1,64 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +from cryptography import utils +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.primitives import interfaces + + +@utils.register_interface(interfaces.HashContext) +class _HashContext(object): + def __init__(self, backend, algorithm, ctx=None): + self._algorithm = algorithm + self._backend = backend + + if ctx is None: + try: + methods = self._backend._hash_mapping[self.algorithm.name] + except KeyError: + raise UnsupportedAlgorithm( + "{0} is not a supported hash on this backend.".format( + algorithm.name), + _Reasons.UNSUPPORTED_HASH + ) + ctx = self._backend._ffi.new(methods.ctx) + res = methods.hash_init(ctx) + assert res == 1 + + self._ctx = ctx + + algorithm = utils.read_only_property("_algorithm") + + 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)[:] diff --git a/src/cryptography/hazmat/backends/commoncrypto/hmac.py b/src/cryptography/hazmat/backends/commoncrypto/hmac.py new file mode 100644 index 00000000..ee7e3abb --- /dev/null +++ b/src/cryptography/hazmat/backends/commoncrypto/hmac.py @@ -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 + +from cryptography import utils +from cryptography.exceptions import ( + InvalidSignature, UnsupportedAlgorithm, _Reasons +) +from cryptography.hazmat.primitives import constant_time, interfaces + + +@utils.register_interface(interfaces.MACContext) +@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 + + algorithm = utils.read_only_property("_algorithm") + + 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)[:] + + def verify(self, signature): + digest = self.finalize() + if not constant_time.bytes_eq(digest, signature): + raise InvalidSignature("Signature did not match digest.") diff --git a/src/cryptography/hazmat/backends/interfaces.py b/src/cryptography/hazmat/backends/interfaces.py new file mode 100644 index 00000000..ecb5bf48 --- /dev/null +++ b/src/cryptography/hazmat/backends/interfaces.py @@ -0,0 +1,261 @@ +# 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 MACContext for calculating a message authentication code. + """ + + +@six.add_metaclass(abc.ABCMeta) +class CMACBackend(object): + @abc.abstractmethod + def cmac_algorithm_supported(self, algorithm): + """ + Returns True if the block cipher is supported for CMAC by this backend + """ + + @abc.abstractmethod + def create_cmac_ctx(self, algorithm): + """ + Create a MACContext 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 rsa_padding_supported(self, padding): + """ + Returns True if the backend supports the given padding options. + """ + + @abc.abstractmethod + def generate_rsa_parameters_supported(self, public_exponent, key_size): + """ + Returns True if the backend supports the given parameters for key + generation. + """ + + @abc.abstractmethod + def load_rsa_private_numbers(self, numbers): + """ + Returns an RSAPrivateKey provider. + """ + + @abc.abstractmethod + def load_rsa_public_numbers(self, numbers): + """ + Returns an RSAPublicKey provider. + """ + + +@six.add_metaclass(abc.ABCMeta) +class DSABackend(object): + @abc.abstractmethod + def generate_dsa_parameters(self, key_size): + """ + Generate a DSAParameters instance with a modulus of key_size bits. + """ + + @abc.abstractmethod + def generate_dsa_private_key(self, parameters): + """ + Generate a DSAPrivateKey instance with parameters as a DSAParameters + object. + """ + + @abc.abstractmethod + def generate_dsa_private_key_and_parameters(self, key_size): + """ + Generate a DSAPrivateKey instance using key size only. + """ + + @abc.abstractmethod + def dsa_hash_supported(self, algorithm): + """ + Return True if the hash algorithm is supported by the backend for DSA. + """ + + @abc.abstractmethod + def dsa_parameters_supported(self, p, q, g): + """ + Return True if the parameters are supported by the backend for DSA. + """ + + @abc.abstractmethod + def load_dsa_private_numbers(self, numbers): + """ + Returns a DSAPrivateKey provider. + """ + + @abc.abstractmethod + def load_dsa_public_numbers(self, numbers): + """ + Returns a DSAPublicKey provider. + """ + + @abc.abstractmethod + def load_dsa_parameter_numbers(self, numbers): + """ + Returns a DSAParameters provider. + """ + + +@six.add_metaclass(abc.ABCMeta) +class EllipticCurveBackend(object): + @abc.abstractmethod + def elliptic_curve_signature_algorithm_supported( + self, signature_algorithm, curve + ): + """ + Returns True if the backend supports the named elliptic curve with the + specified signature algorithm. + """ + + @abc.abstractmethod + def elliptic_curve_supported(self, curve): + """ + Returns True if the backend supports the named elliptic curve. + """ + + @abc.abstractmethod + def generate_elliptic_curve_private_key(self, curve): + """ + Return an object conforming to the EllipticCurvePrivateKey interface. + """ + + @abc.abstractmethod + def load_elliptic_curve_public_numbers(self, numbers): + """ + Return an EllipticCurvePublicKey provider using the given numbers. + """ + + @abc.abstractmethod + def load_elliptic_curve_private_numbers(self, numbers): + """ + Return an EllipticCurvePublicKey provider using the given numbers. + """ + + +@six.add_metaclass(abc.ABCMeta) +class PEMSerializationBackend(object): + @abc.abstractmethod + def load_pem_private_key(self, data, password): + """ + Loads a private key from PEM encoded data, using the provided password + if the data is encrypted. + """ + + @abc.abstractmethod + def load_pem_public_key(self, data): + """ + Loads a public key from PEM encoded data. + """ + + +@six.add_metaclass(abc.ABCMeta) +class TraditionalOpenSSLSerializationBackend(object): + @abc.abstractmethod + def load_traditional_openssl_pem_private_key(self, data, password): + """ + Load a private key from PEM encoded data, using password if the data + is encrypted. + """ + + +@six.add_metaclass(abc.ABCMeta) +class PKCS8SerializationBackend(object): + @abc.abstractmethod + def load_pkcs8_pem_private_key(self, data, password): + """ + Load a private key from PKCS8 encoded data, using password if the data + is encrypted. + """ diff --git a/src/cryptography/hazmat/backends/multibackend.py b/src/cryptography/hazmat/backends/multibackend.py new file mode 100644 index 00000000..c62b790c --- /dev/null +++ b/src/cryptography/hazmat/backends/multibackend.py @@ -0,0 +1,358 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +import warnings + +from cryptography import utils +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.backends.interfaces import ( + CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend, + HashBackend, PBKDF2HMACBackend, PEMSerializationBackend, + PKCS8SerializationBackend, RSABackend, + TraditionalOpenSSLSerializationBackend +) + + +@utils.register_interface(CMACBackend) +@utils.register_interface(CipherBackend) +@utils.register_interface(HashBackend) +@utils.register_interface(HMACBackend) +@utils.register_interface(PBKDF2HMACBackend) +@utils.register_interface(PKCS8SerializationBackend) +@utils.register_interface(RSABackend) +@utils.register_interface(TraditionalOpenSSLSerializationBackend) +@utils.register_interface(DSABackend) +@utils.register_interface(EllipticCurveBackend) +@utils.register_interface(PEMSerializationBackend) +class MultiBackend(object): + name = "multibackend" + + def __init__(self, backends): + self._backends = backends + + def _filtered_backends(self, interface): + for b in self._backends: + if isinstance(b, interface): + yield b + + def cipher_supported(self, cipher, mode): + return any( + b.cipher_supported(cipher, mode) + for b in self._filtered_backends(CipherBackend) + ) + + def create_symmetric_encryption_ctx(self, cipher, mode): + for b in self._filtered_backends(CipherBackend): + try: + return b.create_symmetric_encryption_ctx(cipher, mode) + except UnsupportedAlgorithm: + pass + 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 + ) + + def create_symmetric_decryption_ctx(self, cipher, mode): + for b in self._filtered_backends(CipherBackend): + try: + return b.create_symmetric_decryption_ctx(cipher, mode) + except UnsupportedAlgorithm: + pass + 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 + ) + + def hash_supported(self, algorithm): + return any( + b.hash_supported(algorithm) + for b in self._filtered_backends(HashBackend) + ) + + def create_hash_ctx(self, algorithm): + for b in self._filtered_backends(HashBackend): + try: + return b.create_hash_ctx(algorithm) + except UnsupportedAlgorithm: + pass + raise UnsupportedAlgorithm( + "{0} is not a supported hash on this backend.".format( + algorithm.name), + _Reasons.UNSUPPORTED_HASH + ) + + def hmac_supported(self, algorithm): + return any( + b.hmac_supported(algorithm) + for b in self._filtered_backends(HMACBackend) + ) + + def create_hmac_ctx(self, key, algorithm): + for b in self._filtered_backends(HMACBackend): + try: + return b.create_hmac_ctx(key, algorithm) + except UnsupportedAlgorithm: + pass + raise UnsupportedAlgorithm( + "{0} is not a supported hash on this backend.".format( + algorithm.name), + _Reasons.UNSUPPORTED_HASH + ) + + def pbkdf2_hmac_supported(self, algorithm): + return any( + b.pbkdf2_hmac_supported(algorithm) + for b in self._filtered_backends(PBKDF2HMACBackend) + ) + + def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations, + key_material): + for b in self._filtered_backends(PBKDF2HMACBackend): + try: + return b.derive_pbkdf2_hmac( + algorithm, length, salt, iterations, key_material + ) + except UnsupportedAlgorithm: + pass + raise UnsupportedAlgorithm( + "{0} is not a supported hash on this backend.".format( + algorithm.name), + _Reasons.UNSUPPORTED_HASH + ) + + def generate_rsa_private_key(self, public_exponent, key_size): + for b in self._filtered_backends(RSABackend): + return b.generate_rsa_private_key(public_exponent, key_size) + raise UnsupportedAlgorithm("RSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def generate_rsa_parameters_supported(self, public_exponent, key_size): + for b in self._filtered_backends(RSABackend): + return b.generate_rsa_parameters_supported( + public_exponent, key_size + ) + raise UnsupportedAlgorithm("RSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def rsa_padding_supported(self, padding): + for b in self._filtered_backends(RSABackend): + return b.rsa_padding_supported(padding) + raise UnsupportedAlgorithm("RSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def load_rsa_private_numbers(self, numbers): + for b in self._filtered_backends(RSABackend): + return b.load_rsa_private_numbers(numbers) + + raise UnsupportedAlgorithm("RSA is not supported by the backend", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def load_rsa_public_numbers(self, numbers): + for b in self._filtered_backends(RSABackend): + return b.load_rsa_public_numbers(numbers) + + raise UnsupportedAlgorithm("RSA is not supported by the backend", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def generate_dsa_parameters(self, key_size): + for b in self._filtered_backends(DSABackend): + return b.generate_dsa_parameters(key_size) + raise UnsupportedAlgorithm("DSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def generate_dsa_private_key(self, parameters): + for b in self._filtered_backends(DSABackend): + return b.generate_dsa_private_key(parameters) + raise UnsupportedAlgorithm("DSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def generate_dsa_private_key_and_parameters(self, key_size): + for b in self._filtered_backends(DSABackend): + return b.generate_dsa_private_key_and_parameters(key_size) + raise UnsupportedAlgorithm("DSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def dsa_hash_supported(self, algorithm): + for b in self._filtered_backends(DSABackend): + return b.dsa_hash_supported(algorithm) + raise UnsupportedAlgorithm("DSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def dsa_parameters_supported(self, p, q, g): + for b in self._filtered_backends(DSABackend): + return b.dsa_parameters_supported(p, q, g) + raise UnsupportedAlgorithm("DSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def load_dsa_public_numbers(self, numbers): + for b in self._filtered_backends(DSABackend): + return b.load_dsa_public_numbers(numbers) + raise UnsupportedAlgorithm("DSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def load_dsa_private_numbers(self, numbers): + for b in self._filtered_backends(DSABackend): + return b.load_dsa_private_numbers(numbers) + raise UnsupportedAlgorithm("DSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def load_dsa_parameter_numbers(self, numbers): + for b in self._filtered_backends(DSABackend): + return b.load_dsa_parameter_numbers(numbers) + raise UnsupportedAlgorithm("DSA is not supported by the backend.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def cmac_algorithm_supported(self, algorithm): + return any( + b.cmac_algorithm_supported(algorithm) + for b in self._filtered_backends(CMACBackend) + ) + + def create_cmac_ctx(self, algorithm): + for b in self._filtered_backends(CMACBackend): + try: + return b.create_cmac_ctx(algorithm) + except UnsupportedAlgorithm: + pass + raise UnsupportedAlgorithm("This backend does not support CMAC.", + _Reasons.UNSUPPORTED_CIPHER) + + def elliptic_curve_supported(self, curve): + return any( + b.elliptic_curve_supported(curve) + for b in self._filtered_backends(EllipticCurveBackend) + ) + + def elliptic_curve_signature_algorithm_supported( + self, signature_algorithm, curve + ): + return any( + b.elliptic_curve_signature_algorithm_supported( + signature_algorithm, curve + ) + for b in self._filtered_backends(EllipticCurveBackend) + ) + + def generate_elliptic_curve_private_key(self, curve): + for b in self._filtered_backends(EllipticCurveBackend): + try: + return b.generate_elliptic_curve_private_key(curve) + except UnsupportedAlgorithm: + continue + + raise UnsupportedAlgorithm( + "This backend does not support this elliptic curve.", + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE + ) + + def elliptic_curve_private_key_from_numbers(self, numbers): + warnings.warn( + "elliptic_curve_private_key_from_numbers is deprecated and will " + "be removed in a future version.", + utils.DeprecatedIn06, + stacklevel=2 + ) + for b in self._filtered_backends(EllipticCurveBackend): + try: + return b.elliptic_curve_private_key_from_numbers(numbers) + except UnsupportedAlgorithm: + continue + + raise UnsupportedAlgorithm( + "This backend does not support this elliptic curve.", + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE + ) + + def load_elliptic_curve_private_numbers(self, numbers): + for b in self._filtered_backends(EllipticCurveBackend): + try: + return b.load_elliptic_curve_private_numbers(numbers) + except UnsupportedAlgorithm: + continue + + raise UnsupportedAlgorithm( + "This backend does not support this elliptic curve.", + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE + ) + + def elliptic_curve_public_key_from_numbers(self, numbers): + warnings.warn( + "elliptic_curve_public_key_from_numbers is deprecated and will " + "be removed in a future version.", + utils.DeprecatedIn06, + stacklevel=2 + ) + for b in self._filtered_backends(EllipticCurveBackend): + try: + return b.elliptic_curve_public_key_from_numbers(numbers) + except UnsupportedAlgorithm: + continue + + raise UnsupportedAlgorithm( + "This backend does not support this elliptic curve.", + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE + ) + + def load_elliptic_curve_public_numbers(self, numbers): + for b in self._filtered_backends(EllipticCurveBackend): + try: + return b.load_elliptic_curve_public_numbers(numbers) + except UnsupportedAlgorithm: + continue + + raise UnsupportedAlgorithm( + "This backend does not support this elliptic curve.", + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE + ) + + def load_pem_private_key(self, data, password): + for b in self._filtered_backends(PEMSerializationBackend): + return b.load_pem_private_key(data, password) + + raise UnsupportedAlgorithm( + "This backend does not support this key serialization.", + _Reasons.UNSUPPORTED_SERIALIZATION + ) + + def load_pem_public_key(self, data): + for b in self._filtered_backends(PEMSerializationBackend): + return b.load_pem_public_key(data) + + raise UnsupportedAlgorithm( + "This backend does not support this key serialization.", + _Reasons.UNSUPPORTED_SERIALIZATION + ) + + def load_pkcs8_pem_private_key(self, data, password): + for b in self._filtered_backends(PKCS8SerializationBackend): + return b.load_pkcs8_pem_private_key(data, password) + + raise UnsupportedAlgorithm( + "This backend does not support this key serialization.", + _Reasons.UNSUPPORTED_SERIALIZATION + ) + + def load_traditional_openssl_pem_private_key(self, data, password): + for b in self._filtered_backends( + TraditionalOpenSSLSerializationBackend + ): + return b.load_traditional_openssl_pem_private_key(data, password) + + raise UnsupportedAlgorithm( + "This backend does not support this key serialization.", + _Reasons.UNSUPPORTED_SERIALIZATION + ) diff --git a/src/cryptography/hazmat/backends/openssl/__init__.py b/src/cryptography/hazmat/backends/openssl/__init__.py new file mode 100644 index 00000000..25885e18 --- /dev/null +++ b/src/cryptography/hazmat/backends/openssl/__init__.py @@ -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"] diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py new file mode 100644 index 00000000..bb1a3f3d --- /dev/null +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -0,0 +1,1036 @@ +# 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 collections +import itertools +import warnings +from contextlib import contextmanager + +import six + +from cryptography import utils +from cryptography.exceptions import ( + InternalError, UnsupportedAlgorithm, _Reasons +) +from cryptography.hazmat.backends.interfaces import ( + CMACBackend, CipherBackend, DSABackend, EllipticCurveBackend, HMACBackend, + HashBackend, PBKDF2HMACBackend, PEMSerializationBackend, + PKCS8SerializationBackend, RSABackend, + TraditionalOpenSSLSerializationBackend +) +from cryptography.hazmat.backends.openssl.ciphers import ( + _AESCTRCipherContext, _CipherContext +) +from cryptography.hazmat.backends.openssl.cmac import _CMACContext +from cryptography.hazmat.backends.openssl.dsa import ( + _DSAParameters, _DSAPrivateKey, _DSAPublicKey +) +from cryptography.hazmat.backends.openssl.ec import ( + _EllipticCurvePrivateKey, _EllipticCurvePublicKey +) +from cryptography.hazmat.backends.openssl.hashes import _HashContext +from cryptography.hazmat.backends.openssl.hmac import _HMACContext +from cryptography.hazmat.backends.openssl.rsa import ( + _RSAPrivateKey, _RSAPublicKey +) +from cryptography.hazmat.bindings.openssl.binding import Binding +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa +from cryptography.hazmat.primitives.asymmetric.padding import ( + MGF1, OAEP, PKCS1v15, PSS +) +from cryptography.hazmat.primitives.ciphers.algorithms import ( + AES, ARC4, Blowfish, CAST5, Camellia, IDEA, SEED, TripleDES +) +from cryptography.hazmat.primitives.ciphers.modes import ( + CBC, CFB, CFB8, CTR, ECB, GCM, OFB +) + + +_MemoryBIO = collections.namedtuple("_MemoryBIO", ["bio", "char_ptr"]) +_OpenSSLError = collections.namedtuple("_OpenSSLError", + ["code", "lib", "func", "reason"]) + + +@utils.register_interface(CipherBackend) +@utils.register_interface(CMACBackend) +@utils.register_interface(DSABackend) +@utils.register_interface(EllipticCurveBackend) +@utils.register_interface(HashBackend) +@utils.register_interface(HMACBackend) +@utils.register_interface(PBKDF2HMACBackend) +@utils.register_interface(PKCS8SerializationBackend) +@utils.register_interface(RSABackend) +@utils.register_interface(TraditionalOpenSSLSerializationBackend) +@utils.register_interface(PEMSerializationBackend) +class Backend(object): + """ + OpenSSL API binding interfaces. + """ + name = "openssl" + + def __init__(self): + self._binding = Binding() + self._ffi = self._binding.ffi + self._lib = self._binding.lib + + self._binding.init_static_locks() + + # adds all ciphers/digests for EVP + self._lib.OpenSSL_add_all_algorithms() + # registers available SSL/TLS ciphers and digests + self._lib.SSL_library_init() + # loads error strings for libcrypto and libssl functions + self._lib.SSL_load_error_strings() + + self._cipher_registry = {} + self._register_default_ciphers() + self.activate_osrandom_engine() + + def activate_builtin_random(self): + # Obtain a new structural reference. + e = self._lib.ENGINE_get_default_RAND() + if e != self._ffi.NULL: + self._lib.ENGINE_unregister_RAND(e) + # Reset the RNG to use the new engine. + self._lib.RAND_cleanup() + # decrement the structural reference from get_default_RAND + res = self._lib.ENGINE_finish(e) + assert res == 1 + + def activate_osrandom_engine(self): + # Unregister and free the current engine. + self.activate_builtin_random() + # Fetches an engine by id and returns it. This creates a structural + # reference. + e = self._lib.ENGINE_by_id(self._lib.Cryptography_osrandom_engine_id) + assert e != self._ffi.NULL + # Initialize the engine for use. This adds a functional reference. + res = self._lib.ENGINE_init(e) + assert res == 1 + # Set the engine as the default RAND provider. + res = self._lib.ENGINE_set_default_RAND(e) + assert res == 1 + # Decrement the structural ref incremented by ENGINE_by_id. + res = self._lib.ENGINE_free(e) + assert res == 1 + # Decrement the functional ref incremented by ENGINE_init. + res = self._lib.ENGINE_finish(e) + assert res == 1 + # Reset the RNG to use the new engine. + self._lib.RAND_cleanup() + + def openssl_version_text(self): + """ + Friendly string name of the loaded OpenSSL library. This is not + necessarily the same version as it was compiled against. + + Example: OpenSSL 1.0.1e 11 Feb 2013 + """ + return self._ffi.string( + self._lib.SSLeay_version(self._lib.SSLEAY_VERSION) + ).decode("ascii") + + def create_hmac_ctx(self, key, algorithm): + return _HMACContext(self, key, algorithm) + + def hash_supported(self, algorithm): + digest = self._lib.EVP_get_digestbyname(algorithm.name.encode("ascii")) + return digest != self._ffi.NULL + + def hmac_supported(self, algorithm): + return self.hash_supported(algorithm) + + def create_hash_ctx(self, algorithm): + return _HashContext(self, algorithm) + + def cipher_supported(self, cipher, mode): + if self._evp_cipher_supported(cipher, mode): + return True + elif isinstance(mode, CTR) and isinstance(cipher, AES): + return True + else: + return False + + def _evp_cipher_supported(self, cipher, mode): + try: + adapter = self._cipher_registry[type(cipher), type(mode)] + except KeyError: + return False + evp_cipher = adapter(self, cipher, mode) + return self._ffi.NULL != evp_cipher + + def register_cipher_adapter(self, cipher_cls, mode_cls, adapter): + 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] = adapter + + def _register_default_ciphers(self): + for mode_cls in [CBC, CTR, ECB, OFB, CFB, CFB8]: + self.register_cipher_adapter( + AES, + mode_cls, + GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}") + ) + for mode_cls in [CBC, CTR, ECB, OFB, CFB]: + self.register_cipher_adapter( + Camellia, + mode_cls, + GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}") + ) + for mode_cls in [CBC, CFB, CFB8, OFB]: + self.register_cipher_adapter( + TripleDES, + mode_cls, + GetCipherByName("des-ede3-{mode.name}") + ) + self.register_cipher_adapter( + TripleDES, + ECB, + GetCipherByName("des-ede3") + ) + for mode_cls in [CBC, CFB, OFB, ECB]: + self.register_cipher_adapter( + Blowfish, + mode_cls, + GetCipherByName("bf-{mode.name}") + ) + for mode_cls in [CBC, CFB, OFB, ECB]: + self.register_cipher_adapter( + SEED, + mode_cls, + GetCipherByName("seed-{mode.name}") + ) + for cipher_cls, mode_cls in itertools.product( + [CAST5, IDEA], + [CBC, OFB, CFB, ECB], + ): + self.register_cipher_adapter( + cipher_cls, + mode_cls, + GetCipherByName("{cipher.name}-{mode.name}") + ) + self.register_cipher_adapter( + ARC4, + type(None), + GetCipherByName("rc4") + ) + self.register_cipher_adapter( + AES, + GCM, + GetCipherByName("{cipher.name}-{cipher.key_size}-{mode.name}") + ) + + def create_symmetric_encryption_ctx(self, cipher, mode): + if (isinstance(mode, CTR) and isinstance(cipher, AES) + and not self._evp_cipher_supported(cipher, mode)): + # This is needed to provide support for AES CTR mode in OpenSSL + # 0.9.8. It can be removed when we drop 0.9.8 support (RHEL 5 + # extended life ends 2020). + return _AESCTRCipherContext(self, cipher, mode) + else: + return _CipherContext(self, cipher, mode, _CipherContext._ENCRYPT) + + def create_symmetric_decryption_ctx(self, cipher, mode): + if (isinstance(mode, CTR) and isinstance(cipher, AES) + and not self._evp_cipher_supported(cipher, mode)): + # This is needed to provide support for AES CTR mode in OpenSSL + # 0.9.8. It can be removed when we drop 0.9.8 support (RHEL 5 + # extended life ends 2020). + return _AESCTRCipherContext(self, cipher, mode) + else: + return _CipherContext(self, cipher, mode, _CipherContext._DECRYPT) + + def pbkdf2_hmac_supported(self, algorithm): + if self._lib.Cryptography_HAS_PBKDF2_HMAC: + return self.hmac_supported(algorithm) + else: + # OpenSSL < 1.0.0 has an explicit PBKDF2-HMAC-SHA1 function, + # so if the PBKDF2_HMAC function is missing we only support + # SHA1 via PBKDF2_HMAC_SHA1. + return isinstance(algorithm, hashes.SHA1) + + def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations, + key_material): + buf = self._ffi.new("char[]", length) + if self._lib.Cryptography_HAS_PBKDF2_HMAC: + evp_md = self._lib.EVP_get_digestbyname( + algorithm.name.encode("ascii")) + assert evp_md != self._ffi.NULL + res = self._lib.PKCS5_PBKDF2_HMAC( + key_material, + len(key_material), + salt, + len(salt), + iterations, + evp_md, + length, + buf + ) + assert res == 1 + else: + if not isinstance(algorithm, hashes.SHA1): + raise UnsupportedAlgorithm( + "This version of OpenSSL only supports PBKDF2HMAC with " + "SHA1.", + _Reasons.UNSUPPORTED_HASH + ) + res = self._lib.PKCS5_PBKDF2_HMAC_SHA1( + key_material, + len(key_material), + salt, + len(salt), + iterations, + length, + buf + ) + assert res == 1 + + return self._ffi.buffer(buf)[:] + + def _err_string(self, code): + err_buf = self._ffi.new("char[]", 256) + self._lib.ERR_error_string_n(code, err_buf, 256) + return self._ffi.string(err_buf, 256)[:] + + def _consume_errors(self): + errors = [] + while True: + code = self._lib.ERR_get_error() + if code == 0: + break + + lib = self._lib.ERR_GET_LIB(code) + func = self._lib.ERR_GET_FUNC(code) + reason = self._lib.ERR_GET_REASON(code) + + errors.append(_OpenSSLError(code, lib, func, reason)) + return errors + + def _unknown_error(self, error): + return InternalError( + "Unknown error code {0} from OpenSSL, " + "you should probably file a bug. {1}.".format( + error.code, self._err_string(error.code) + ) + ) + + def _bn_to_int(self, bn): + if six.PY3: + # Python 3 has constant time from_bytes, so use that. + + bn_num_bytes = (self._lib.BN_num_bits(bn) + 7) // 8 + bin_ptr = self._ffi.new("unsigned char[]", bn_num_bytes) + bin_len = self._lib.BN_bn2bin(bn, bin_ptr) + assert bin_len > 0 + assert bin_ptr != self._ffi.NULL + return int.from_bytes(self._ffi.buffer(bin_ptr)[:bin_len], "big") + + else: + # Under Python 2 the best we can do is hex() + + hex_cdata = self._lib.BN_bn2hex(bn) + assert hex_cdata != self._ffi.NULL + hex_str = self._ffi.string(hex_cdata) + self._lib.OPENSSL_free(hex_cdata) + return int(hex_str, 16) + + def _int_to_bn(self, num, bn=None): + """ + Converts a python integer to a BIGNUM. The returned BIGNUM will not + be garbage collected (to support adding them to structs that take + ownership of the object). Be sure to register it for GC if it will + be discarded after use. + """ + + if bn is None: + bn = self._ffi.NULL + + if six.PY3: + # Python 3 has constant time to_bytes, so use that. + + binary = num.to_bytes(int(num.bit_length() / 8.0 + 1), "big") + bn_ptr = self._lib.BN_bin2bn(binary, len(binary), bn) + assert bn_ptr != self._ffi.NULL + return bn_ptr + + else: + # Under Python 2 the best we can do is hex() + + hex_num = hex(num).rstrip("L").lstrip("0x").encode("ascii") or b"0" + bn_ptr = self._ffi.new("BIGNUM **") + bn_ptr[0] = bn + res = self._lib.BN_hex2bn(bn_ptr, hex_num) + assert res != 0 + assert bn_ptr[0] != self._ffi.NULL + return bn_ptr[0] + + def generate_rsa_private_key(self, public_exponent, key_size): + rsa._verify_rsa_parameters(public_exponent, key_size) + + rsa_cdata = self._lib.RSA_new() + assert rsa_cdata != self._ffi.NULL + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + + bn = self._int_to_bn(public_exponent) + bn = self._ffi.gc(bn, self._lib.BN_free) + + res = self._lib.RSA_generate_key_ex( + rsa_cdata, key_size, bn, self._ffi.NULL + ) + assert res == 1 + + return _RSAPrivateKey(self, rsa_cdata) + + def generate_rsa_parameters_supported(self, public_exponent, key_size): + return (public_exponent >= 3 and public_exponent & 1 != 0 and + key_size >= 512) + + def load_rsa_private_numbers(self, numbers): + rsa._check_private_key_components( + numbers.p, + numbers.q, + numbers.d, + numbers.dmp1, + numbers.dmq1, + numbers.iqmp, + numbers.public_numbers.e, + numbers.public_numbers.n + ) + rsa_cdata = self._lib.RSA_new() + assert rsa_cdata != self._ffi.NULL + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + rsa_cdata.p = self._int_to_bn(numbers.p) + rsa_cdata.q = self._int_to_bn(numbers.q) + rsa_cdata.d = self._int_to_bn(numbers.d) + rsa_cdata.dmp1 = self._int_to_bn(numbers.dmp1) + rsa_cdata.dmq1 = self._int_to_bn(numbers.dmq1) + rsa_cdata.iqmp = self._int_to_bn(numbers.iqmp) + rsa_cdata.e = self._int_to_bn(numbers.public_numbers.e) + rsa_cdata.n = self._int_to_bn(numbers.public_numbers.n) + res = self._lib.RSA_blinding_on(rsa_cdata, self._ffi.NULL) + assert res == 1 + + return _RSAPrivateKey(self, rsa_cdata) + + def load_rsa_public_numbers(self, numbers): + rsa._check_public_key_components(numbers.e, numbers.n) + rsa_cdata = self._lib.RSA_new() + assert rsa_cdata != self._ffi.NULL + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + rsa_cdata.e = self._int_to_bn(numbers.e) + rsa_cdata.n = self._int_to_bn(numbers.n) + res = self._lib.RSA_blinding_on(rsa_cdata, self._ffi.NULL) + assert res == 1 + + return _RSAPublicKey(self, rsa_cdata) + + def _bytes_to_bio(self, data): + """ + Return a _MemoryBIO namedtuple of (BIO, char*). + + The char* is the storage for the BIO and it must stay alive until the + BIO is finished with. + """ + data_char_p = self._ffi.new("char[]", data) + bio = self._lib.BIO_new_mem_buf( + data_char_p, len(data) + ) + assert bio != self._ffi.NULL + + return _MemoryBIO(self._ffi.gc(bio, self._lib.BIO_free), data_char_p) + + def _evp_pkey_to_private_key(self, evp_pkey): + """ + Return the appropriate type of PrivateKey given an evp_pkey cdata + pointer. + """ + + type = evp_pkey.type + + if type == self._lib.EVP_PKEY_RSA: + rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) + assert rsa_cdata != self._ffi.NULL + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + return _RSAPrivateKey(self, rsa_cdata) + elif type == self._lib.EVP_PKEY_DSA: + dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey) + assert dsa_cdata != self._ffi.NULL + dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) + return _DSAPrivateKey(self, dsa_cdata) + elif (self._lib.Cryptography_HAS_EC == 1 and + type == self._lib.EVP_PKEY_EC): + ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) + assert ec_cdata != self._ffi.NULL + ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) + return _EllipticCurvePrivateKey(self, ec_cdata) + else: + raise UnsupportedAlgorithm("Unsupported key type.") + + def _evp_pkey_to_public_key(self, evp_pkey): + """ + Return the appropriate type of PublicKey given an evp_pkey cdata + pointer. + """ + + type = evp_pkey.type + + if type == self._lib.EVP_PKEY_RSA: + rsa_cdata = self._lib.EVP_PKEY_get1_RSA(evp_pkey) + assert rsa_cdata != self._ffi.NULL + rsa_cdata = self._ffi.gc(rsa_cdata, self._lib.RSA_free) + return _RSAPublicKey(self, rsa_cdata) + elif type == self._lib.EVP_PKEY_DSA: + dsa_cdata = self._lib.EVP_PKEY_get1_DSA(evp_pkey) + assert dsa_cdata != self._ffi.NULL + dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) + return _DSAPublicKey(self, dsa_cdata) + elif (self._lib.Cryptography_HAS_EC == 1 and + type == self._lib.EVP_PKEY_EC): + ec_cdata = self._lib.EVP_PKEY_get1_EC_KEY(evp_pkey) + assert ec_cdata != self._ffi.NULL + ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) + return _EllipticCurvePublicKey(self, ec_cdata) + else: + raise UnsupportedAlgorithm("Unsupported key type.") + + def _pem_password_cb(self, password): + """ + Generate a pem_password_cb function pointer that copied the password to + OpenSSL as required and returns the number of bytes copied. + + typedef int pem_password_cb(char *buf, int size, + int rwflag, void *userdata); + + Useful for decrypting PKCS8 files and so on. + + Returns a tuple of (cdata function pointer, callback function). + """ + + def pem_password_cb(buf, size, writing, userdata): + pem_password_cb.called += 1 + + if not password: + pem_password_cb.exception = TypeError( + "Password was not given but private key is encrypted." + ) + return 0 + elif len(password) < size: + pw_buf = self._ffi.buffer(buf, size) + pw_buf[:len(password)] = password + return len(password) + else: + pem_password_cb.exception = ValueError( + "Passwords longer than {0} bytes are not supported " + "by this backend.".format(size - 1) + ) + return 0 + + pem_password_cb.called = 0 + pem_password_cb.exception = None + + return ( + self._ffi.callback("int (char *, int, int, void *)", + pem_password_cb), + pem_password_cb + ) + + def _mgf1_hash_supported(self, algorithm): + if self._lib.Cryptography_HAS_MGF1_MD: + return self.hash_supported(algorithm) + else: + return isinstance(algorithm, hashes.SHA1) + + def rsa_padding_supported(self, padding): + if isinstance(padding, PKCS1v15): + return True + elif isinstance(padding, PSS) and isinstance(padding._mgf, MGF1): + return self._mgf1_hash_supported(padding._mgf._algorithm) + elif isinstance(padding, OAEP) and isinstance(padding._mgf, MGF1): + return isinstance(padding._mgf._algorithm, hashes.SHA1) + else: + return False + + def generate_dsa_parameters(self, key_size): + if key_size not in (1024, 2048, 3072): + raise ValueError( + "Key size must be 1024 or 2048 or 3072 bits.") + + if (self._lib.OPENSSL_VERSION_NUMBER < 0x1000000f and + key_size > 1024): + raise ValueError( + "Key size must be 1024 because OpenSSL < 1.0.0 doesn't " + "support larger key sizes.") + + ctx = self._lib.DSA_new() + assert ctx != self._ffi.NULL + ctx = self._ffi.gc(ctx, self._lib.DSA_free) + + res = self._lib.DSA_generate_parameters_ex( + ctx, key_size, self._ffi.NULL, 0, + self._ffi.NULL, self._ffi.NULL, self._ffi.NULL + ) + + assert res == 1 + + return _DSAParameters(self, ctx) + + def generate_dsa_private_key(self, parameters): + ctx = self._lib.DSA_new() + assert ctx != self._ffi.NULL + ctx = self._ffi.gc(ctx, self._lib.DSA_free) + ctx.p = self._lib.BN_dup(parameters._dsa_cdata.p) + ctx.q = self._lib.BN_dup(parameters._dsa_cdata.q) + ctx.g = self._lib.BN_dup(parameters._dsa_cdata.g) + + self._lib.DSA_generate_key(ctx) + + return _DSAPrivateKey(self, ctx) + + def generate_dsa_private_key_and_parameters(self, key_size): + parameters = self.generate_dsa_parameters(key_size) + return self.generate_dsa_private_key(parameters) + + def load_dsa_private_numbers(self, numbers): + dsa._check_dsa_private_numbers(numbers) + parameter_numbers = numbers.public_numbers.parameter_numbers + + dsa_cdata = self._lib.DSA_new() + assert dsa_cdata != self._ffi.NULL + dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) + + dsa_cdata.p = self._int_to_bn(parameter_numbers.p) + dsa_cdata.q = self._int_to_bn(parameter_numbers.q) + dsa_cdata.g = self._int_to_bn(parameter_numbers.g) + dsa_cdata.pub_key = self._int_to_bn(numbers.public_numbers.y) + dsa_cdata.priv_key = self._int_to_bn(numbers.x) + + return _DSAPrivateKey(self, dsa_cdata) + + def load_dsa_public_numbers(self, numbers): + dsa._check_dsa_parameters(numbers.parameter_numbers) + dsa_cdata = self._lib.DSA_new() + assert dsa_cdata != self._ffi.NULL + dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) + + dsa_cdata.p = self._int_to_bn(numbers.parameter_numbers.p) + dsa_cdata.q = self._int_to_bn(numbers.parameter_numbers.q) + dsa_cdata.g = self._int_to_bn(numbers.parameter_numbers.g) + dsa_cdata.pub_key = self._int_to_bn(numbers.y) + + return _DSAPublicKey(self, dsa_cdata) + + def load_dsa_parameter_numbers(self, numbers): + dsa._check_dsa_parameters(numbers) + dsa_cdata = self._lib.DSA_new() + assert dsa_cdata != self._ffi.NULL + dsa_cdata = self._ffi.gc(dsa_cdata, self._lib.DSA_free) + + dsa_cdata.p = self._int_to_bn(numbers.p) + dsa_cdata.q = self._int_to_bn(numbers.q) + dsa_cdata.g = self._int_to_bn(numbers.g) + + return _DSAParameters(self, dsa_cdata) + + def dsa_hash_supported(self, algorithm): + if self._lib.OPENSSL_VERSION_NUMBER < 0x1000000f: + return isinstance(algorithm, hashes.SHA1) + else: + return self.hash_supported(algorithm) + + def dsa_parameters_supported(self, p, q, g): + if self._lib.OPENSSL_VERSION_NUMBER < 0x1000000f: + return (utils.bit_length(p) <= 1024 and utils.bit_length(q) <= 160) + else: + return True + + def cmac_algorithm_supported(self, algorithm): + return ( + self._lib.Cryptography_HAS_CMAC == 1 + and self.cipher_supported(algorithm, CBC( + b"\x00" * algorithm.block_size)) + ) + + def create_cmac_ctx(self, algorithm): + return _CMACContext(self, algorithm) + + def load_pem_private_key(self, data, password): + return self._load_key( + self._lib.PEM_read_bio_PrivateKey, + self._evp_pkey_to_private_key, + data, + password, + ) + + def load_pem_public_key(self, data): + return self._load_key( + self._lib.PEM_read_bio_PUBKEY, + self._evp_pkey_to_public_key, + data, + None, + ) + + def load_traditional_openssl_pem_private_key(self, data, password): + warnings.warn( + "load_traditional_openssl_pem_private_key is deprecated and will " + "be removed in a future version, use load_pem_private_key " + "instead.", + utils.DeprecatedIn06, + stacklevel=2 + ) + return self.load_pem_private_key(data, password) + + def load_pkcs8_pem_private_key(self, data, password): + warnings.warn( + "load_pkcs8_pem_private_key is deprecated and will be removed in a" + " future version, use load_pem_private_key instead.", + utils.DeprecatedIn06, + stacklevel=2 + ) + return self.load_pem_private_key(data, password) + + def _load_key(self, openssl_read_func, convert_func, data, password): + mem_bio = self._bytes_to_bio(data) + + password_callback, password_func = self._pem_password_cb(password) + + evp_pkey = openssl_read_func( + mem_bio.bio, + self._ffi.NULL, + password_callback, + self._ffi.NULL + ) + + if evp_pkey == self._ffi.NULL: + if password_func.exception is not None: + errors = self._consume_errors() + assert errors + raise password_func.exception + else: + self._handle_key_loading_error() + + evp_pkey = self._ffi.gc(evp_pkey, self._lib.EVP_PKEY_free) + + if password is not None and password_func.called == 0: + raise TypeError( + "Password was given but private key is not encrypted.") + + assert ( + (password is not None and password_func.called == 1) or + password is None + ) + + return convert_func(evp_pkey) + + def _handle_key_loading_error(self): + errors = self._consume_errors() + + if not errors: + raise ValueError("Could not unserialize key data.") + + elif errors[0][1:] in ( + ( + self._lib.ERR_LIB_EVP, + self._lib.EVP_F_EVP_DECRYPTFINAL_EX, + self._lib.EVP_R_BAD_DECRYPT + ), + ( + self._lib.ERR_LIB_PKCS12, + self._lib.PKCS12_F_PKCS12_PBE_CRYPT, + self._lib.PKCS12_R_PKCS12_CIPHERFINAL_ERROR, + ) + ): + raise ValueError("Bad decrypt. Incorrect password?") + + elif errors[0][1:] in ( + ( + self._lib.ERR_LIB_PEM, + self._lib.PEM_F_PEM_GET_EVP_CIPHER_INFO, + self._lib.PEM_R_UNSUPPORTED_ENCRYPTION + ), + + ( + self._lib.ERR_LIB_EVP, + self._lib.EVP_F_EVP_PBE_CIPHERINIT, + self._lib.EVP_R_UNKNOWN_PBE_ALGORITHM + ) + ): + raise UnsupportedAlgorithm( + "PEM data is encrypted with an unsupported cipher", + _Reasons.UNSUPPORTED_CIPHER + ) + + elif any( + error[1:] == ( + self._lib.ERR_LIB_EVP, + self._lib.EVP_F_EVP_PKCS82PKEY, + self._lib.EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM + ) + for error in errors + ): + raise UnsupportedAlgorithm( + "Unsupported public key algorithm.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM + ) + + else: + assert errors[0][1] in ( + self._lib.ERR_LIB_EVP, + self._lib.ERR_LIB_PEM, + self._lib.ERR_LIB_ASN1, + ) + raise ValueError("Could not unserialize key data.") + + def elliptic_curve_supported(self, curve): + if self._lib.Cryptography_HAS_EC != 1: + return False + + try: + curve_nid = self._elliptic_curve_to_nid(curve) + except UnsupportedAlgorithm: + curve_nid = self._lib.NID_undef + + ctx = self._lib.EC_GROUP_new_by_curve_name(curve_nid) + + if ctx == self._ffi.NULL: + errors = self._consume_errors() + assert ( + curve_nid == self._lib.NID_undef or + errors[0][1:] == ( + self._lib.ERR_LIB_EC, + self._lib.EC_F_EC_GROUP_NEW_BY_CURVE_NAME, + self._lib.EC_R_UNKNOWN_GROUP + ) + ) + return False + else: + assert curve_nid != self._lib.NID_undef + self._lib.EC_GROUP_free(ctx) + return True + + def elliptic_curve_signature_algorithm_supported( + self, signature_algorithm, curve + ): + if self._lib.Cryptography_HAS_EC != 1: + return False + + # We only support ECDSA right now. + if not isinstance(signature_algorithm, ec.ECDSA): + return False + + # Before 0.9.8m OpenSSL can't cope with digests longer than the curve. + if ( + self._lib.OPENSSL_VERSION_NUMBER < 0x009080df and + curve.key_size < signature_algorithm.algorithm.digest_size * 8 + ): + return False + + return self.elliptic_curve_supported(curve) + + def generate_elliptic_curve_private_key(self, curve): + """ + Generate a new private key on the named curve. + """ + + if self.elliptic_curve_supported(curve): + curve_nid = self._elliptic_curve_to_nid(curve) + + ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid) + assert ec_cdata != self._ffi.NULL + ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) + + res = self._lib.EC_KEY_generate_key(ec_cdata) + assert res == 1 + + res = self._lib.EC_KEY_check_key(ec_cdata) + assert res == 1 + + return _EllipticCurvePrivateKey(self, ec_cdata) + else: + raise UnsupportedAlgorithm( + "Backend object does not support {0}.".format(curve.name), + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE + ) + + def elliptic_curve_private_key_from_numbers(self, numbers): + warnings.warn( + "elliptic_curve_private_key_from_numbers is deprecated and will " + "be removed in a future version.", + utils.DeprecatedIn06, + stacklevel=2 + ) + return self.load_elliptic_curve_private_numbers(numbers) + + def load_elliptic_curve_private_numbers(self, numbers): + public = numbers.public_numbers + + curve_nid = self._elliptic_curve_to_nid(public.curve) + + ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid) + assert ec_cdata != self._ffi.NULL + ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) + + ec_cdata = self._ec_key_set_public_key_affine_coordinates( + ec_cdata, public.x, public.y) + + res = self._lib.EC_KEY_set_private_key( + ec_cdata, self._int_to_bn(numbers.private_value)) + assert res == 1 + + return _EllipticCurvePrivateKey(self, ec_cdata) + + def elliptic_curve_public_key_from_numbers(self, numbers): + warnings.warn( + "elliptic_curve_public_key_from_numbers is deprecated and will be " + "removed in a future version.", + utils.DeprecatedIn06, + stacklevel=2 + ) + return self.load_elliptic_curve_public_numbers(numbers) + + def load_elliptic_curve_public_numbers(self, numbers): + curve_nid = self._elliptic_curve_to_nid(numbers.curve) + + ec_cdata = self._lib.EC_KEY_new_by_curve_name(curve_nid) + assert ec_cdata != self._ffi.NULL + ec_cdata = self._ffi.gc(ec_cdata, self._lib.EC_KEY_free) + + ec_cdata = self._ec_key_set_public_key_affine_coordinates( + ec_cdata, numbers.x, numbers.y) + + return _EllipticCurvePublicKey(self, ec_cdata) + + def _elliptic_curve_to_nid(self, curve): + """ + Get the NID for a curve name. + """ + + curve_aliases = { + "secp192r1": "prime192v1", + "secp256r1": "prime256v1" + } + + curve_name = curve_aliases.get(curve.name, curve.name) + + curve_nid = self._lib.OBJ_sn2nid(curve_name.encode()) + if curve_nid == self._lib.NID_undef: + raise UnsupportedAlgorithm( + "{0} is not a supported elliptic curve".format(curve.name), + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE + ) + return curve_nid + + @contextmanager + def _tmp_bn_ctx(self): + bn_ctx = self._lib.BN_CTX_new() + assert bn_ctx != self._ffi.NULL + bn_ctx = self._ffi.gc(bn_ctx, self._lib.BN_CTX_free) + self._lib.BN_CTX_start(bn_ctx) + try: + yield bn_ctx + finally: + self._lib.BN_CTX_end(bn_ctx) + + def _ec_key_determine_group_get_set_funcs(self, ctx): + """ + Given an EC_KEY determine the group and what methods are required to + get/set point coordinates. + """ + assert ctx != self._ffi.NULL + + nid_two_field = self._lib.OBJ_sn2nid(b"characteristic-two-field") + assert nid_two_field != self._lib.NID_undef + + group = self._lib.EC_KEY_get0_group(ctx) + assert group != self._ffi.NULL + + method = self._lib.EC_GROUP_method_of(group) + assert method != self._ffi.NULL + + nid = self._lib.EC_METHOD_get_field_type(method) + assert nid != self._lib.NID_undef + + if nid == nid_two_field and self._lib.Cryptography_HAS_EC2M: + set_func = self._lib.EC_POINT_set_affine_coordinates_GF2m + get_func = self._lib.EC_POINT_get_affine_coordinates_GF2m + else: + set_func = self._lib.EC_POINT_set_affine_coordinates_GFp + get_func = self._lib.EC_POINT_get_affine_coordinates_GFp + + assert set_func and get_func + + return set_func, get_func, group + + def _ec_key_set_public_key_affine_coordinates(self, ctx, x, y): + """ + This is a port of EC_KEY_set_public_key_affine_coordinates that was + added in 1.0.1. + + Sets the public key point in the EC_KEY context to the affine x and y + values. + """ + + if x < 0 or y < 0: + raise ValueError( + "Invalid EC key. Both x and y must be non-negative." + ) + + bn_x = self._int_to_bn(x) + bn_y = self._int_to_bn(y) + + set_func, get_func, group = ( + self._ec_key_determine_group_get_set_funcs(ctx) + ) + + point = self._lib.EC_POINT_new(group) + assert point != self._ffi.NULL + point = self._ffi.gc(point, self._lib.EC_POINT_free) + + with self._tmp_bn_ctx() as bn_ctx: + check_x = self._lib.BN_CTX_get(bn_ctx) + check_y = self._lib.BN_CTX_get(bn_ctx) + + res = set_func(group, point, bn_x, bn_y, bn_ctx) + assert res == 1 + + res = get_func(group, point, check_x, check_y, bn_ctx) + assert res == 1 + + assert self._lib.BN_cmp(bn_x, check_x) == 0 + assert self._lib.BN_cmp(bn_y, check_y) == 0 + + res = self._lib.EC_KEY_set_public_key(ctx, point) + assert res == 1 + + res = self._lib.EC_KEY_check_key(ctx) + if res != 1: + self._consume_errors() + raise ValueError("Invalid EC key.") + + return ctx + + +class GetCipherByName(object): + def __init__(self, fmt): + self._fmt = fmt + + def __call__(self, backend, cipher, mode): + cipher_name = self._fmt.format(cipher=cipher, mode=mode).lower() + return backend._lib.EVP_get_cipherbyname(cipher_name.encode("ascii")) + + +backend = Backend() diff --git a/src/cryptography/hazmat/backends/openssl/ciphers.py b/src/cryptography/hazmat/backends/openssl/ciphers.py new file mode 100644 index 00000000..4ec2ac89 --- /dev/null +++ b/src/cryptography/hazmat/backends/openssl/ciphers.py @@ -0,0 +1,225 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +from cryptography import utils +from cryptography.exceptions import InvalidTag, UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.primitives import interfaces +from cryptography.hazmat.primitives.ciphers.modes import GCM + + +@utils.register_interface(interfaces.CipherContext) +@utils.register_interface(interfaces.AEADCipherContext) +@utils.register_interface(interfaces.AEADEncryptionContext) +class _CipherContext(object): + _ENCRYPT = 1 + _DECRYPT = 0 + + def __init__(self, backend, cipher, mode, operation): + self._backend = backend + self._cipher = cipher + self._mode = mode + self._operation = operation + self._tag = None + + if isinstance(self._cipher, interfaces.BlockCipherAlgorithm): + self._block_size = self._cipher.block_size + else: + self._block_size = 1 + + ctx = self._backend._lib.EVP_CIPHER_CTX_new() + ctx = self._backend._ffi.gc( + ctx, self._backend._lib.EVP_CIPHER_CTX_free + ) + + registry = self._backend._cipher_registry + try: + adapter = registry[type(cipher), type(mode)] + except KeyError: + raise UnsupportedAlgorithm( + "cipher {0} in {1} mode is not supported " + "by this backend.".format( + cipher.name, mode.name if mode else mode), + _Reasons.UNSUPPORTED_CIPHER + ) + + evp_cipher = adapter(self._backend, cipher, mode) + if evp_cipher == self._backend._ffi.NULL: + raise UnsupportedAlgorithm( + "cipher {0} in {1} mode is not supported " + "by this backend.".format( + cipher.name, mode.name if mode else mode), + _Reasons.UNSUPPORTED_CIPHER + ) + + if isinstance(mode, interfaces.ModeWithInitializationVector): + iv_nonce = mode.initialization_vector + elif isinstance(mode, interfaces.ModeWithNonce): + iv_nonce = mode.nonce + else: + iv_nonce = self._backend._ffi.NULL + # begin init with cipher and operation type + res = self._backend._lib.EVP_CipherInit_ex(ctx, evp_cipher, + self._backend._ffi.NULL, + self._backend._ffi.NULL, + self._backend._ffi.NULL, + operation) + assert res != 0 + # set the key length to handle variable key ciphers + res = self._backend._lib.EVP_CIPHER_CTX_set_key_length( + ctx, len(cipher.key) + ) + assert res != 0 + if isinstance(mode, GCM): + res = self._backend._lib.EVP_CIPHER_CTX_ctrl( + ctx, self._backend._lib.EVP_CTRL_GCM_SET_IVLEN, + len(iv_nonce), self._backend._ffi.NULL + ) + assert res != 0 + if operation == self._DECRYPT: + res = self._backend._lib.EVP_CIPHER_CTX_ctrl( + ctx, self._backend._lib.EVP_CTRL_GCM_SET_TAG, + len(mode.tag), mode.tag + ) + assert res != 0 + + # pass key/iv + res = self._backend._lib.EVP_CipherInit_ex( + ctx, + self._backend._ffi.NULL, + self._backend._ffi.NULL, + cipher.key, + iv_nonce, + operation + ) + assert res != 0 + # We purposely disable padding here as it's handled higher up in the + # API. + self._backend._lib.EVP_CIPHER_CTX_set_padding(ctx, 0) + self._ctx = ctx + + def update(self, data): + # OpenSSL 0.9.8e has an assertion in its EVP code that causes it + # to SIGABRT if you call update with an empty byte string. This can be + # removed when we drop support for 0.9.8e (CentOS/RHEL 5). This branch + # should be taken only when length is zero and mode is not GCM because + # AES GCM can return improper tag values if you don't call update + # with empty plaintext when authenticating AAD for ...reasons. + if len(data) == 0 and not isinstance(self._mode, GCM): + return b"" + + buf = self._backend._ffi.new("unsigned char[]", + len(data) + self._block_size - 1) + outlen = self._backend._ffi.new("int *") + res = self._backend._lib.EVP_CipherUpdate(self._ctx, buf, outlen, data, + len(data)) + assert res != 0 + return self._backend._ffi.buffer(buf)[:outlen[0]] + + def finalize(self): + # OpenSSL 1.0.1 on Ubuntu 12.04 (and possibly other distributions) + # appears to have a bug where you must make at least one call to update + # even if you are only using authenticate_additional_data or the + # GCM tag will be wrong. An (empty) call to update resolves this + # and is harmless for all other versions of OpenSSL. + if isinstance(self._mode, GCM): + self.update(b"") + + buf = self._backend._ffi.new("unsigned char[]", self._block_size) + outlen = self._backend._ffi.new("int *") + res = self._backend._lib.EVP_CipherFinal_ex(self._ctx, buf, outlen) + if res == 0: + errors = self._backend._consume_errors() + + if not errors and isinstance(self._mode, GCM): + raise InvalidTag + + assert errors + + if errors[0][1:] == ( + self._backend._lib.ERR_LIB_EVP, + self._backend._lib.EVP_F_EVP_ENCRYPTFINAL_EX, + self._backend._lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH + ) or errors[0][1:] == ( + self._backend._lib.ERR_LIB_EVP, + self._backend._lib.EVP_F_EVP_DECRYPTFINAL_EX, + self._backend._lib.EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH + ): + raise ValueError( + "The length of the provided data is not a multiple of " + "the block length." + ) + else: + raise self._backend._unknown_error(errors[0]) + + if (isinstance(self._mode, GCM) and + self._operation == self._ENCRYPT): + block_byte_size = self._block_size // 8 + tag_buf = self._backend._ffi.new( + "unsigned char[]", block_byte_size + ) + res = self._backend._lib.EVP_CIPHER_CTX_ctrl( + self._ctx, self._backend._lib.EVP_CTRL_GCM_GET_TAG, + block_byte_size, tag_buf + ) + assert res != 0 + self._tag = self._backend._ffi.buffer(tag_buf)[:] + + res = self._backend._lib.EVP_CIPHER_CTX_cleanup(self._ctx) + assert res == 1 + return self._backend._ffi.buffer(buf)[:outlen[0]] + + def authenticate_additional_data(self, data): + outlen = self._backend._ffi.new("int *") + res = self._backend._lib.EVP_CipherUpdate( + self._ctx, self._backend._ffi.NULL, outlen, data, len(data) + ) + assert res != 0 + + tag = utils.read_only_property("_tag") + + +@utils.register_interface(interfaces.CipherContext) +class _AESCTRCipherContext(object): + """ + This is needed to provide support for AES CTR mode in OpenSSL 0.9.8. It can + be removed when we drop 0.9.8 support (RHEL5 extended life ends 2020). + """ + def __init__(self, backend, cipher, mode): + self._backend = backend + + self._key = self._backend._ffi.new("AES_KEY *") + assert self._key != self._backend._ffi.NULL + res = self._backend._lib.AES_set_encrypt_key( + cipher.key, len(cipher.key) * 8, self._key + ) + assert res == 0 + self._ecount = self._backend._ffi.new("char[]", 16) + self._nonce = self._backend._ffi.new("char[16]", mode.nonce) + self._num = self._backend._ffi.new("unsigned int *", 0) + + def update(self, data): + buf = self._backend._ffi.new("unsigned char[]", len(data)) + self._backend._lib.AES_ctr128_encrypt( + data, buf, len(data), self._key, self._nonce, + self._ecount, self._num + ) + return self._backend._ffi.buffer(buf)[:] + + def finalize(self): + self._key = None + self._ecount = None + self._nonce = None + self._num = None + return b"" diff --git a/src/cryptography/hazmat/backends/openssl/cmac.py b/src/cryptography/hazmat/backends/openssl/cmac.py new file mode 100644 index 00000000..1ad6055b --- /dev/null +++ b/src/cryptography/hazmat/backends/openssl/cmac.py @@ -0,0 +1,89 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + + +from cryptography import utils +from cryptography.exceptions import ( + InvalidSignature, UnsupportedAlgorithm, _Reasons +) +from cryptography.hazmat.primitives import constant_time, interfaces +from cryptography.hazmat.primitives.ciphers.modes import CBC + + +@utils.register_interface(interfaces.MACContext) +class _CMACContext(object): + def __init__(self, backend, algorithm, ctx=None): + if not backend.cmac_algorithm_supported(algorithm): + raise UnsupportedAlgorithm("This backend does not support CMAC.", + _Reasons.UNSUPPORTED_CIPHER) + + self._backend = backend + self._key = algorithm.key + self._algorithm = algorithm + self._output_length = algorithm.block_size // 8 + + if ctx is None: + registry = self._backend._cipher_registry + adapter = registry[type(algorithm), CBC] + + evp_cipher = adapter(self._backend, algorithm, CBC) + + ctx = self._backend._lib.CMAC_CTX_new() + + assert ctx != self._backend._ffi.NULL + ctx = self._backend._ffi.gc(ctx, self._backend._lib.CMAC_CTX_free) + + self._backend._lib.CMAC_Init( + ctx, self._key, len(self._key), + evp_cipher, self._backend._ffi.NULL + ) + + self._ctx = ctx + + algorithm = utils.read_only_property("_algorithm") + + def update(self, data): + res = self._backend._lib.CMAC_Update(self._ctx, data, len(data)) + assert res == 1 + + def finalize(self): + buf = self._backend._ffi.new("unsigned char[]", self._output_length) + length = self._backend._ffi.new("size_t *", self._output_length) + res = self._backend._lib.CMAC_Final( + self._ctx, buf, length + ) + assert res == 1 + + self._ctx = None + + return self._backend._ffi.buffer(buf)[:] + + def copy(self): + copied_ctx = self._backend._lib.CMAC_CTX_new() + copied_ctx = self._backend._ffi.gc( + copied_ctx, self._backend._lib.CMAC_CTX_free + ) + res = self._backend._lib.CMAC_CTX_copy( + copied_ctx, self._ctx + ) + assert res == 1 + return _CMACContext( + self._backend, self._algorithm, ctx=copied_ctx + ) + + def verify(self, signature): + digest = self.finalize() + if not constant_time.bytes_eq(digest, signature): + raise InvalidSignature("Signature did not match digest.") diff --git a/src/cryptography/hazmat/backends/openssl/dsa.py b/src/cryptography/hazmat/backends/openssl/dsa.py new file mode 100644 index 00000000..8652d50b --- /dev/null +++ b/src/cryptography/hazmat/backends/openssl/dsa.py @@ -0,0 +1,207 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +from cryptography import utils +from cryptography.exceptions import InvalidSignature +from cryptography.hazmat.backends.openssl.utils import _truncate_digest +from cryptography.hazmat.primitives import hashes, interfaces +from cryptography.hazmat.primitives.asymmetric import dsa +from cryptography.hazmat.primitives.interfaces import ( + DSAParametersWithNumbers, DSAPrivateKeyWithNumbers, DSAPublicKeyWithNumbers +) + + +def _truncate_digest_for_dsa(dsa_cdata, digest, backend): + """ + This function truncates digests that are longer than a given DS + key's length so they can be signed. OpenSSL does this for us in + 1.0.0c+ and it isn't needed in 0.9.8, but that leaves us with three + releases (1.0.0, 1.0.0a, and 1.0.0b) where this is a problem. This + truncation is not required in 0.9.8 because DSA is limited to SHA-1. + """ + + order_bits = backend._lib.BN_num_bits(dsa_cdata.q) + return _truncate_digest(digest, order_bits) + + +@utils.register_interface(interfaces.AsymmetricVerificationContext) +class _DSAVerificationContext(object): + def __init__(self, backend, public_key, signature, algorithm): + self._backend = backend + self._public_key = public_key + self._signature = signature + self._algorithm = algorithm + + self._hash_ctx = hashes.Hash(self._algorithm, self._backend) + + def update(self, data): + self._hash_ctx.update(data) + + def verify(self): + self._dsa_cdata = self._backend._ffi.gc(self._public_key._dsa_cdata, + self._backend._lib.DSA_free) + + data_to_verify = self._hash_ctx.finalize() + + data_to_verify = _truncate_digest_for_dsa( + self._dsa_cdata, data_to_verify, self._backend + ) + + # The first parameter passed to DSA_verify is unused by OpenSSL but + # must be an integer. + res = self._backend._lib.DSA_verify( + 0, data_to_verify, len(data_to_verify), self._signature, + len(self._signature), self._public_key._dsa_cdata) + + if res != 1: + errors = self._backend._consume_errors() + assert errors + if res == -1: + assert errors[0].lib == self._backend._lib.ERR_LIB_ASN1 + + raise InvalidSignature + + +@utils.register_interface(interfaces.AsymmetricSignatureContext) +class _DSASignatureContext(object): + def __init__(self, backend, private_key, algorithm): + self._backend = backend + self._private_key = private_key + self._algorithm = algorithm + self._hash_ctx = hashes.Hash(self._algorithm, self._backend) + + def update(self, data): + self._hash_ctx.update(data) + + def finalize(self): + data_to_sign = self._hash_ctx.finalize() + data_to_sign = _truncate_digest_for_dsa( + self._private_key._dsa_cdata, data_to_sign, self._backend + ) + sig_buf_len = self._backend._lib.DSA_size(self._private_key._dsa_cdata) + sig_buf = self._backend._ffi.new("unsigned char[]", sig_buf_len) + buflen = self._backend._ffi.new("unsigned int *") + + # The first parameter passed to DSA_sign is unused by OpenSSL but + # must be an integer. + res = self._backend._lib.DSA_sign( + 0, data_to_sign, len(data_to_sign), sig_buf, + buflen, self._private_key._dsa_cdata) + assert res == 1 + assert buflen[0] + + return self._backend._ffi.buffer(sig_buf)[:buflen[0]] + + +@utils.register_interface(DSAParametersWithNumbers) +class _DSAParameters(object): + def __init__(self, backend, dsa_cdata): + self._backend = backend + self._dsa_cdata = dsa_cdata + + def parameter_numbers(self): + return dsa.DSAParameterNumbers( + p=self._backend._bn_to_int(self._dsa_cdata.p), + q=self._backend._bn_to_int(self._dsa_cdata.q), + g=self._backend._bn_to_int(self._dsa_cdata.g) + ) + + def generate_private_key(self): + return self._backend.generate_dsa_private_key(self) + + +@utils.register_interface(DSAPrivateKeyWithNumbers) +class _DSAPrivateKey(object): + def __init__(self, backend, dsa_cdata): + self._backend = backend + self._dsa_cdata = dsa_cdata + self._key_size = self._backend._lib.BN_num_bits(self._dsa_cdata.p) + + key_size = utils.read_only_property("_key_size") + + def signer(self, signature_algorithm): + return _DSASignatureContext(self._backend, self, signature_algorithm) + + def private_numbers(self): + return dsa.DSAPrivateNumbers( + public_numbers=dsa.DSAPublicNumbers( + parameter_numbers=dsa.DSAParameterNumbers( + p=self._backend._bn_to_int(self._dsa_cdata.p), + q=self._backend._bn_to_int(self._dsa_cdata.q), + g=self._backend._bn_to_int(self._dsa_cdata.g) + ), + y=self._backend._bn_to_int(self._dsa_cdata.pub_key) + ), + x=self._backend._bn_to_int(self._dsa_cdata.priv_key) + ) + + def public_key(self): + dsa_cdata = self._backend._lib.DSA_new() + assert dsa_cdata != self._backend._ffi.NULL + dsa_cdata = self._backend._ffi.gc( + dsa_cdata, self._backend._lib.DSA_free + ) + dsa_cdata.p = self._backend._lib.BN_dup(self._dsa_cdata.p) + dsa_cdata.q = self._backend._lib.BN_dup(self._dsa_cdata.q) + dsa_cdata.g = self._backend._lib.BN_dup(self._dsa_cdata.g) + dsa_cdata.pub_key = self._backend._lib.BN_dup(self._dsa_cdata.pub_key) + return _DSAPublicKey(self._backend, dsa_cdata) + + def parameters(self): + dsa_cdata = self._backend._lib.DSA_new() + assert dsa_cdata != self._backend._ffi.NULL + dsa_cdata = self._backend._ffi.gc( + dsa_cdata, self._backend._lib.DSA_free + ) + dsa_cdata.p = self._backend._lib.BN_dup(self._dsa_cdata.p) + dsa_cdata.q = self._backend._lib.BN_dup(self._dsa_cdata.q) + dsa_cdata.g = self._backend._lib.BN_dup(self._dsa_cdata.g) + return _DSAParameters(self._backend, dsa_cdata) + + +@utils.register_interface(DSAPublicKeyWithNumbers) +class _DSAPublicKey(object): + def __init__(self, backend, dsa_cdata): + self._backend = backend + self._dsa_cdata = dsa_cdata + self._key_size = self._backend._lib.BN_num_bits(self._dsa_cdata.p) + + key_size = utils.read_only_property("_key_size") + + def verifier(self, signature, signature_algorithm): + return _DSAVerificationContext( + self._backend, self, signature, signature_algorithm + ) + + def public_numbers(self): + return dsa.DSAPublicNumbers( + parameter_numbers=dsa.DSAParameterNumbers( + p=self._backend._bn_to_int(self._dsa_cdata.p), + q=self._backend._bn_to_int(self._dsa_cdata.q), + g=self._backend._bn_to_int(self._dsa_cdata.g) + ), + y=self._backend._bn_to_int(self._dsa_cdata.pub_key) + ) + + def parameters(self): + dsa_cdata = self._backend._lib.DSA_new() + assert dsa_cdata != self._backend._ffi.NULL + dsa_cdata = self._backend._ffi.gc( + dsa_cdata, self._backend._lib.DSA_free + ) + dsa_cdata.p = self._backend._lib.BN_dup(self._dsa_cdata.p) + dsa_cdata.q = self._backend._lib.BN_dup(self._dsa_cdata.q) + dsa_cdata.g = self._backend._lib.BN_dup(self._dsa_cdata.g) + return _DSAParameters(self._backend, dsa_cdata) diff --git a/src/cryptography/hazmat/backends/openssl/ec.py b/src/cryptography/hazmat/backends/openssl/ec.py new file mode 100644 index 00000000..13b0ddbb --- /dev/null +++ b/src/cryptography/hazmat/backends/openssl/ec.py @@ -0,0 +1,234 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +from cryptography import utils +from cryptography.exceptions import ( + InvalidSignature, UnsupportedAlgorithm, _Reasons +) +from cryptography.hazmat.backends.openssl.utils import _truncate_digest +from cryptography.hazmat.primitives import hashes, interfaces +from cryptography.hazmat.primitives.asymmetric import ec + + +def _truncate_digest_for_ecdsa(ec_key_cdata, digest, backend): + """ + This function truncates digests that are longer than a given elliptic + curve key's length so they can be signed. Since elliptic curve keys are + much shorter than RSA keys many digests (e.g. SHA-512) may require + truncation. + """ + + _lib = backend._lib + _ffi = backend._ffi + + group = _lib.EC_KEY_get0_group(ec_key_cdata) + + with backend._tmp_bn_ctx() as bn_ctx: + order = _lib.BN_CTX_get(bn_ctx) + assert order != _ffi.NULL + + res = _lib.EC_GROUP_get_order(group, order, bn_ctx) + assert res == 1 + + order_bits = _lib.BN_num_bits(order) + + return _truncate_digest(digest, order_bits) + + +def _ec_key_curve_sn(backend, ec_key): + group = backend._lib.EC_KEY_get0_group(ec_key) + assert group != backend._ffi.NULL + + nid = backend._lib.EC_GROUP_get_curve_name(group) + assert nid != backend._lib.NID_undef + + curve_name = backend._lib.OBJ_nid2sn(nid) + assert curve_name != backend._ffi.NULL + + sn = backend._ffi.string(curve_name).decode('ascii') + return sn + + +def _sn_to_elliptic_curve(backend, sn): + try: + return ec._CURVE_TYPES[sn]() + except KeyError: + raise UnsupportedAlgorithm( + "{0} is not a supported elliptic curve".format(sn), + _Reasons.UNSUPPORTED_ELLIPTIC_CURVE + ) + + +@utils.register_interface(interfaces.AsymmetricSignatureContext) +class _ECDSASignatureContext(object): + def __init__(self, backend, private_key, algorithm): + self._backend = backend + self._private_key = private_key + self._digest = hashes.Hash(algorithm, backend) + + def update(self, data): + self._digest.update(data) + + def finalize(self): + ec_key = self._private_key._ec_key + + digest = self._digest.finalize() + + digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend) + + max_size = self._backend._lib.ECDSA_size(ec_key) + assert max_size > 0 + + sigbuf = self._backend._ffi.new("char[]", max_size) + siglen_ptr = self._backend._ffi.new("unsigned int[]", 1) + res = self._backend._lib.ECDSA_sign( + 0, + digest, + len(digest), + sigbuf, + siglen_ptr, + ec_key + ) + assert res == 1 + return self._backend._ffi.buffer(sigbuf)[:siglen_ptr[0]] + + +@utils.register_interface(interfaces.AsymmetricVerificationContext) +class _ECDSAVerificationContext(object): + def __init__(self, backend, public_key, signature, algorithm): + self._backend = backend + self._public_key = public_key + self._signature = signature + self._digest = hashes.Hash(algorithm, backend) + + def update(self, data): + self._digest.update(data) + + def verify(self): + ec_key = self._public_key._ec_key + + digest = self._digest.finalize() + + digest = _truncate_digest_for_ecdsa(ec_key, digest, self._backend) + + res = self._backend._lib.ECDSA_verify( + 0, + digest, + len(digest), + self._signature, + len(self._signature), + ec_key + ) + if res != 1: + self._backend._consume_errors() + raise InvalidSignature + return True + + +@utils.register_interface(interfaces.EllipticCurvePrivateKeyWithNumbers) +class _EllipticCurvePrivateKey(object): + def __init__(self, backend, ec_key_cdata): + self._backend = backend + self._ec_key = ec_key_cdata + + sn = _ec_key_curve_sn(backend, ec_key_cdata) + self._curve = _sn_to_elliptic_curve(backend, sn) + + curve = utils.read_only_property("_curve") + + def signer(self, signature_algorithm): + if isinstance(signature_algorithm, ec.ECDSA): + return _ECDSASignatureContext( + self._backend, self, signature_algorithm.algorithm + ) + else: + raise UnsupportedAlgorithm( + "Unsupported elliptic curve signature algorithm.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def public_key(self): + group = self._backend._lib.EC_KEY_get0_group(self._ec_key) + assert group != self._backend._ffi.NULL + + curve_nid = self._backend._lib.EC_GROUP_get_curve_name(group) + + public_ec_key = self._backend._lib.EC_KEY_new_by_curve_name(curve_nid) + assert public_ec_key != self._backend._ffi.NULL + public_ec_key = self._backend._ffi.gc( + public_ec_key, self._backend._lib.EC_KEY_free + ) + + point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) + assert point != self._backend._ffi.NULL + + res = self._backend._lib.EC_KEY_set_public_key(public_ec_key, point) + assert res == 1 + + return _EllipticCurvePublicKey( + self._backend, public_ec_key + ) + + def private_numbers(self): + bn = self._backend._lib.EC_KEY_get0_private_key(self._ec_key) + private_value = self._backend._bn_to_int(bn) + return ec.EllipticCurvePrivateNumbers( + private_value=private_value, + public_numbers=self.public_key().public_numbers() + ) + + +@utils.register_interface(interfaces.EllipticCurvePublicKeyWithNumbers) +class _EllipticCurvePublicKey(object): + def __init__(self, backend, ec_key_cdata): + self._backend = backend + self._ec_key = ec_key_cdata + + sn = _ec_key_curve_sn(backend, ec_key_cdata) + self._curve = _sn_to_elliptic_curve(backend, sn) + + curve = utils.read_only_property("_curve") + + def verifier(self, signature, signature_algorithm): + if isinstance(signature_algorithm, ec.ECDSA): + return _ECDSAVerificationContext( + self._backend, self, signature, signature_algorithm.algorithm + ) + else: + raise UnsupportedAlgorithm( + "Unsupported elliptic curve signature algorithm.", + _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM) + + def public_numbers(self): + set_func, get_func, group = ( + self._backend._ec_key_determine_group_get_set_funcs(self._ec_key) + ) + point = self._backend._lib.EC_KEY_get0_public_key(self._ec_key) + assert point != self._backend._ffi.NULL + + with self._backend._tmp_bn_ctx() as bn_ctx: + bn_x = self._backend._lib.BN_CTX_get(bn_ctx) + bn_y = self._backend._lib.BN_CTX_get(bn_ctx) + + res = get_func(group, point, bn_x, bn_y, bn_ctx) + assert res == 1 + + x = self._backend._bn_to_int(bn_x) + y = self._backend._bn_to_int(bn_y) + + return ec.EllipticCurvePublicNumbers( + x=x, + y=y, + curve=self._curve + ) diff --git a/src/cryptography/hazmat/backends/openssl/hashes.py b/src/cryptography/hazmat/backends/openssl/hashes.py new file mode 100644 index 00000000..591c014a --- /dev/null +++ b/src/cryptography/hazmat/backends/openssl/hashes.py @@ -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 + + +from cryptography import utils +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons +from cryptography.hazmat.primitives import interfaces + + +@utils.register_interface(interfaces.HashContext) +class _HashContext(object): + def __init__(self, backend, algorithm, ctx=None): + self._algorithm = algorithm + + self._backend = backend + + if ctx is None: + ctx = self._backend._lib.EVP_MD_CTX_create() + ctx = self._backend._ffi.gc(ctx, + self._backend._lib.EVP_MD_CTX_destroy) + evp_md = self._backend._lib.EVP_get_digestbyname( + algorithm.name.encode("ascii")) + if evp_md == self._backend._ffi.NULL: + raise UnsupportedAlgorithm( + "{0} is not a supported hash on this backend.".format( + algorithm.name), + _Reasons.UNSUPPORTED_HASH + ) + res = self._backend._lib.EVP_DigestInit_ex(ctx, evp_md, + self._backend._ffi.NULL) + assert res != 0 + + self._ctx = ctx + + algorithm = utils.read_only_property("_algorithm") + + def copy(self): + copied_ctx = self._backend._lib.EVP_MD_CTX_create() + copied_ctx = self._backend._ffi.gc( + copied_ctx, self._backend._lib.EVP_MD_CTX_destroy + ) + res = self._backend._lib.EVP_MD_CTX_copy_ex(copied_ctx, self._ctx) + assert res != 0 + return _HashContext(self._backend, self.algorithm, ctx=copied_ctx) + + def update(self, data): + res = self._backend._lib.EVP_DigestUpdate(self._ctx, data, len(data)) + assert res != 0 + + def finalize(self): + buf = self._backend._ffi.new("unsigned char[]", + self._backend._lib.EVP_MAX_MD_SIZE) + outlen = self._backend._ffi.new("unsigned int *") + res = self._backend._lib.EVP_DigestFinal_ex(self._ctx, buf, outlen) + assert res != 0 + assert outlen[0] == self.algorithm.digest_size + res = self._backend._lib.EVP_MD_CTX_cleanup(self._ctx) + assert res == 1 + return self._backend._ffi.buffer(buf)[:outlen[0]] diff --git a/src/cryptography/hazmat/backends/openssl/hmac.py b/src/cryptography/hazmat/backends/openssl/hmac.py new file mode 100644 index 00000000..c324bd8c --- /dev/null +++ b/src/cryptography/hazmat/backends/openssl/hmac.py @@ -0,0 +1,90 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + + +from cryptography import utils +from cryptography.exceptions import ( + InvalidSignature, UnsupportedAlgorithm, _Reasons +) +from cryptography.hazmat.primitives import constant_time, interfaces + + +@utils.register_interface(interfaces.MACContext) +@utils.register_interface(interfaces.HashContext) +class _HMACContext(object): + def __init__(self, backend, key, algorithm, ctx=None): + self._algorithm = algorithm + self._backend = backend + + if ctx is None: + ctx = self._backend._ffi.new("HMAC_CTX *") + self._backend._lib.HMAC_CTX_init(ctx) + ctx = self._backend._ffi.gc( + ctx, self._backend._lib.HMAC_CTX_cleanup + ) + evp_md = self._backend._lib.EVP_get_digestbyname( + algorithm.name.encode('ascii')) + if evp_md == self._backend._ffi.NULL: + raise UnsupportedAlgorithm( + "{0} is not a supported hash on this backend.".format( + algorithm.name), + _Reasons.UNSUPPORTED_HASH + ) + res = self._backend._lib.Cryptography_HMAC_Init_ex( + ctx, key, len(key), evp_md, self._backend._ffi.NULL + ) + assert res != 0 + + self._ctx = ctx + self._key = key + + algorithm = utils.read_only_property("_algorithm") + + def copy(self): + copied_ctx = self._backend._ffi.new("HMAC_CTX *") + self._backend._lib.HMAC_CTX_init(copied_ctx) + copied_ctx = self._backend._ffi.gc( + copied_ctx, self._backend._lib.HMAC_CTX_cleanup + ) + res = self._backend._lib.Cryptography_HMAC_CTX_copy( + copied_ctx, self._ctx + ) + assert res != 0 + return _HMACContext( + self._backend, self._key, self.algorithm, ctx=copied_ctx + ) + + def update(self, data): + res = self._backend._lib.Cryptography_HMAC_Update( + self._ctx, data, len(data) + ) + assert res != 0 + + def finalize(self): + buf = self._backend._ffi.new("unsigned char[]", + self._backend._lib.EVP_MAX_MD_SIZE) + outlen = self._backend._ffi.new("unsigned int *") + res = self._backend._lib.Cryptography_HMAC_Final( + self._ctx, buf, outlen + ) + assert res != 0 + assert outlen[0] == self.algorithm.digest_size + self._backend._lib.HMAC_CTX_cleanup(self._ctx) + return self._backend._ffi.buffer(buf)[:outlen[0]] + + def verify(self, signature): + digest = self.finalize() + if not constant_time.bytes_eq(digest, signature): + raise InvalidSignature("Signature did not match digest.") diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py new file mode 100644 index 00000000..0a2a7f96 --- /dev/null +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -0,0 +1,603 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +import math + +from cryptography import utils +from cryptography.exceptions import ( + AlreadyFinalized, InvalidSignature, UnsupportedAlgorithm, _Reasons +) +from cryptography.hazmat.primitives import hashes, interfaces +from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.primitives.asymmetric.padding import ( + MGF1, OAEP, PKCS1v15, PSS +) +from cryptography.hazmat.primitives.interfaces import ( + RSAPrivateKeyWithNumbers, RSAPublicKeyWithNumbers +) + + +def _get_rsa_pss_salt_length(pss, key_size, digest_size): + salt = pss._salt_length + + if salt is MGF1.MAX_LENGTH or salt is PSS.MAX_LENGTH: + # bit length - 1 per RFC 3447 + emlen = int(math.ceil((key_size - 1) / 8.0)) + salt_length = emlen - digest_size - 2 + assert salt_length >= 0 + return salt_length + else: + return salt + + +def _enc_dec_rsa(backend, key, data, padding): + if not isinstance(padding, interfaces.AsymmetricPadding): + raise TypeError("Padding must be an instance of AsymmetricPadding.") + + if isinstance(padding, PKCS1v15): + padding_enum = backend._lib.RSA_PKCS1_PADDING + elif isinstance(padding, OAEP): + padding_enum = backend._lib.RSA_PKCS1_OAEP_PADDING + if not isinstance(padding._mgf, MGF1): + raise UnsupportedAlgorithm( + "Only MGF1 is supported by this backend.", + _Reasons.UNSUPPORTED_MGF + ) + + if not isinstance(padding._mgf._algorithm, hashes.SHA1): + raise UnsupportedAlgorithm( + "This backend supports only SHA1 inside MGF1 when " + "using OAEP.", + _Reasons.UNSUPPORTED_HASH + ) + + if padding._label is not None and padding._label != b"": + raise ValueError("This backend does not support OAEP labels.") + + if not isinstance(padding._algorithm, hashes.SHA1): + raise UnsupportedAlgorithm( + "This backend only supports SHA1 when using OAEP.", + _Reasons.UNSUPPORTED_HASH + ) + else: + raise UnsupportedAlgorithm( + "{0} is not supported by this backend.".format( + padding.name + ), + _Reasons.UNSUPPORTED_PADDING + ) + + if backend._lib.Cryptography_HAS_PKEY_CTX: + return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum) + else: + return _enc_dec_rsa_098(backend, key, data, padding_enum) + + +def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum): + if isinstance(key, _RSAPublicKey): + init = backend._lib.EVP_PKEY_encrypt_init + crypt = backend._lib.Cryptography_EVP_PKEY_encrypt + else: + init = backend._lib.EVP_PKEY_decrypt_init + crypt = backend._lib.Cryptography_EVP_PKEY_decrypt + + pkey_ctx = backend._lib.EVP_PKEY_CTX_new( + key._evp_pkey, backend._ffi.NULL + ) + assert pkey_ctx != backend._ffi.NULL + pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free) + res = init(pkey_ctx) + assert res == 1 + res = backend._lib.EVP_PKEY_CTX_set_rsa_padding( + pkey_ctx, padding_enum) + assert res > 0 + buf_size = backend._lib.EVP_PKEY_size(key._evp_pkey) + assert buf_size > 0 + outlen = backend._ffi.new("size_t *", buf_size) + buf = backend._ffi.new("char[]", buf_size) + res = crypt(pkey_ctx, buf, outlen, data, len(data)) + if res <= 0: + _handle_rsa_enc_dec_error(backend, key) + + return backend._ffi.buffer(buf)[:outlen[0]] + + +def _enc_dec_rsa_098(backend, key, data, padding_enum): + if isinstance(key, _RSAPublicKey): + crypt = backend._lib.RSA_public_encrypt + else: + crypt = backend._lib.RSA_private_decrypt + + key_size = backend._lib.RSA_size(key._rsa_cdata) + assert key_size > 0 + buf = backend._ffi.new("unsigned char[]", key_size) + res = crypt(len(data), data, buf, key._rsa_cdata, padding_enum) + if res < 0: + _handle_rsa_enc_dec_error(backend, key) + + return backend._ffi.buffer(buf)[:res] + + +def _handle_rsa_enc_dec_error(backend, key): + errors = backend._consume_errors() + assert errors + assert errors[0].lib == backend._lib.ERR_LIB_RSA + if isinstance(key, _RSAPublicKey): + assert (errors[0].reason == + backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE) + raise ValueError( + "Data too long for key size. Encrypt less data or use a " + "larger key size." + ) + else: + decoding_errors = [ + backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_01, + backend._lib.RSA_R_BLOCK_TYPE_IS_NOT_02, + ] + if backend._lib.Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR: + decoding_errors.append(backend._lib.RSA_R_PKCS_DECODING_ERROR) + + assert errors[0].reason in decoding_errors + raise ValueError("Decryption failed.") + + +@utils.register_interface(interfaces.AsymmetricSignatureContext) +class _RSASignatureContext(object): + def __init__(self, backend, private_key, padding, algorithm): + self._backend = backend + self._private_key = private_key + + if not isinstance(padding, interfaces.AsymmetricPadding): + raise TypeError( + "Expected provider of interfaces.AsymmetricPadding.") + + self._pkey_size = self._backend._lib.EVP_PKEY_size( + self._private_key._evp_pkey + ) + + if isinstance(padding, PKCS1v15): + if self._backend._lib.Cryptography_HAS_PKEY_CTX: + self._finalize_method = self._finalize_pkey_ctx + self._padding_enum = self._backend._lib.RSA_PKCS1_PADDING + else: + self._finalize_method = self._finalize_pkcs1 + elif isinstance(padding, PSS): + if not isinstance(padding._mgf, MGF1): + raise UnsupportedAlgorithm( + "Only MGF1 is supported by this backend.", + _Reasons.UNSUPPORTED_MGF + ) + + # Size of key in bytes - 2 is the maximum + # PSS signature length (salt length is checked later) + assert self._pkey_size > 0 + if self._pkey_size - algorithm.digest_size - 2 < 0: + raise ValueError("Digest too large for key size. Use a larger " + "key.") + + if not self._backend._mgf1_hash_supported(padding._mgf._algorithm): + raise UnsupportedAlgorithm( + "When OpenSSL is older than 1.0.1 then only SHA1 is " + "supported with MGF1.", + _Reasons.UNSUPPORTED_HASH + ) + + if self._backend._lib.Cryptography_HAS_PKEY_CTX: + self._finalize_method = self._finalize_pkey_ctx + self._padding_enum = self._backend._lib.RSA_PKCS1_PSS_PADDING + else: + self._finalize_method = self._finalize_pss + else: + raise UnsupportedAlgorithm( + "{0} is not supported by this backend.".format(padding.name), + _Reasons.UNSUPPORTED_PADDING + ) + + self._padding = padding + self._algorithm = algorithm + self._hash_ctx = hashes.Hash(self._algorithm, self._backend) + + def update(self, data): + self._hash_ctx.update(data) + + def finalize(self): + evp_md = self._backend._lib.EVP_get_digestbyname( + self._algorithm.name.encode("ascii")) + assert evp_md != self._backend._ffi.NULL + + return self._finalize_method(evp_md) + + def _finalize_pkey_ctx(self, evp_md): + pkey_ctx = self._backend._lib.EVP_PKEY_CTX_new( + self._private_key._evp_pkey, self._backend._ffi.NULL + ) + assert pkey_ctx != self._backend._ffi.NULL + pkey_ctx = self._backend._ffi.gc(pkey_ctx, + self._backend._lib.EVP_PKEY_CTX_free) + res = self._backend._lib.EVP_PKEY_sign_init(pkey_ctx) + assert res == 1 + res = self._backend._lib.EVP_PKEY_CTX_set_signature_md( + pkey_ctx, evp_md) + assert res > 0 + + res = self._backend._lib.EVP_PKEY_CTX_set_rsa_padding( + pkey_ctx, self._padding_enum) + assert res > 0 + if isinstance(self._padding, PSS): + res = self._backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen( + pkey_ctx, + _get_rsa_pss_salt_length( + self._padding, + self._private_key.key_size, + self._hash_ctx.algorithm.digest_size + ) + ) + assert res > 0 + + if self._backend._lib.Cryptography_HAS_MGF1_MD: + # MGF1 MD is configurable in OpenSSL 1.0.1+ + mgf1_md = self._backend._lib.EVP_get_digestbyname( + self._padding._mgf._algorithm.name.encode("ascii")) + assert mgf1_md != self._backend._ffi.NULL + res = self._backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md( + pkey_ctx, mgf1_md + ) + assert res > 0 + data_to_sign = self._hash_ctx.finalize() + buflen = self._backend._ffi.new("size_t *") + res = self._backend._lib.EVP_PKEY_sign( + pkey_ctx, + self._backend._ffi.NULL, + buflen, + data_to_sign, + len(data_to_sign) + ) + assert res == 1 + buf = self._backend._ffi.new("unsigned char[]", buflen[0]) + res = self._backend._lib.EVP_PKEY_sign( + pkey_ctx, buf, buflen, data_to_sign, len(data_to_sign)) + if res != 1: + errors = self._backend._consume_errors() + assert errors[0].lib == self._backend._lib.ERR_LIB_RSA + reason = None + if (errors[0].reason == + self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE): + reason = ("Salt length too long for key size. Try using " + "MAX_LENGTH instead.") + elif (errors[0].reason == + self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY): + reason = "Digest too large for key size. Use a larger key." + assert reason is not None + raise ValueError(reason) + + return self._backend._ffi.buffer(buf)[:] + + def _finalize_pkcs1(self, evp_md): + if self._hash_ctx._ctx is None: + raise AlreadyFinalized("Context has already been finalized.") + + sig_buf = self._backend._ffi.new("char[]", self._pkey_size) + sig_len = self._backend._ffi.new("unsigned int *") + res = self._backend._lib.EVP_SignFinal( + self._hash_ctx._ctx._ctx, + sig_buf, + sig_len, + self._private_key._evp_pkey + ) + self._hash_ctx.finalize() + if res == 0: + errors = self._backend._consume_errors() + assert errors[0].lib == self._backend._lib.ERR_LIB_RSA + assert (errors[0].reason == + self._backend._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY) + raise ValueError("Digest too large for key size. Use a larger " + "key.") + + return self._backend._ffi.buffer(sig_buf)[:sig_len[0]] + + def _finalize_pss(self, evp_md): + data_to_sign = self._hash_ctx.finalize() + padded = self._backend._ffi.new("unsigned char[]", self._pkey_size) + res = self._backend._lib.RSA_padding_add_PKCS1_PSS( + self._private_key._rsa_cdata, + padded, + data_to_sign, + evp_md, + _get_rsa_pss_salt_length( + self._padding, + self._private_key.key_size, + len(data_to_sign) + ) + ) + if res != 1: + errors = self._backend._consume_errors() + assert errors[0].lib == self._backend._lib.ERR_LIB_RSA + assert (errors[0].reason == + self._backend._lib.RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE) + raise ValueError("Salt length too long for key size. Try using " + "MAX_LENGTH instead.") + + sig_buf = self._backend._ffi.new("char[]", self._pkey_size) + sig_len = self._backend._lib.RSA_private_encrypt( + self._pkey_size, + padded, + sig_buf, + self._private_key._rsa_cdata, + self._backend._lib.RSA_NO_PADDING + ) + assert sig_len != -1 + return self._backend._ffi.buffer(sig_buf)[:sig_len] + + +@utils.register_interface(interfaces.AsymmetricVerificationContext) +class _RSAVerificationContext(object): + def __init__(self, backend, public_key, signature, padding, algorithm): + self._backend = backend + self._public_key = public_key + self._signature = signature + + if not isinstance(padding, interfaces.AsymmetricPadding): + raise TypeError( + "Expected provider of interfaces.AsymmetricPadding.") + + self._pkey_size = self._backend._lib.EVP_PKEY_size( + self._public_key._evp_pkey + ) + + if isinstance(padding, PKCS1v15): + if self._backend._lib.Cryptography_HAS_PKEY_CTX: + self._verify_method = self._verify_pkey_ctx + self._padding_enum = self._backend._lib.RSA_PKCS1_PADDING + else: + self._verify_method = self._verify_pkcs1 + elif isinstance(padding, PSS): + if not isinstance(padding._mgf, MGF1): + raise UnsupportedAlgorithm( + "Only MGF1 is supported by this backend.", + _Reasons.UNSUPPORTED_MGF + ) + + # Size of key in bytes - 2 is the maximum + # PSS signature length (salt length is checked later) + assert self._pkey_size > 0 + if self._pkey_size - algorithm.digest_size - 2 < 0: + raise ValueError( + "Digest too large for key size. Check that you have the " + "correct key and digest algorithm." + ) + + if not self._backend._mgf1_hash_supported(padding._mgf._algorithm): + raise UnsupportedAlgorithm( + "When OpenSSL is older than 1.0.1 then only SHA1 is " + "supported with MGF1.", + _Reasons.UNSUPPORTED_HASH + ) + + if self._backend._lib.Cryptography_HAS_PKEY_CTX: + self._verify_method = self._verify_pkey_ctx + self._padding_enum = self._backend._lib.RSA_PKCS1_PSS_PADDING + else: + self._verify_method = self._verify_pss + else: + raise UnsupportedAlgorithm( + "{0} is not supported by this backend.".format(padding.name), + _Reasons.UNSUPPORTED_PADDING + ) + + self._padding = padding + self._algorithm = algorithm + self._hash_ctx = hashes.Hash(self._algorithm, self._backend) + + def update(self, data): + self._hash_ctx.update(data) + + def verify(self): + evp_md = self._backend._lib.EVP_get_digestbyname( + self._algorithm.name.encode("ascii")) + assert evp_md != self._backend._ffi.NULL + + self._verify_method(evp_md) + + def _verify_pkey_ctx(self, evp_md): + pkey_ctx = self._backend._lib.EVP_PKEY_CTX_new( + self._public_key._evp_pkey, self._backend._ffi.NULL + ) + assert pkey_ctx != self._backend._ffi.NULL + pkey_ctx = self._backend._ffi.gc(pkey_ctx, + self._backend._lib.EVP_PKEY_CTX_free) + res = self._backend._lib.EVP_PKEY_verify_init(pkey_ctx) + assert res == 1 + res = self._backend._lib.EVP_PKEY_CTX_set_signature_md( + pkey_ctx, evp_md) + assert res > 0 + + res = self._backend._lib.EVP_PKEY_CTX_set_rsa_padding( + pkey_ctx, self._padding_enum) + assert res > 0 + if isinstance(self._padding, PSS): + res = self._backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen( + pkey_ctx, + _get_rsa_pss_salt_length( + self._padding, + self._public_key.key_size, + self._hash_ctx.algorithm.digest_size + ) + ) + assert res > 0 + if self._backend._lib.Cryptography_HAS_MGF1_MD: + # MGF1 MD is configurable in OpenSSL 1.0.1+ + mgf1_md = self._backend._lib.EVP_get_digestbyname( + self._padding._mgf._algorithm.name.encode("ascii")) + assert mgf1_md != self._backend._ffi.NULL + res = self._backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md( + pkey_ctx, mgf1_md + ) + assert res > 0 + + data_to_verify = self._hash_ctx.finalize() + res = self._backend._lib.EVP_PKEY_verify( + pkey_ctx, + self._signature, + len(self._signature), + data_to_verify, + len(data_to_verify) + ) + # The previous call can return negative numbers in the event of an + # error. This is not a signature failure but we need to fail if it + # occurs. + assert res >= 0 + if res == 0: + errors = self._backend._consume_errors() + assert errors + raise InvalidSignature + + def _verify_pkcs1(self, evp_md): + if self._hash_ctx._ctx is None: + raise AlreadyFinalized("Context has already been finalized.") + + res = self._backend._lib.EVP_VerifyFinal( + self._hash_ctx._ctx._ctx, + self._signature, + len(self._signature), + self._public_key._evp_pkey + ) + self._hash_ctx.finalize() + # The previous call can return negative numbers in the event of an + # error. This is not a signature failure but we need to fail if it + # occurs. + assert res >= 0 + if res == 0: + errors = self._backend._consume_errors() + assert errors + raise InvalidSignature + + def _verify_pss(self, evp_md): + buf = self._backend._ffi.new("unsigned char[]", self._pkey_size) + res = self._backend._lib.RSA_public_decrypt( + len(self._signature), + self._signature, + buf, + self._public_key._rsa_cdata, + self._backend._lib.RSA_NO_PADDING + ) + if res != self._pkey_size: + errors = self._backend._consume_errors() + assert errors + raise InvalidSignature + + data_to_verify = self._hash_ctx.finalize() + res = self._backend._lib.RSA_verify_PKCS1_PSS( + self._public_key._rsa_cdata, + data_to_verify, + evp_md, + buf, + _get_rsa_pss_salt_length( + self._padding, + self._public_key.key_size, + len(data_to_verify) + ) + ) + if res != 1: + errors = self._backend._consume_errors() + assert errors + raise InvalidSignature + + +@utils.register_interface(RSAPrivateKeyWithNumbers) +class _RSAPrivateKey(object): + def __init__(self, backend, rsa_cdata): + self._backend = backend + self._rsa_cdata = rsa_cdata + + evp_pkey = self._backend._lib.EVP_PKEY_new() + assert evp_pkey != self._backend._ffi.NULL + evp_pkey = self._backend._ffi.gc( + evp_pkey, self._backend._lib.EVP_PKEY_free + ) + res = self._backend._lib.EVP_PKEY_set1_RSA(evp_pkey, rsa_cdata) + assert res == 1 + self._evp_pkey = evp_pkey + + self._key_size = self._backend._lib.BN_num_bits(self._rsa_cdata.n) + + key_size = utils.read_only_property("_key_size") + + def signer(self, padding, algorithm): + return _RSASignatureContext(self._backend, self, padding, algorithm) + + def decrypt(self, ciphertext, padding): + key_size_bytes = int(math.ceil(self.key_size / 8.0)) + if key_size_bytes != len(ciphertext): + raise ValueError("Ciphertext length must be equal to key size.") + + return _enc_dec_rsa(self._backend, self, ciphertext, padding) + + def public_key(self): + ctx = self._backend._lib.RSA_new() + assert ctx != self._backend._ffi.NULL + ctx = self._backend._ffi.gc(ctx, self._backend._lib.RSA_free) + ctx.e = self._backend._lib.BN_dup(self._rsa_cdata.e) + ctx.n = self._backend._lib.BN_dup(self._rsa_cdata.n) + res = self._backend._lib.RSA_blinding_on(ctx, self._backend._ffi.NULL) + assert res == 1 + return _RSAPublicKey(self._backend, ctx) + + def private_numbers(self): + return rsa.RSAPrivateNumbers( + p=self._backend._bn_to_int(self._rsa_cdata.p), + q=self._backend._bn_to_int(self._rsa_cdata.q), + d=self._backend._bn_to_int(self._rsa_cdata.d), + dmp1=self._backend._bn_to_int(self._rsa_cdata.dmp1), + dmq1=self._backend._bn_to_int(self._rsa_cdata.dmq1), + iqmp=self._backend._bn_to_int(self._rsa_cdata.iqmp), + public_numbers=rsa.RSAPublicNumbers( + e=self._backend._bn_to_int(self._rsa_cdata.e), + n=self._backend._bn_to_int(self._rsa_cdata.n), + ) + ) + + +@utils.register_interface(RSAPublicKeyWithNumbers) +class _RSAPublicKey(object): + def __init__(self, backend, rsa_cdata): + self._backend = backend + self._rsa_cdata = rsa_cdata + + evp_pkey = self._backend._lib.EVP_PKEY_new() + assert evp_pkey != self._backend._ffi.NULL + evp_pkey = self._backend._ffi.gc( + evp_pkey, self._backend._lib.EVP_PKEY_free + ) + res = self._backend._lib.EVP_PKEY_set1_RSA(evp_pkey, rsa_cdata) + assert res == 1 + self._evp_pkey = evp_pkey + + self._key_size = self._backend._lib.BN_num_bits(self._rsa_cdata.n) + + key_size = utils.read_only_property("_key_size") + + def verifier(self, signature, padding, algorithm): + return _RSAVerificationContext( + self._backend, self, signature, padding, algorithm + ) + + def encrypt(self, plaintext, padding): + return _enc_dec_rsa(self._backend, self, plaintext, padding) + + def public_numbers(self): + return rsa.RSAPublicNumbers( + e=self._backend._bn_to_int(self._rsa_cdata.e), + n=self._backend._bn_to_int(self._rsa_cdata.n), + ) diff --git a/src/cryptography/hazmat/backends/openssl/utils.py b/src/cryptography/hazmat/backends/openssl/utils.py new file mode 100644 index 00000000..408b6146 --- /dev/null +++ b/src/cryptography/hazmat/backends/openssl/utils.py @@ -0,0 +1,35 @@ +# 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 + + +def _truncate_digest(digest, order_bits): + digest_len = len(digest) + + if 8 * digest_len > order_bits: + digest_len = (order_bits + 7) // 8 + digest = digest[:digest_len] + + if 8 * digest_len > order_bits: + rshift = 8 - (order_bits & 0x7) + assert rshift > 0 and rshift < 8 + + mask = 0xFF >> rshift << rshift + + # Set the bottom rshift bits to 0 + digest = digest[:-1] + six.int2byte(six.indexbytes(digest, -1) & mask) + + return digest diff --git a/src/cryptography/hazmat/bindings/__init__.py b/src/cryptography/hazmat/bindings/__init__.py new file mode 100644 index 00000000..2f420574 --- /dev/null +++ b/src/cryptography/hazmat/bindings/__init__.py @@ -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 diff --git a/src/cryptography/hazmat/bindings/commoncrypto/__init__.py b/src/cryptography/hazmat/bindings/commoncrypto/__init__.py new file mode 100644 index 00000000..2f420574 --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/__init__.py @@ -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 diff --git a/src/cryptography/hazmat/bindings/commoncrypto/binding.py b/src/cryptography/hazmat/bindings/commoncrypto/binding.py new file mode 100644 index 00000000..bb950aac --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/binding.py @@ -0,0 +1,60 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +from cryptography.hazmat.bindings.utils import ( + build_ffi_for_binding, load_library_for_binding, +) + + +class Binding(object): + """ + CommonCrypto API wrapper. + """ + _module_prefix = "cryptography.hazmat.bindings.commoncrypto." + _modules = [ + "cf", + "common_digest", + "common_hmac", + "common_key_derivation", + "common_cryptor", + "secimport", + "secitem", + "seckey", + "seckeychain", + "sectransform", + ] + + ffi = build_ffi_for_binding( + module_prefix=_module_prefix, + modules=_modules, + extra_link_args=[ + "-framework", "Security", "-framework", "CoreFoundation" + ], + ) + lib = None + + def __init__(self): + self._ensure_ffi_initialized() + + @classmethod + def _ensure_ffi_initialized(cls): + if cls.lib is not None: + return + + cls.lib = load_library_for_binding( + cls.ffi, + module_prefix=cls._module_prefix, + modules=cls._modules, + ) diff --git a/src/cryptography/hazmat/bindings/commoncrypto/cf.py b/src/cryptography/hazmat/bindings/commoncrypto/cf.py new file mode 100644 index 00000000..671963a3 --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/cf.py @@ -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 +""" + +TYPES = """ +typedef bool Boolean; +typedef signed long OSStatus; +typedef unsigned char UInt8; +typedef uint32_t UInt32; + +typedef const void * CFAllocatorRef; +const CFAllocatorRef kCFAllocatorDefault; +typedef const void * CFDataRef; +typedef signed long long CFIndex; +typedef ... *CFStringRef; +typedef ... *CFArrayRef; +typedef ... *CFBooleanRef; +typedef ... *CFErrorRef; +typedef ... *CFNumberRef; +typedef ... *CFTypeRef; +typedef ... *CFDictionaryRef; +typedef ... *CFMutableDictionaryRef; +typedef struct { + ...; +} CFDictionaryKeyCallBacks; +typedef struct { + ...; +} CFDictionaryValueCallBacks; +typedef struct { + ...; +} CFRange; + +typedef UInt32 CFStringEncoding; +enum { + kCFStringEncodingASCII = 0x0600 +}; + +enum { + kCFNumberSInt8Type = 1, + kCFNumberSInt16Type = 2, + kCFNumberSInt32Type = 3, + kCFNumberSInt64Type = 4, + kCFNumberFloat32Type = 5, + kCFNumberFloat64Type = 6, + kCFNumberCharType = 7, + kCFNumberShortType = 8, + kCFNumberIntType = 9, + kCFNumberLongType = 10, + kCFNumberLongLongType = 11, + kCFNumberFloatType = 12, + kCFNumberDoubleType = 13, + kCFNumberCFIndexType = 14, + kCFNumberNSIntegerType = 15, + kCFNumberCGFloatType = 16, + kCFNumberMaxType = 16 +}; +typedef int CFNumberType; + +const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; +const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; + +const CFBooleanRef kCFBooleanTrue; +const CFBooleanRef kCFBooleanFalse; +""" + +FUNCTIONS = """ +CFDataRef CFDataCreate(CFAllocatorRef, const UInt8 *, CFIndex); +CFStringRef CFStringCreateWithCString(CFAllocatorRef, const char *, + CFStringEncoding); +CFDictionaryRef CFDictionaryCreate(CFAllocatorRef, const void **, + const void **, CFIndex, + const CFDictionaryKeyCallBacks *, + const CFDictionaryValueCallBacks *); +CFMutableDictionaryRef CFDictionaryCreateMutable( + CFAllocatorRef, + CFIndex, + const CFDictionaryKeyCallBacks *, + const CFDictionaryValueCallBacks * +); +void CFDictionarySetValue(CFMutableDictionaryRef, const void *, const void *); +CFIndex CFArrayGetCount(CFArrayRef); +const void *CFArrayGetValueAtIndex(CFArrayRef, CFIndex); +CFIndex CFDataGetLength(CFDataRef); +void CFDataGetBytes(CFDataRef, CFRange, UInt8 *); +CFRange CFRangeMake(CFIndex, CFIndex); +void CFShow(CFTypeRef); +Boolean CFBooleanGetValue(CFBooleanRef); +CFNumberRef CFNumberCreate(CFAllocatorRef, CFNumberType, const void *); +void CFRelease(CFTypeRef); +CFTypeRef CFRetain(CFTypeRef); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py b/src/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py new file mode 100644 index 00000000..713bc566 --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/common_cryptor.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/commoncrypto/common_digest.py b/src/cryptography/hazmat/bindings/commoncrypto/common_digest.py new file mode 100644 index 00000000..c59200cb --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/common_digest.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/commoncrypto/common_hmac.py b/src/cryptography/hazmat/bindings/commoncrypto/common_hmac.py new file mode 100644 index 00000000..4f54b62b --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/common_hmac.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py b/src/cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py new file mode 100644 index 00000000..e8cc03ef --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/common_key_derivation.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/commoncrypto/secimport.py b/src/cryptography/hazmat/bindings/commoncrypto/secimport.py new file mode 100644 index 00000000..add62c79 --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/secimport.py @@ -0,0 +1,95 @@ +# 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 +""" + +TYPES = """ +typedef ... *SecAccessRef; + +CFStringRef kSecImportExportPassphrase; +CFStringRef kSecImportExportKeychain; +CFStringRef kSecImportExportAccess; + +typedef uint32_t SecExternalItemType; +enum { + kSecItemTypeUnknown, + kSecItemTypePrivateKey, + kSecItemTypePublicKey, + kSecItemTypeSessionKey, + kSecItemTypeCertificate, + kSecItemTypeAggregate +}; + + +typedef uint32_t SecExternalFormat; +enum { + kSecFormatUnknown = 0, + kSecFormatOpenSSL, + kSecFormatSSH, + kSecFormatBSAFE, + kSecFormatRawKey, + kSecFormatWrappedPKCS8, + kSecFormatWrappedOpenSSL, + kSecFormatWrappedSSH, + kSecFormatWrappedLSH, + kSecFormatX509Cert, + kSecFormatPEMSequence, + kSecFormatPKCS7, + kSecFormatPKCS12, + kSecFormatNetscapeCertSequence, + kSecFormatSSHv2 +}; + +typedef uint32_t SecItemImportExportFlags; +enum { + kSecKeyImportOnlyOne = 0x00000001, + kSecKeySecurePassphrase = 0x00000002, + kSecKeyNoAccessControl = 0x00000004 +}; +typedef uint32_t SecKeyImportExportFlags; + +typedef struct { + /* for import and export */ + uint32_t version; + SecKeyImportExportFlags flags; + CFTypeRef passphrase; + CFStringRef alertTitle; + CFStringRef alertPrompt; + + /* for import only */ + SecAccessRef accessRef; + CFArrayRef keyUsage; + + CFArrayRef keyAttributes; +} SecItemImportExportKeyParameters; +""" + +FUNCTIONS = """ +OSStatus SecItemImport(CFDataRef, CFStringRef, SecExternalFormat *, + SecExternalItemType *, SecItemImportExportFlags, + const SecItemImportExportKeyParameters *, + SecKeychainRef, CFArrayRef *); +OSStatus SecPKCS12Import(CFDataRef, CFDictionaryRef, CFArrayRef *); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/commoncrypto/secitem.py b/src/cryptography/hazmat/bindings/commoncrypto/secitem.py new file mode 100644 index 00000000..ac3dad3f --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/secitem.py @@ -0,0 +1,38 @@ +# 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 +""" + +TYPES = """ +const CFTypeRef kSecAttrKeyType; +const CFTypeRef kSecAttrKeySizeInBits; +const CFTypeRef kSecAttrIsPermanent; +const CFTypeRef kSecAttrKeyTypeRSA; +const CFTypeRef kSecAttrKeyTypeDSA; +const CFTypeRef kSecUseKeychain; +""" + +FUNCTIONS = """ +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/commoncrypto/seckey.py b/src/cryptography/hazmat/bindings/commoncrypto/seckey.py new file mode 100644 index 00000000..5e4b6dac --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/seckey.py @@ -0,0 +1,35 @@ +# 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 +""" + +TYPES = """ +typedef ... *SecKeyRef; +""" + +FUNCTIONS = """ +OSStatus SecKeyGeneratePair(CFDictionaryRef, SecKeyRef *, SecKeyRef *); +size_t SecKeyGetBlockSize(SecKeyRef); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/commoncrypto/seckeychain.py b/src/cryptography/hazmat/bindings/commoncrypto/seckeychain.py new file mode 100644 index 00000000..c045c347 --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/seckeychain.py @@ -0,0 +1,36 @@ +# 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 +""" + +TYPES = """ +typedef ... *SecKeychainRef; +""" + +FUNCTIONS = """ +OSStatus SecKeychainCreate(const char *, UInt32, const void *, Boolean, + SecAccessRef, SecKeychainRef *); +OSStatus SecKeychainDelete(SecKeychainRef); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/commoncrypto/sectransform.py b/src/cryptography/hazmat/bindings/commoncrypto/sectransform.py new file mode 100644 index 00000000..d6dbc5f6 --- /dev/null +++ b/src/cryptography/hazmat/bindings/commoncrypto/sectransform.py @@ -0,0 +1,79 @@ +# 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 +#include +#include +""" + +TYPES = """ +typedef ... *SecTransformRef; + +CFStringRef kSecImportExportPassphrase; +CFStringRef kSecImportExportKeychain; +CFStringRef kSecImportExportAccess; + +CFStringRef kSecEncryptionMode; +CFStringRef kSecEncryptKey; +CFStringRef kSecIVKey; +CFStringRef kSecModeCBCKey; +CFStringRef kSecModeCFBKey; +CFStringRef kSecModeECBKey; +CFStringRef kSecModeNoneKey; +CFStringRef kSecModeOFBKey; +CFStringRef kSecOAEPEncodingParametersAttributeName; +CFStringRef kSecPaddingKey; +CFStringRef kSecPaddingNoneKey; +CFStringRef kSecPaddingOAEPKey; +CFStringRef kSecPaddingPKCS1Key; +CFStringRef kSecPaddingPKCS5Key; +CFStringRef kSecPaddingPKCS7Key; + +const CFStringRef kSecTransformInputAttributeName; +const CFStringRef kSecTransformOutputAttributeName; +const CFStringRef kSecTransformDebugAttributeName; +const CFStringRef kSecTransformTransformName; +const CFStringRef kSecTransformAbortAttributeName; + +CFStringRef kSecInputIsAttributeName; +CFStringRef kSecInputIsPlainText; +CFStringRef kSecInputIsDigest; +CFStringRef kSecInputIsRaw; + +const CFStringRef kSecDigestTypeAttribute; +const CFStringRef kSecDigestLengthAttribute; +const CFStringRef kSecDigestMD5; +const CFStringRef kSecDigestSHA1; +const CFStringRef kSecDigestSHA2; +""" + +FUNCTIONS = """ +Boolean SecTransformSetAttribute(SecTransformRef, CFStringRef, CFTypeRef, + CFErrorRef *); +SecTransformRef SecDecryptTransformCreate(SecKeyRef, CFErrorRef *); +SecTransformRef SecEncryptTransformCreate(SecKeyRef, CFErrorRef *); +SecTransformRef SecVerifyTransformCreate(SecKeyRef, CFDataRef, CFErrorRef *); +SecTransformRef SecSignTransformCreate(SecKeyRef, CFErrorRef *) ; +CFTypeRef SecTransformExecute(SecTransformRef, CFErrorRef *); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/openssl/__init__.py b/src/cryptography/hazmat/bindings/openssl/__init__.py new file mode 100644 index 00000000..2f420574 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/__init__.py @@ -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 diff --git a/src/cryptography/hazmat/bindings/openssl/aes.py b/src/cryptography/hazmat/bindings/openssl/aes.py new file mode 100644 index 00000000..e4071523 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/aes.py @@ -0,0 +1,70 @@ +# 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 +""" + +TYPES = """ +static const int Cryptography_HAS_AES_WRAP; + +struct aes_key_st { + ...; +}; +typedef struct aes_key_st AES_KEY; +""" + +FUNCTIONS = """ +int AES_set_encrypt_key(const unsigned char *, const int, AES_KEY *); +int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *); +""" + +MACROS = """ +/* these can be moved back to FUNCTIONS once we drop support for 0.9.8h. + This should be when we drop RHEL/CentOS 5, which is on 0.9.8e. */ +int AES_wrap_key(AES_KEY *, const unsigned char *, unsigned char *, + const unsigned char *, unsigned int); +int AES_unwrap_key(AES_KEY *, const unsigned char *, unsigned char *, + const unsigned char *, unsigned int); + +/* The ctr128_encrypt function is only useful in 0.9.8. You should use EVP for + this in 1.0.0+. It is defined in macros because the function signature + changed after 0.9.8 */ +void AES_ctr128_encrypt(const unsigned char *, unsigned char *, + const size_t, const AES_KEY *, + unsigned char[], unsigned char[], unsigned int *); + +""" + +CUSTOMIZATIONS = """ +/* OpenSSL 0.9.8h+ */ +#if OPENSSL_VERSION_NUMBER >= 0x0090808fL +static const long Cryptography_HAS_AES_WRAP = 1; +#else +static const long Cryptography_HAS_AES_WRAP = 0; +int (*AES_wrap_key)(AES_KEY *, const unsigned char *, unsigned char *, + const unsigned char *, unsigned int) = NULL; +int (*AES_unwrap_key)(AES_KEY *, const unsigned char *, unsigned char *, + const unsigned char *, unsigned int) = NULL; +#endif + +""" + +CONDITIONAL_NAMES = { + "Cryptography_HAS_AES_WRAP": [ + "AES_wrap_key", + "AES_unwrap_key", + ], +} diff --git a/src/cryptography/hazmat/bindings/openssl/asn1.py b/src/cryptography/hazmat/bindings/openssl/asn1.py new file mode 100644 index 00000000..2edfd2d8 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/asn1.py @@ -0,0 +1,152 @@ +# 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 +""" + +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: + * + * I think you want to declare your value too large (e.g. long) + * that way you'll never pass garbage + */ +typedef intptr_t time_t; + +typedef int ASN1_BOOLEAN; +typedef ... ASN1_INTEGER; + +struct asn1_string_st { + int length; + int type; + unsigned char *data; + long flags; +}; + +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef ... ASN1_OBJECT; +typedef ... ASN1_STRING; +typedef ... ASN1_TYPE; +typedef ... ASN1_GENERALIZEDTIME; +typedef ... ASN1_ENUMERATED; +typedef ... ASN1_ITEM; +typedef ... ASN1_VALUE; + +typedef struct { + ...; +} ASN1_TIME; +typedef ... ASN1_ITEM_EXP; + +typedef ... ASN1_UTCTIME; + +static const int V_ASN1_GENERALIZEDTIME; + +static const int MBSTRING_UTF8; +""" + +FUNCTIONS = """ +ASN1_OBJECT *ASN1_OBJECT_new(void); +void ASN1_OBJECT_free(ASN1_OBJECT *); + +/* ASN1 OBJECT IDENTIFIER */ +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **, const unsigned char **, long); +int i2d_ASN1_OBJECT(ASN1_OBJECT *, unsigned char **); + +/* ASN1 STRING */ +ASN1_STRING *ASN1_STRING_new(void); +ASN1_STRING *ASN1_STRING_type_new(int); +void ASN1_STRING_free(ASN1_STRING *); +unsigned char *ASN1_STRING_data(ASN1_STRING *); +int ASN1_STRING_set(ASN1_STRING *, const void *, int); +int ASN1_STRING_type(ASN1_STRING *); +int ASN1_STRING_to_UTF8(unsigned char **, ASN1_STRING *); + +/* ASN1 OCTET STRING */ +ASN1_OCTET_STRING *ASN1_OCTET_STRING_new(void); +void ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *, const unsigned char *, int); + +/* ASN1 INTEGER */ +ASN1_INTEGER *ASN1_INTEGER_new(void); +void ASN1_INTEGER_free(ASN1_INTEGER *); +int ASN1_INTEGER_set(ASN1_INTEGER *, long); +int i2a_ASN1_INTEGER(BIO *, ASN1_INTEGER *); + +/* ASN1 TIME */ +ASN1_TIME *ASN1_TIME_new(void); +void ASN1_TIME_free(ASN1_TIME *); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *, + ASN1_GENERALIZEDTIME **); + +/* ASN1 UTCTIME */ +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *, time_t); + +/* ASN1 GENERALIZEDTIME */ +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *, const char *); +void ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *); + +/* ASN1 ENUMERATED */ +ASN1_ENUMERATED *ASN1_ENUMERATED_new(void); +void ASN1_ENUMERATED_free(ASN1_ENUMERATED *); +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *, long); + +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **, const unsigned char **, long, + const ASN1_ITEM *); +""" + +MACROS = """ +ASN1_TIME *M_ASN1_TIME_dup(void *); +const ASN1_ITEM *ASN1_ITEM_ptr(ASN1_ITEM_EXP *); + +/* These aren't macros these arguments are all const X on openssl > 1.0.x */ + +int ASN1_STRING_length(ASN1_STRING *); +ASN1_STRING *ASN1_STRING_dup(ASN1_STRING *); +int ASN1_STRING_cmp(ASN1_STRING *, ASN1_STRING *); + +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *); +int ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *, ASN1_OCTET_STRING *); + +ASN1_INTEGER *ASN1_INTEGER_dup(ASN1_INTEGER *); +int ASN1_INTEGER_cmp(ASN1_INTEGER *, ASN1_INTEGER *); +long ASN1_INTEGER_get(ASN1_INTEGER *); + +BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *, BIGNUM *); +ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *, ASN1_INTEGER *); + +/* These isn't a macro the arg is const on openssl 1.0.2+ */ +int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *); + +/* Not a macro, const on openssl 1.0 */ +int ASN1_STRING_set_default_mask_asc(char *); +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/openssl/bignum.py b/src/cryptography/hazmat/bindings/openssl/bignum.py new file mode 100644 index 00000000..1d944ee9 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/bignum.py @@ -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 +""" + +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: + * + * I think you want to declare your value too large (e.g. long) + * 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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/binding.py b/src/cryptography/hazmat/bindings/openssl/binding.py new file mode 100644 index 00000000..ff9039cf --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/binding.py @@ -0,0 +1,176 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import, division, print_function + +import os +import sys +import threading + +from cryptography.hazmat.bindings.utils import ( + build_ffi_for_binding, load_library_for_binding, +) + + +_OSX_PRE_INCLUDE = """ +#ifdef __APPLE__ +#include +#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 +""" + + +def _get_libraries(platform): + # OpenSSL goes by a different library name on different operating systems. + if platform != "win32": + # In some circumstances, the order in which these libs are + # specified on the linker command-line is significant; + # libssl must come before libcrypto + # (http://marc.info/?l=openssl-users&m=135361825921871) + return ["ssl", "crypto"] + else: + link_type = os.environ.get("PYCA_WINDOWS_LINK_TYPE", "static") + return _get_windows_libraries(link_type) + + +def _get_windows_libraries(link_type): + if link_type == "dynamic": + return ["libeay32", "ssleay32", "advapi32"] + elif link_type == "static" or link_type == "": + return ["libeay32mt", "ssleay32mt", "advapi32", + "crypt32", "gdi32", "user32", "ws2_32"] + else: + raise ValueError( + "PYCA_WINDOWS_LINK_TYPE must be 'static' or 'dynamic'" + ) + + +class Binding(object): + """ + OpenSSL API wrapper. + """ + _module_prefix = "cryptography.hazmat.bindings.openssl." + _modules = [ + "aes", + "asn1", + "bignum", + "bio", + "cmac", + "cms", + "conf", + "crypto", + "dh", + "dsa", + "ec", + "ecdh", + "ecdsa", + "engine", + "err", + "evp", + "hmac", + "nid", + "objects", + "opensslv", + "osrandom_engine", + "pem", + "pkcs7", + "pkcs12", + "rand", + "rsa", + "ssl", + "x509", + "x509name", + "x509v3", + "x509_vfy" + ] + + _locks = None + _lock_cb_handle = None + _lock_init_lock = threading.Lock() + + ffi = build_ffi_for_binding( + module_prefix=_module_prefix, + modules=_modules, + pre_include=_OSX_PRE_INCLUDE, + post_include=_OSX_POST_INCLUDE, + libraries=_get_libraries(sys.platform) + ) + lib = None + + def __init__(self): + self._ensure_ffi_initialized() + + @classmethod + def _ensure_ffi_initialized(cls): + if cls.lib is not None: + return + + cls.lib = load_library_for_binding( + cls.ffi, + cls._module_prefix, + cls._modules, + ) + + res = cls.lib.Cryptography_add_osrandom_engine() + assert res != 0 + + @classmethod + def init_static_locks(cls): + with cls._lock_init_lock: + cls._ensure_ffi_initialized() + + if not cls._lock_cb_handle: + cls._lock_cb_handle = cls.ffi.callback( + "void(int, int, const char *, int)", + cls._lock_cb + ) + + # Use Python's implementation if available, importing _ssl triggers + # the setup for this. + __import__("_ssl") + + if cls.lib.CRYPTO_get_locking_callback() != cls.ffi.NULL: + return + + # If nothing else has setup a locking callback already, we set up + # our own + num_locks = cls.lib.CRYPTO_num_locks() + cls._locks = [threading.Lock() for n in range(num_locks)] + + cls.lib.CRYPTO_set_locking_callback(cls._lock_cb_handle) + + @classmethod + def _lock_cb(cls, mode, n, file, line): + lock = cls._locks[n] + + if mode & cls.lib.CRYPTO_LOCK: + lock.acquire() + elif mode & cls.lib.CRYPTO_UNLOCK: + lock.release() + else: + raise RuntimeError( + "Unknown lock mode {0}: lock={1}, file={2}, line={3}.".format( + mode, n, file, line + ) + ) diff --git a/src/cryptography/hazmat/bindings/openssl/bio.py b/src/cryptography/hazmat/bindings/openssl/bio.py new file mode 100644 index 00000000..cfe6034f --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/bio.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/cmac.py b/src/cryptography/hazmat/bindings/openssl/cmac.py new file mode 100644 index 00000000..c8bcc824 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/cmac.py @@ -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 +#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", + ], +} diff --git a/src/cryptography/hazmat/bindings/openssl/cms.py b/src/cryptography/hazmat/bindings/openssl/cms.py new file mode 100644 index 00000000..cbf4b283 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/cms.py @@ -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 +#endif +#include +#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", + ] +} diff --git a/src/cryptography/hazmat/bindings/openssl/conf.py b/src/cryptography/hazmat/bindings/openssl/conf.py new file mode 100644 index 00000000..001a0707 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/conf.py @@ -0,0 +1,35 @@ +# 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 +""" + +TYPES = """ +typedef ... CONF; +""" + +FUNCTIONS = """ +void OPENSSL_config(const char *); +void OPENSSL_no_config(void); +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/openssl/crypto.py b/src/cryptography/hazmat/bindings/openssl/crypto.py new file mode 100644 index 00000000..99e1a61d --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/crypto.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/dh.py b/src/cryptography/hazmat/bindings/openssl/dh.py new file mode 100644 index 00000000..e2e8976e --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/dh.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/dsa.py b/src/cryptography/hazmat/bindings/openssl/dsa.py new file mode 100644 index 00000000..c9aa8882 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/dsa.py @@ -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 +""" + +TYPES = """ +typedef struct dsa_st { + /* Prime number (public) */ + BIGNUM *p; + /* Subprime (160-bit, q | p-1, public) */ + BIGNUM *q; + /* Generator of subgroup (public) */ + BIGNUM *g; + /* Private key x */ + BIGNUM *priv_key; + /* Public key y = g^x */ + BIGNUM *pub_key; + ...; +} DSA; +typedef struct { + BIGNUM *r; + BIGNUM *s; +} DSA_SIG; +""" + +FUNCTIONS = """ +DSA *DSA_generate_parameters(int, unsigned char *, int, int *, unsigned long *, + void (*)(int, int, void *), void *); +int DSA_generate_key(DSA *); +DSA *DSA_new(void); +void DSA_free(DSA *); +DSA_SIG *DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *); +int i2d_DSA_SIG(const DSA_SIG *, unsigned char **); +DSA_SIG *d2i_DSA_SIG(DSA_SIG **, const unsigned char **, long); +int DSA_size(const DSA *); +int DSA_sign(int, const unsigned char *, int, unsigned char *, unsigned int *, + DSA *); +int DSA_verify(int, const unsigned char *, int, const unsigned char *, int, + DSA *); +""" + +MACROS = """ +int DSA_generate_parameters_ex(DSA *, int, unsigned char *, int, + int *, unsigned long *, BN_GENCB *); +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/openssl/ec.py b/src/cryptography/hazmat/bindings/openssl/ec.py new file mode 100644 index 00000000..26fc8ff0 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/ec.py @@ -0,0 +1,490 @@ +# 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 +#endif + +#include +""" + +TYPES = """ +static const int Cryptography_HAS_EC; +static const int Cryptography_HAS_EC_1_0_1; +static const int Cryptography_HAS_EC_NISTP_64_GCC_128; +static const int Cryptography_HAS_EC2M; + +static const int OPENSSL_EC_NAMED_CURVE; + +typedef ... EC_KEY; +typedef ... EC_GROUP; +typedef ... EC_POINT; +typedef ... EC_METHOD; +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; +typedef enum { ... } point_conversion_form_t; +""" + +FUNCTIONS = """ +""" + +MACROS = """ +EC_GROUP *EC_GROUP_new(const EC_METHOD *); +void EC_GROUP_free(EC_GROUP *); +void EC_GROUP_clear_free(EC_GROUP *); + +EC_GROUP *EC_GROUP_new_curve_GFp( + const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); +EC_GROUP *EC_GROUP_new_curve_GF2m( + const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); +EC_GROUP *EC_GROUP_new_by_curve_name(int); + +int EC_GROUP_set_curve_GFp( + EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); +int EC_GROUP_get_curve_GFp( + const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *); +int EC_GROUP_set_curve_GF2m( + EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); +int EC_GROUP_get_curve_GF2m( + const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *); + +int EC_GROUP_get_degree(const EC_GROUP *); + +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *); +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *); +int EC_GROUP_get_curve_name(const EC_GROUP *); + +size_t EC_get_builtin_curves(EC_builtin_curve *, size_t); + +void EC_KEY_free(EC_KEY *); + +int EC_KEY_get_flags(const EC_KEY *); +void EC_KEY_set_flags(EC_KEY *, int); +void EC_KEY_clear_flags(EC_KEY *, int); +EC_KEY *EC_KEY_new_by_curve_name(int); +EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *); +EC_KEY *EC_KEY_dup(const EC_KEY *); +int EC_KEY_up_ref(EC_KEY *); +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *); +int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *, BN_CTX *); +int EC_KEY_set_group(EC_KEY *, const EC_GROUP *); +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *); +int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *); +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *); +int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *); +unsigned int EC_KEY_get_enc_flags(const EC_KEY *); +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *); +void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t); +void *EC_KEY_get_key_method_data( + EC_KEY *, + void *(*)(void *), + void (*)(void *), + void (*)(void *) +); +void EC_KEY_insert_key_method_data( + EC_KEY *, + void *, + void *(*)(void *), + void (*)(void *), + void (*)(void *) +); +void EC_KEY_set_asn1_flag(EC_KEY *, int); +int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *); +int EC_KEY_generate_key(EC_KEY *); +int EC_KEY_check_key(const EC_KEY *); +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *, BIGNUM *, BIGNUM *); + +EC_POINT *EC_POINT_new(const EC_GROUP *); +void EC_POINT_free(EC_POINT *); +void EC_POINT_clear_free(EC_POINT *); +int EC_POINT_copy(EC_POINT *, const EC_POINT *); +EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *); +const EC_METHOD *EC_POINT_method_of(const EC_POINT *); + +int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *); + +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *, + const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *, + const EC_POINT *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *); + +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *, + const BIGNUM *, const BIGNUM *, BN_CTX *); + +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, + const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *); + +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *, + const BIGNUM *, int, BN_CTX *); + +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *, + const BIGNUM *, const BIGNUM *, BN_CTX *); + +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, + const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *); + +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *, + const BIGNUM *, int, BN_CTX *); + +size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t, + unsigned char *, size_t, BN_CTX *); + +int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *, + const unsigned char *, size_t, BN_CTX *); + +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); + +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, + EC_POINT *, BN_CTX *); + +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *); + +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, + EC_POINT *, BN_CTX *); + +int EC_POINT_add(const EC_GROUP *, EC_POINT *, const EC_POINT *, + const EC_POINT *, BN_CTX *); + +int EC_POINT_dbl(const EC_GROUP *, EC_POINT *, const EC_POINT *, BN_CTX *); +int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); +int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *); +int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); + +int EC_POINT_cmp( + const EC_GROUP *, const EC_POINT *, const EC_POINT *, BN_CTX *); + +int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); +int EC_POINTs_make_affine(const EC_GROUP *, size_t, EC_POINT *[], BN_CTX *); + +int EC_POINTs_mul( + const EC_GROUP *, EC_POINT *, const BIGNUM *, + size_t, const EC_POINT *[], const BIGNUM *[], BN_CTX *); + +int EC_POINT_mul(const EC_GROUP *, EC_POINT *, const BIGNUM *, + const EC_POINT *, const BIGNUM *, BN_CTX *); + +int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *); +int EC_GROUP_have_precompute_mult(const EC_GROUP *); + +const EC_METHOD *EC_GFp_simple_method(); +const EC_METHOD *EC_GFp_mont_method(); +const EC_METHOD *EC_GFp_nist_method(); + +const EC_METHOD *EC_GFp_nistp224_method(); +const EC_METHOD *EC_GFp_nistp256_method(); +const EC_METHOD *EC_GFp_nistp521_method(); + +const EC_METHOD *EC_GF2m_simple_method(); + +int EC_METHOD_get_field_type(const EC_METHOD *); +""" + +CUSTOMIZATIONS = """ +#ifdef OPENSSL_NO_EC +static const long Cryptography_HAS_EC = 0; + +typedef void EC_KEY; +typedef void EC_GROUP; +typedef void EC_POINT; +typedef void EC_METHOD; +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; +typedef long point_conversion_form_t; + +static const int OPENSSL_EC_NAMED_CURVE = 0; + +void (*EC_KEY_free)(EC_KEY *) = NULL; +size_t (*EC_get_builtin_curves)(EC_builtin_curve *, size_t) = NULL; +EC_KEY *(*EC_KEY_new_by_curve_name)(int) = NULL; +EC_KEY *(*EC_KEY_copy)(EC_KEY *, const EC_KEY *) = NULL; +EC_KEY *(*EC_KEY_dup)(const EC_KEY *) = NULL; +int (*EC_KEY_up_ref)(EC_KEY *) = NULL; +const EC_GROUP *(*EC_KEY_get0_group)(const EC_KEY *) = NULL; +int (*EC_GROUP_get_order)(const EC_GROUP *, BIGNUM *, BN_CTX *) = NULL; +int (*EC_KEY_set_group)(EC_KEY *, const EC_GROUP *) = NULL; +const BIGNUM *(*EC_KEY_get0_private_key)(const EC_KEY *) = NULL; +int (*EC_KEY_set_private_key)(EC_KEY *, const BIGNUM *) = NULL; +const EC_POINT *(*EC_KEY_get0_public_key)(const EC_KEY *) = NULL; +int (*EC_KEY_set_public_key)(EC_KEY *, const EC_POINT *) = NULL; +unsigned int (*EC_KEY_get_enc_flags)(const EC_KEY *) = NULL; +void (*EC_KEY_set_enc_flags)(EC_KEY *eckey, unsigned int) = NULL; +point_conversion_form_t (*EC_KEY_get_conv_form)(const EC_KEY *) = NULL; +void (*EC_KEY_set_conv_form)(EC_KEY *, point_conversion_form_t) = NULL; +void *(*EC_KEY_get_key_method_data)( + EC_KEY *, void *(*)(void *), void (*)(void *), void (*)(void *)) = NULL; +void (*EC_KEY_insert_key_method_data)( + EC_KEY *, void *, + void *(*)(void *), void (*)(void *), void (*)(void *)) = NULL; +void (*EC_KEY_set_asn1_flag)(EC_KEY *, int) = NULL; +int (*EC_KEY_precompute_mult)(EC_KEY *, BN_CTX *) = NULL; +int (*EC_KEY_generate_key)(EC_KEY *) = NULL; +int (*EC_KEY_check_key)(const EC_KEY *) = NULL; + +EC_GROUP *(*EC_GROUP_new)(const EC_METHOD *); +void (*EC_GROUP_free)(EC_GROUP *); +void (*EC_GROUP_clear_free)(EC_GROUP *); + +EC_GROUP *(*EC_GROUP_new_curve_GFp)( + const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + +EC_GROUP *(*EC_GROUP_new_by_curve_name)(int); + +int (*EC_GROUP_set_curve_GFp)( + EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + +int (*EC_GROUP_get_curve_GFp)( + const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *); + +int (*EC_GROUP_get_degree)(const EC_GROUP *) = NULL; + +const EC_METHOD *(*EC_GROUP_method_of)(const EC_GROUP *) = NULL; +const EC_POINT *(*EC_GROUP_get0_generator)(const EC_GROUP *) = NULL; +int (*EC_GROUP_get_curve_name)(const EC_GROUP *) = NULL; + +EC_POINT *(*EC_POINT_new)(const EC_GROUP *) = NULL; +void (*EC_POINT_free)(EC_POINT *) = NULL; +void (*EC_POINT_clear_free)(EC_POINT *) = NULL; +int (*EC_POINT_copy)(EC_POINT *, const EC_POINT *) = NULL; +EC_POINT *(*EC_POINT_dup)(const EC_POINT *, const EC_GROUP *) = NULL; +const EC_METHOD *(*EC_POINT_method_of)(const EC_POINT *) = NULL; +int (*EC_POINT_set_to_infinity)(const EC_GROUP *, EC_POINT *) = NULL; +int (*EC_POINT_set_Jprojective_coordinates_GFp)(const EC_GROUP *, EC_POINT *, + const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL; + +int (*EC_POINT_get_Jprojective_coordinates_GFp)(const EC_GROUP *, + const EC_POINT *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL; + +int (*EC_POINT_set_affine_coordinates_GFp)(const EC_GROUP *, EC_POINT *, + const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL; + +int (*EC_POINT_get_affine_coordinates_GFp)(const EC_GROUP *, + const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL; + +int (*EC_POINT_set_compressed_coordinates_GFp)(const EC_GROUP *, EC_POINT *, + const BIGNUM *, int, BN_CTX *) = NULL; + +size_t (*EC_POINT_point2oct)(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t, + unsigned char *, size_t, BN_CTX *) = NULL; + +int (*EC_POINT_oct2point)(const EC_GROUP *, EC_POINT *, + const unsigned char *, size_t, BN_CTX *) = NULL; + +BIGNUM *(*EC_POINT_point2bn)(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *) = NULL; + +EC_POINT *(*EC_POINT_bn2point)(const EC_GROUP *, const BIGNUM *, + EC_POINT *, BN_CTX *) = NULL; + +char *(*EC_POINT_point2hex)(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *) = NULL; + +EC_POINT *(*EC_POINT_hex2point)(const EC_GROUP *, const char *, + EC_POINT *, BN_CTX *) = NULL; + +int (*EC_POINT_add)(const EC_GROUP *, EC_POINT *, const EC_POINT *, + const EC_POINT *, BN_CTX *) = NULL; + +int (*EC_POINT_dbl)(const EC_GROUP *, EC_POINT *, const EC_POINT *, + BN_CTX *) = NULL; + +int (*EC_POINT_invert)(const EC_GROUP *, EC_POINT *, BN_CTX *) = NULL; +int (*EC_POINT_is_at_infinity)(const EC_GROUP *, const EC_POINT *) = NULL; + +int (*EC_POINT_is_on_curve)(const EC_GROUP *, const EC_POINT *, + BN_CTX *) = NULL; + +int (*EC_POINT_cmp)( + const EC_GROUP *, const EC_POINT *, const EC_POINT *, BN_CTX *) = NULL; + +int (*EC_POINT_make_affine)(const EC_GROUP *, EC_POINT *, BN_CTX *) = NULL; + +int (*EC_POINTs_make_affine)(const EC_GROUP *, size_t, EC_POINT *[], + BN_CTX *) = NULL; + +int (*EC_POINTs_mul)( + const EC_GROUP *, EC_POINT *, const BIGNUM *, + size_t, const EC_POINT *[], const BIGNUM *[], BN_CTX *) = NULL; + +int (*EC_POINT_mul)(const EC_GROUP *, EC_POINT *, const BIGNUM *, + const EC_POINT *, const BIGNUM *, BN_CTX *) = NULL; + +int (*EC_GROUP_precompute_mult)(EC_GROUP *, BN_CTX *) = NULL; +int (*EC_GROUP_have_precompute_mult)(const EC_GROUP *) = NULL; + +const EC_METHOD *(*EC_GFp_simple_method)() = NULL; +const EC_METHOD *(*EC_GFp_mont_method)() = NULL; +const EC_METHOD *(*EC_GFp_nist_method)() = NULL; + +int (*EC_METHOD_get_field_type)(const EC_METHOD *) = NULL; + +#else +static const long Cryptography_HAS_EC = 1; +#endif + +#if defined(OPENSSL_NO_EC) || OPENSSL_VERSION_NUMBER < 0x1000100f +static const long Cryptography_HAS_EC_1_0_1 = 0; + +int (*EC_KEY_get_flags)(const EC_KEY *) = NULL; +void (*EC_KEY_set_flags)(EC_KEY *, int) = NULL; +void (*EC_KEY_clear_flags)(EC_KEY *, int) = NULL; + +int (*EC_KEY_set_public_key_affine_coordinates)( + EC_KEY *, BIGNUM *, BIGNUM *) = NULL; +#else +static const long Cryptography_HAS_EC_1_0_1 = 1; +#endif + + +#if defined(OPENSSL_NO_EC) || OPENSSL_VERSION_NUMBER < 0x1000100f || \ + defined(OPENSSL_NO_EC_NISTP_64_GCC_128) +static const long Cryptography_HAS_EC_NISTP_64_GCC_128 = 0; + +const EC_METHOD *(*EC_GFp_nistp224_method)(void) = NULL; +const EC_METHOD *(*EC_GFp_nistp256_method)(void) = NULL; +const EC_METHOD *(*EC_GFp_nistp521_method)(void) = NULL; +#else +static const long Cryptography_HAS_EC_NISTP_64_GCC_128 = 1; +#endif + +#if defined(OPENSSL_NO_EC) || defined(OPENSSL_NO_EC2M) +static const long Cryptography_HAS_EC2M = 0; + +const EC_METHOD *(*EC_GF2m_simple_method)() = NULL; + +int (*EC_POINT_set_affine_coordinates_GF2m)(const EC_GROUP *, EC_POINT *, + const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL; + +int (*EC_POINT_get_affine_coordinates_GF2m)(const EC_GROUP *, + const EC_POINT *, BIGNUM *, BIGNUM *, BN_CTX *) = NULL; + +int (*EC_POINT_set_compressed_coordinates_GF2m)(const EC_GROUP *, EC_POINT *, + const BIGNUM *, int, BN_CTX *) = NULL; + +int (*EC_GROUP_set_curve_GF2m)( + EC_GROUP *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); + +int (*EC_GROUP_get_curve_GF2m)( + const EC_GROUP *, BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *); + +EC_GROUP *(*EC_GROUP_new_curve_GF2m)( + const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); +#else +static const long Cryptography_HAS_EC2M = 1; +#endif +""" + +CONDITIONAL_NAMES = { + "Cryptography_HAS_EC": [ + "OPENSSL_EC_NAMED_CURVE", + "EC_GROUP_new", + "EC_GROUP_free", + "EC_GROUP_clear_free", + "EC_GROUP_new_curve_GFp", + "EC_GROUP_new_by_curve_name", + "EC_GROUP_set_curve_GFp", + "EC_GROUP_get_curve_GFp", + "EC_GROUP_method_of", + "EC_GROUP_get0_generator", + "EC_GROUP_get_curve_name", + "EC_GROUP_get_degree", + "EC_KEY_free", + "EC_get_builtin_curves", + "EC_KEY_new_by_curve_name", + "EC_KEY_copy", + "EC_KEY_dup", + "EC_KEY_up_ref", + "EC_KEY_set_group", + "EC_KEY_get0_private_key", + "EC_KEY_set_private_key", + "EC_KEY_set_public_key", + "EC_KEY_get_enc_flags", + "EC_KEY_set_enc_flags", + "EC_KEY_set_conv_form", + "EC_KEY_get_key_method_data", + "EC_KEY_insert_key_method_data", + "EC_KEY_set_asn1_flag", + "EC_KEY_precompute_mult", + "EC_KEY_generate_key", + "EC_KEY_check_key", + "EC_POINT_new", + "EC_POINT_free", + "EC_POINT_clear_free", + "EC_POINT_copy", + "EC_POINT_dup", + "EC_POINT_method_of", + "EC_POINT_set_to_infinity", + "EC_POINT_set_Jprojective_coordinates_GFp", + "EC_POINT_get_Jprojective_coordinates_GFp", + "EC_POINT_set_affine_coordinates_GFp", + "EC_POINT_get_affine_coordinates_GFp", + "EC_POINT_set_compressed_coordinates_GFp", + "EC_POINT_point2oct", + "EC_POINT_oct2point", + "EC_POINT_point2bn", + "EC_POINT_bn2point", + "EC_POINT_point2hex", + "EC_POINT_hex2point", + "EC_POINT_add", + "EC_POINT_dbl", + "EC_POINT_invert", + "EC_POINT_is_at_infinity", + "EC_POINT_is_on_curve", + "EC_POINT_cmp", + "EC_POINT_make_affine", + "EC_POINTs_make_affine", + "EC_POINTs_mul", + "EC_POINT_mul", + "EC_GROUP_precompute_mult", + "EC_GROUP_have_precompute_mult", + "EC_GFp_simple_method", + "EC_GFp_mont_method", + "EC_GFp_nist_method", + "EC_METHOD_get_field_type", + ], + + "Cryptography_HAS_EC_1_0_1": [ + "EC_KEY_get_flags", + "EC_KEY_set_flags", + "EC_KEY_clear_flags", + "EC_KEY_set_public_key_affine_coordinates", + ], + + "Cryptography_HAS_EC_NISTP_64_GCC_128": [ + "EC_GFp_nistp224_method", + "EC_GFp_nistp256_method", + "EC_GFp_nistp521_method", + ], + + "Cryptography_HAS_EC2M": [ + "EC_GF2m_simple_method", + "EC_POINT_set_affine_coordinates_GF2m", + "EC_POINT_get_affine_coordinates_GF2m", + "EC_POINT_set_compressed_coordinates_GF2m", + "EC_GROUP_set_curve_GF2m", + "EC_GROUP_get_curve_GF2m", + "EC_GROUP_new_curve_GF2m", + ], +} diff --git a/src/cryptography/hazmat/bindings/openssl/ecdh.py b/src/cryptography/hazmat/bindings/openssl/ecdh.py new file mode 100644 index 00000000..960d46fb --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/ecdh.py @@ -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 +#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", + ], +} diff --git a/src/cryptography/hazmat/bindings/openssl/ecdsa.py b/src/cryptography/hazmat/bindings/openssl/ecdsa.py new file mode 100644 index 00000000..bfa67206 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/ecdsa.py @@ -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 +#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", + ], +} diff --git a/src/cryptography/hazmat/bindings/openssl/engine.py b/src/cryptography/hazmat/bindings/openssl/engine.py new file mode 100644 index 00000000..364232e0 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/engine.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/err.py b/src/cryptography/hazmat/bindings/openssl/err.py new file mode 100644 index 00000000..4e44a2eb --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/err.py @@ -0,0 +1,365 @@ +# 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 +""" + +TYPES = """ +static const int Cryptography_HAS_REMOVE_THREAD_STATE; +static const int Cryptography_HAS_098H_ERROR_CODES; +static const int Cryptography_HAS_098C_CAMELLIA_CODES; +static const int Cryptography_HAS_EC_CODES; +static const int Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR; + +struct ERR_string_data_st { + unsigned long error; + const char *string; +}; +typedef struct ERR_string_data_st ERR_STRING_DATA; + +static const int ERR_LIB_EVP; +static const int ERR_LIB_EC; +static const int ERR_LIB_PEM; +static const int ERR_LIB_ASN1; +static const int ERR_LIB_RSA; +static const int ERR_LIB_PKCS12; + +static const int ASN1_F_ASN1_ENUMERATED_TO_BN; +static const int ASN1_F_ASN1_EX_C2I; +static const int ASN1_F_ASN1_FIND_END; +static const int ASN1_F_ASN1_GENERALIZEDTIME_SET; +static const int ASN1_F_ASN1_GENERATE_V3; +static const int ASN1_F_ASN1_GET_OBJECT; +static const int ASN1_F_ASN1_ITEM_I2D_FP; +static const int ASN1_F_ASN1_ITEM_PACK; +static const int ASN1_F_ASN1_ITEM_SIGN; +static const int ASN1_F_ASN1_ITEM_UNPACK; +static const int ASN1_F_ASN1_ITEM_VERIFY; +static const int ASN1_F_ASN1_MBSTRING_NCOPY; +static const int ASN1_F_ASN1_TEMPLATE_EX_D2I; +static const int ASN1_F_ASN1_TEMPLATE_NEW; +static const int ASN1_F_ASN1_TEMPLATE_NOEXP_D2I; +static const int ASN1_F_ASN1_TIME_SET; +static const int ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING; +static const int ASN1_F_ASN1_TYPE_GET_OCTETSTRING; +static const int ASN1_F_ASN1_UNPACK_STRING; +static const int ASN1_F_ASN1_UTCTIME_SET; +static const int ASN1_F_ASN1_VERIFY; +static const int ASN1_F_BITSTR_CB; +static const int ASN1_F_BN_TO_ASN1_ENUMERATED; +static const int ASN1_F_BN_TO_ASN1_INTEGER; +static const int ASN1_F_D2I_ASN1_TYPE_BYTES; +static const int ASN1_F_D2I_ASN1_UINTEGER; +static const int ASN1_F_D2I_ASN1_UTCTIME; +static const int ASN1_F_D2I_NETSCAPE_RSA; +static const int ASN1_F_D2I_NETSCAPE_RSA_2; +static const int ASN1_F_D2I_PRIVATEKEY; +static const int ASN1_F_D2I_X509; +static const int ASN1_F_D2I_X509_CINF; +static const int ASN1_F_D2I_X509_PKEY; +static const int ASN1_F_I2D_ASN1_SET; +static const int ASN1_F_I2D_ASN1_TIME; +static const int ASN1_F_I2D_DSA_PUBKEY; +static const int ASN1_F_LONG_C2I; +static const int ASN1_F_OID_MODULE_INIT; +static const int ASN1_F_PARSE_TAGGING; +static const int ASN1_F_PKCS5_PBE_SET; +static const int ASN1_F_X509_CINF_NEW; + +static const int ASN1_R_BOOLEAN_IS_WRONG_LENGTH; +static const int ASN1_R_BUFFER_TOO_SMALL; +static const int ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER; +static const int ASN1_R_DATA_IS_WRONG; +static const int ASN1_R_DECODE_ERROR; +static const int ASN1_R_DECODING_ERROR; +static const int ASN1_R_DEPTH_EXCEEDED; +static const int ASN1_R_ENCODE_ERROR; +static const int ASN1_R_ERROR_GETTING_TIME; +static const int ASN1_R_ERROR_LOADING_SECTION; +static const int ASN1_R_MSTRING_WRONG_TAG; +static const int ASN1_R_NESTED_ASN1_STRING; +static const int ASN1_R_NO_MATCHING_CHOICE_TYPE; +static const int ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM; +static const int ASN1_R_UNKNOWN_OBJECT_TYPE; +static const int ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE; +static const int ASN1_R_UNKNOWN_TAG; +static const int ASN1_R_UNKOWN_FORMAT; +static const int ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE; +static const int ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM; +static const int ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE; +static const int ASN1_R_UNSUPPORTED_TYPE; +static const int ASN1_R_WRONG_TAG; +static const int ASN1_R_WRONG_TYPE; + +static const int EVP_F_AES_INIT_KEY; +static const int EVP_F_D2I_PKEY; +static const int EVP_F_DSA_PKEY2PKCS8; +static const int EVP_F_DSAPKEY2PKCS8; +static const int EVP_F_ECDSA_PKEY2PKCS8; +static const int EVP_F_ECKEY_PKEY2PKCS8; +static const int EVP_F_EVP_CIPHER_CTX_CTRL; +static const int EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH; +static const int EVP_F_EVP_CIPHERINIT_EX; +static const int EVP_F_EVP_DECRYPTFINAL_EX; +static const int EVP_F_EVP_DIGESTINIT_EX; +static const int EVP_F_EVP_ENCRYPTFINAL_EX; +static const int EVP_F_EVP_MD_CTX_COPY_EX; +static const int EVP_F_EVP_OPENINIT; +static const int EVP_F_EVP_PBE_ALG_ADD; +static const int EVP_F_EVP_PBE_CIPHERINIT; +static const int EVP_F_EVP_PKCS82PKEY; +static const int EVP_F_EVP_PKEY2PKCS8_BROKEN; +static const int EVP_F_EVP_PKEY_COPY_PARAMETERS; +static const int EVP_F_EVP_PKEY_DECRYPT; +static const int EVP_F_EVP_PKEY_ENCRYPT; +static const int EVP_F_EVP_PKEY_GET1_DH; +static const int EVP_F_EVP_PKEY_GET1_DSA; +static const int EVP_F_EVP_PKEY_GET1_ECDSA; +static const int EVP_F_EVP_PKEY_GET1_EC_KEY; +static const int EVP_F_EVP_PKEY_GET1_RSA; +static const int EVP_F_EVP_PKEY_NEW; +static const int EVP_F_EVP_RIJNDAEL; +static const int EVP_F_EVP_SIGNFINAL; +static const int EVP_F_EVP_VERIFYFINAL; +static const int EVP_F_PKCS5_PBE_KEYIVGEN; +static const int EVP_F_PKCS5_V2_PBE_KEYIVGEN; +static const int EVP_F_PKCS8_SET_BROKEN; +static const int EVP_F_RC2_MAGIC_TO_METH; +static const int EVP_F_RC5_CTRL; + +static const int EVP_R_AES_KEY_SETUP_FAILED; +static const int EVP_R_ASN1_LIB; +static const int EVP_R_BAD_BLOCK_LENGTH; +static const int EVP_R_BAD_DECRYPT; +static const int EVP_R_BAD_KEY_LENGTH; +static const int EVP_R_BN_DECODE_ERROR; +static const int EVP_R_BN_PUBKEY_ERROR; +static const int EVP_R_CIPHER_PARAMETER_ERROR; +static const int EVP_R_CTRL_NOT_IMPLEMENTED; +static const int EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED; +static const int EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH; +static const int EVP_R_DECODE_ERROR; +static const int EVP_R_DIFFERENT_KEY_TYPES; +static const int EVP_R_ENCODE_ERROR; +static const int EVP_R_INITIALIZATION_ERROR; +static const int EVP_R_INPUT_NOT_INITIALIZED; +static const int EVP_R_INVALID_KEY_LENGTH; +static const int EVP_R_IV_TOO_LARGE; +static const int EVP_R_KEYGEN_FAILURE; +static const int EVP_R_MISSING_PARAMETERS; +static const int EVP_R_NO_CIPHER_SET; +static const int EVP_R_NO_DIGEST_SET; +static const int EVP_R_NO_DSA_PARAMETERS; +static const int EVP_R_NO_SIGN_FUNCTION_CONFIGURED; +static const int EVP_R_NO_VERIFY_FUNCTION_CONFIGURED; +static const int EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE; +static const int EVP_R_PUBLIC_KEY_NOT_RSA; +static const int EVP_R_UNKNOWN_PBE_ALGORITHM; +static const int EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS; +static const int EVP_R_UNSUPPORTED_CIPHER; +static const int EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION; +static const int EVP_R_UNSUPPORTED_KEYLENGTH; +static const int EVP_R_UNSUPPORTED_SALT_TYPE; +static const int EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM; +static const int EVP_R_WRONG_FINAL_BLOCK_LENGTH; +static const int EVP_R_WRONG_PUBLIC_KEY_TYPE; + +static const int EC_F_EC_GROUP_NEW_BY_CURVE_NAME; + +static const int EC_R_UNKNOWN_GROUP; + +static const int PEM_F_D2I_PKCS8PRIVATEKEY_BIO; +static const int PEM_F_D2I_PKCS8PRIVATEKEY_FP; +static const int PEM_F_DO_PK8PKEY; +static const int PEM_F_DO_PK8PKEY_FP; +static const int PEM_F_LOAD_IV; +static const int PEM_F_PEM_ASN1_READ; +static const int PEM_F_PEM_ASN1_READ_BIO; +static const int PEM_F_PEM_ASN1_WRITE; +static const int PEM_F_PEM_ASN1_WRITE_BIO; +static const int PEM_F_PEM_DEF_CALLBACK; +static const int PEM_F_PEM_DO_HEADER; +static const int PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY; +static const int PEM_F_PEM_GET_EVP_CIPHER_INFO; +static const int PEM_F_PEM_PK8PKEY; +static const int PEM_F_PEM_READ; +static const int PEM_F_PEM_READ_BIO; +static const int PEM_F_PEM_READ_BIO_PRIVATEKEY; +static const int PEM_F_PEM_READ_PRIVATEKEY; +static const int PEM_F_PEM_SEALFINAL; +static const int PEM_F_PEM_SEALINIT; +static const int PEM_F_PEM_SIGNFINAL; +static const int PEM_F_PEM_WRITE; +static const int PEM_F_PEM_WRITE_BIO; +static const int PEM_F_PEM_X509_INFO_READ; +static const int PEM_F_PEM_X509_INFO_READ_BIO; +static const int PEM_F_PEM_X509_INFO_WRITE_BIO; + +static const int PEM_R_BAD_BASE64_DECODE; +static const int PEM_R_BAD_DECRYPT; +static const int PEM_R_BAD_END_LINE; +static const int PEM_R_BAD_IV_CHARS; +static const int PEM_R_BAD_PASSWORD_READ; +static const int PEM_R_ERROR_CONVERTING_PRIVATE_KEY; +static const int PEM_R_NO_START_LINE; +static const int PEM_R_NOT_DEK_INFO; +static const int PEM_R_NOT_ENCRYPTED; +static const int PEM_R_NOT_PROC_TYPE; +static const int PEM_R_PROBLEMS_GETTING_PASSWORD; +static const int PEM_R_PUBLIC_KEY_NO_RSA; +static const int PEM_R_READ_KEY; +static const int PEM_R_SHORT_HEADER; +static const int PEM_R_UNSUPPORTED_CIPHER; +static const int PEM_R_UNSUPPORTED_ENCRYPTION; + +static const int PKCS12_F_PKCS12_PBE_CRYPT; + +static const int PKCS12_R_PKCS12_CIPHERFINAL_ERROR; + +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; +static const int RSA_R_PKCS_DECODING_ERROR; +""" + +FUNCTIONS = """ +void ERR_load_crypto_strings(void); +void ERR_load_SSL_strings(void); +void ERR_free_strings(void); +char* ERR_error_string(unsigned long, char *); +void ERR_error_string_n(unsigned long, char *, size_t); +const char* ERR_lib_error_string(unsigned long); +const char* ERR_func_error_string(unsigned long); +const char* ERR_reason_error_string(unsigned long); +void ERR_print_errors(BIO *); +void ERR_print_errors_fp(FILE *); +unsigned long ERR_get_error(void); +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_last_error(void); +unsigned long ERR_get_error_line(const char **, int *); +unsigned long ERR_peek_error_line(const char **, int *); +unsigned long ERR_peek_last_error_line(const char **, int *); +unsigned long ERR_get_error_line_data(const char **, int *, + const char **, int *); +unsigned long ERR_peek_error_line_data(const char **, + int *, const char **, int *); +unsigned long ERR_peek_last_error_line_data(const char **, + int *, const char **, int *); +void ERR_put_error(int, int, int, const char *, int); +void ERR_add_error_data(int, ...); +int ERR_get_next_error_library(void); +""" + +MACROS = """ +unsigned long ERR_PACK(int, int, int); +int ERR_GET_LIB(unsigned long); +int ERR_GET_FUNC(unsigned long); +int ERR_GET_REASON(unsigned long); +int ERR_FATAL_ERROR(unsigned long); +/* introduced in 1.0.0 so we have to handle this specially to continue + * supporting 0.9.8 + */ +void ERR_remove_thread_state(const CRYPTO_THREADID *); + +/* These were added in OpenSSL 0.9.8h. When we drop support for RHEL/CentOS 5 + we should be able to move these back to TYPES. */ +static const int ASN1_F_B64_READ_ASN1; +static const int ASN1_F_B64_WRITE_ASN1; +static const int ASN1_F_SMIME_READ_ASN1; +static const int ASN1_F_SMIME_TEXT; +static const int ASN1_R_NO_CONTENT_TYPE; +static const int ASN1_R_NO_MULTIPART_BODY_FAILURE; +static const int ASN1_R_NO_MULTIPART_BOUNDARY; +/* These were added in OpenSSL 0.9.8c. */ +static const int EVP_F_CAMELLIA_INIT_KEY; +static const int EVP_R_CAMELLIA_KEY_SETUP_FAILED; +""" + +CUSTOMIZATIONS = """ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +static const long Cryptography_HAS_REMOVE_THREAD_STATE = 1; +#else +static const long Cryptography_HAS_REMOVE_THREAD_STATE = 0; +typedef uint32_t CRYPTO_THREADID; +void (*ERR_remove_thread_state)(const CRYPTO_THREADID *) = NULL; +#endif + +/* OpenSSL 0.9.8h+ */ +#if OPENSSL_VERSION_NUMBER >= 0x0090808fL +static const long Cryptography_HAS_098H_ERROR_CODES = 1; +#else +static const long Cryptography_HAS_098H_ERROR_CODES = 0; +static const int ASN1_F_B64_READ_ASN1 = 0; +static const int ASN1_F_B64_WRITE_ASN1 = 0; +static const int ASN1_F_SMIME_READ_ASN1 = 0; +static const int ASN1_F_SMIME_TEXT = 0; +static const int ASN1_R_NO_CONTENT_TYPE = 0; +static const int ASN1_R_NO_MULTIPART_BODY_FAILURE = 0; +static const int ASN1_R_NO_MULTIPART_BOUNDARY = 0; +#endif + +/* OpenSSL 0.9.8c+ */ +#ifdef EVP_F_CAMELLIA_INIT_KEY +static const long Cryptography_HAS_098C_CAMELLIA_CODES = 1; +#else +static const long Cryptography_HAS_098C_CAMELLIA_CODES = 0; +static const int EVP_F_CAMELLIA_INIT_KEY = 0; +static const int EVP_R_CAMELLIA_KEY_SETUP_FAILED = 0; +#endif + +// OpenSSL without EC. e.g. RHEL +#ifndef OPENSSL_NO_EC +static const long Cryptography_HAS_EC_CODES = 1; +#else +static const long Cryptography_HAS_EC_CODES = 0; +static const int EC_R_UNKNOWN_GROUP = 0; +static const int EC_F_EC_GROUP_NEW_BY_CURVE_NAME = 0; +#endif + +#ifdef RSA_R_PKCS_DECODING_ERROR +static const long Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR = 1; +#else +static const long Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR = 0; +static const long RSA_R_PKCS_DECODING_ERROR = 0; +#endif +""" + +CONDITIONAL_NAMES = { + "Cryptography_HAS_REMOVE_THREAD_STATE": [ + "ERR_remove_thread_state" + ], + "Cryptography_HAS_098H_ERROR_CODES": [ + "ASN1_F_B64_READ_ASN1", + "ASN1_F_B64_WRITE_ASN1", + "ASN1_F_SMIME_READ_ASN1", + "ASN1_F_SMIME_TEXT", + "ASN1_R_NO_CONTENT_TYPE", + "ASN1_R_NO_MULTIPART_BODY_FAILURE", + "ASN1_R_NO_MULTIPART_BOUNDARY", + ], + "Cryptography_HAS_098C_CAMELLIA_CODES": [ + "EVP_F_CAMELLIA_INIT_KEY", + "EVP_R_CAMELLIA_KEY_SETUP_FAILED" + ], + "Cryptography_HAS_EC_CODES": [ + "EC_R_UNKNOWN_GROUP", + "EC_F_EC_GROUP_NEW_BY_CURVE_NAME" + ], + "Cryptography_HAS_RSA_R_PKCS_DECODING_ERROR": [ + "RSA_R_PKCS_DECODING_ERROR" + ] +} diff --git a/src/cryptography/hazmat/bindings/openssl/evp.py b/src/cryptography/hazmat/bindings/openssl/evp.py new file mode 100644 index 00000000..033b083b --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/evp.py @@ -0,0 +1,263 @@ +# 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 +""" + +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); + +int EVP_PKEY_cmp(const EVP_PKEY *, const EVP_PKEY *); +""" + +MACROS = """ +void OpenSSL_add_all_algorithms(void); +int EVP_PKEY_assign_RSA(EVP_PKEY *, RSA *); +int EVP_PKEY_assign_DSA(EVP_PKEY *, DSA *); + +int EVP_PKEY_assign_EC_KEY(EVP_PKEY *, EC_KEY *); +EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *); +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *, EC_KEY *); + +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *); +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *, int, int, void *); + +int PKCS5_PBKDF2_HMAC(const char *, int, const unsigned char *, int, int, + const EVP_MD *, int, unsigned char *); + +int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *, const EVP_MD *); + +/* These aren't macros, but must be in this section because they're not + available in 0.9.8. */ +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *, ENGINE *); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int, ENGINE *); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *); +int EVP_PKEY_sign_init(EVP_PKEY_CTX *); +int EVP_PKEY_sign(EVP_PKEY_CTX *, unsigned char *, size_t *, + const unsigned char *, size_t); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *); +int EVP_PKEY_verify(EVP_PKEY_CTX *, const unsigned char *, size_t, + const unsigned char *, size_t); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *); + +/* The following were macros in 0.9.8e. Once we drop support for RHEL/CentOS 5 + we should move these back to FUNCTIONS. */ +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *); +int EVP_CIPHER_block_size(const EVP_CIPHER *); +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *); +int EVP_MD_size(const EVP_MD *); + +/* Must be in macros because EVP_PKEY_CTX is undefined in 0.9.8 */ +int Cryptography_EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *in, + size_t inlen); +int Cryptography_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *in, + size_t inlen); +""" + +CUSTOMIZATIONS = """ +#ifdef EVP_CTRL_GCM_SET_TAG +const long Cryptography_HAS_GCM = 1; +#else +const long Cryptography_HAS_GCM = 0; +const long EVP_CTRL_GCM_GET_TAG = -1; +const long EVP_CTRL_GCM_SET_TAG = -1; +const long EVP_CTRL_GCM_SET_IVLEN = -1; +#endif +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +const long Cryptography_HAS_PBKDF2_HMAC = 1; +const long Cryptography_HAS_PKEY_CTX = 1; + +/* OpenSSL 0.9.8 defines EVP_PKEY_encrypt and EVP_PKEY_decrypt functions, + but they are a completely different signature from the ones in 1.0.0+. + These wrapper functions allows us to safely declare them on any version and + conditionally remove them on 0.9.8. */ +int Cryptography_EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *in, + size_t inlen) { + return EVP_PKEY_encrypt(ctx, out, outlen, in, inlen); +} +int Cryptography_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *in, + size_t inlen) { + return EVP_PKEY_decrypt(ctx, out, outlen, in, inlen); +} +#else +const long Cryptography_HAS_PBKDF2_HMAC = 0; +int (*PKCS5_PBKDF2_HMAC)(const char *, int, const unsigned char *, int, int, + const EVP_MD *, int, unsigned char *) = NULL; +const long Cryptography_HAS_PKEY_CTX = 0; +typedef void EVP_PKEY_CTX; +int (*EVP_PKEY_CTX_set_signature_md)(EVP_PKEY_CTX *, const EVP_MD *) = NULL; +int (*EVP_PKEY_sign_init)(EVP_PKEY_CTX *) = NULL; +int (*EVP_PKEY_sign)(EVP_PKEY_CTX *, unsigned char *, size_t *, + const unsigned char *, size_t) = NULL; +int (*EVP_PKEY_verify_init)(EVP_PKEY_CTX *) = NULL; +int (*EVP_PKEY_verify)(EVP_PKEY_CTX *, const unsigned char *, size_t, + const unsigned char *, size_t) = NULL; +EVP_PKEY_CTX *(*EVP_PKEY_CTX_new)(EVP_PKEY *, ENGINE *) = NULL; +EVP_PKEY_CTX *(*EVP_PKEY_CTX_new_id)(int, ENGINE *) = NULL; +EVP_PKEY_CTX *(*EVP_PKEY_CTX_dup)(EVP_PKEY_CTX *) = NULL; +void (*EVP_PKEY_CTX_free)(EVP_PKEY_CTX *) = NULL; +int (*EVP_PKEY_encrypt_init)(EVP_PKEY_CTX *) = NULL; +int (*EVP_PKEY_decrypt_init)(EVP_PKEY_CTX *) = NULL; +int (*Cryptography_EVP_PKEY_encrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *, + const unsigned char *, size_t) = NULL; +int (*Cryptography_EVP_PKEY_decrypt)(EVP_PKEY_CTX *, unsigned char *, size_t *, + const unsigned char *, size_t) = NULL; +#endif +#ifdef OPENSSL_NO_EC +int (*EVP_PKEY_assign_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL; +EC_KEY *(*EVP_PKEY_get1_EC_KEY)(EVP_PKEY *) = NULL; +int (*EVP_PKEY_set1_EC_KEY)(EVP_PKEY *, EC_KEY *) = NULL; +#endif + +""" + +CONDITIONAL_NAMES = { + "Cryptography_HAS_GCM": [ + "EVP_CTRL_GCM_GET_TAG", + "EVP_CTRL_GCM_SET_TAG", + "EVP_CTRL_GCM_SET_IVLEN", + ], + "Cryptography_HAS_PBKDF2_HMAC": [ + "PKCS5_PBKDF2_HMAC" + ], + "Cryptography_HAS_PKEY_CTX": [ + "EVP_PKEY_CTX_new", + "EVP_PKEY_CTX_new_id", + "EVP_PKEY_CTX_dup", + "EVP_PKEY_CTX_free", + "EVP_PKEY_sign", + "EVP_PKEY_sign_init", + "EVP_PKEY_verify", + "EVP_PKEY_verify_init", + "Cryptography_EVP_PKEY_encrypt", + "EVP_PKEY_encrypt_init", + "Cryptography_EVP_PKEY_decrypt", + "EVP_PKEY_decrypt_init", + "EVP_PKEY_CTX_set_signature_md", + ], + "Cryptography_HAS_EC": [ + "EVP_PKEY_assign_EC_KEY", + "EVP_PKEY_get1_EC_KEY", + "EVP_PKEY_set1_EC_KEY", + ] +} diff --git a/src/cryptography/hazmat/bindings/openssl/hmac.py b/src/cryptography/hazmat/bindings/openssl/hmac.py new file mode 100644 index 00000000..6a64b92c --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/hmac.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/nid.py b/src/cryptography/hazmat/bindings/openssl/nid.py new file mode 100644 index 00000000..b2e61492 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/nid.py @@ -0,0 +1,241 @@ +# 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 +""" + +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_pbe_WithSHA1And3_Key_TripleDES_CBC; +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; + +static const int NID_subject_key_identifier; +static const int NID_authority_key_identifier; +static const int NID_policy_constraints; +static const int NID_ext_key_usage; +static const int NID_info_access; +static const int NID_key_usage; +static const int NID_subject_alt_name; +static const int NID_issuer_alt_name; +static const int NID_basic_constraints; +static const int NID_issuing_distribution_point; +static const int NID_certificate_issuer; +static const int NID_name_constraints; +static const int NID_crl_distribution_points; +static const int NID_certificate_policies; +static const int NID_inhibit_any_policy; + +static const int NID_private_key_usage_period; +static const int NID_crl_number; +static const int NID_crl_reason; +static const int NID_invalidity_date; +static const int NID_delta_crl; +static const int NID_any_policy; +static const int NID_policy_mappings; +static const int NID_target_information; +static const int NID_no_rev_avail; +""" + +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", + ], +} diff --git a/src/cryptography/hazmat/bindings/openssl/objects.py b/src/cryptography/hazmat/bindings/openssl/objects.py new file mode 100644 index 00000000..557c0158 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/objects.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/opensslv.py b/src/cryptography/hazmat/bindings/openssl/opensslv.py new file mode 100644 index 00000000..ef6e057b --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/opensslv.py @@ -0,0 +1,36 @@ +# 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 +""" + +TYPES = """ +/* Note that these will be resolved when cryptography is compiled and are NOT + guaranteed to be the version that it actually loads. */ +static const int OPENSSL_VERSION_NUMBER; +static const char *const OPENSSL_VERSION_TEXT; +""" + +FUNCTIONS = """ +""" + +MACROS = """ +""" + +CUSTOMIZATIONS = """ +""" + +CONDITIONAL_NAMES = {} diff --git a/src/cryptography/hazmat/bindings/openssl/osrandom_engine.py b/src/cryptography/hazmat/bindings/openssl/osrandom_engine.py new file mode 100644 index 00000000..462997cc --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/osrandom_engine.py @@ -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 +#else +#include +#include +#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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/pem.py b/src/cryptography/hazmat/bindings/openssl/pem.py new file mode 100644 index 00000000..752f1987 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/pem.py @@ -0,0 +1,89 @@ +# 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 +""" + +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 *); + +PKCS7 *d2i_PKCS7_bio(BIO *, PKCS7 **); +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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/pkcs12.py b/src/cryptography/hazmat/bindings/openssl/pkcs12.py new file mode 100644 index 00000000..a8f106f6 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/pkcs12.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/pkcs7.py b/src/cryptography/hazmat/bindings/openssl/pkcs7.py new file mode 100644 index 00000000..1343e566 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/pkcs7.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/rand.py b/src/cryptography/hazmat/bindings/openssl/rand.py new file mode 100644 index 00000000..7b1be9df --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/rand.py @@ -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 +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/rsa.py b/src/cryptography/hazmat/bindings/openssl/rsa.py new file mode 100644 index 00000000..cb8e701e --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/rsa.py @@ -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 +""" + +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", + ], +} diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py new file mode 100644 index 00000000..7d805e78 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/ssl.py @@ -0,0 +1,620 @@ +# 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 + +typedef STACK_OF(SSL_CIPHER) Cryptography_STACK_OF_SSL_CIPHER; +""" + +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; +static const long Cryptography_HAS_SECURE_RENEGOTIATION; + +/* 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 Cryptography_HAS_ALPN; + +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_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; +static const long SSL_OP_LEGACY_SERVER_CONNECT; +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 ... 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; +typedef ... Cryptography_STACK_OF_SSL_CIPHER; +typedef ... COMP_METHOD; +""" + +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); +Cryptography_STACK_OF_SSL_CIPHER *SSL_get_ciphers(const SSL *); + +const COMP_METHOD *SSL_get_current_compression(SSL *); +const COMP_METHOD *SSL_get_current_expansion(SSL *); +const char *SSL_COMP_get_name(const COMP_METHOD *); + +/* 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 *); + +/* 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 *); +long SSL_get_secure_renegotiation_support(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 *); + +int sk_SSL_CIPHER_num(Cryptography_STACK_OF_SSL_CIPHER *); +SSL_CIPHER *sk_SSL_CIPHER_value(Cryptography_STACK_OF_SSL_CIPHER *, int); + +/* ALPN APIs were introduced in OpenSSL 1.0.2. To continue to support earlier + * versions some special handling of these is necessary. + */ +int SSL_CTX_set_alpn_protos(SSL_CTX *, const unsigned char*, unsigned); +int SSL_set_alpn_protos(SSL *, const unsigned char*, unsigned); +void SSL_CTX_set_alpn_select_cb(SSL_CTX *, + int (*) (SSL *, + const unsigned char **, + unsigned char *, + const unsigned char *, + unsigned int, + void *), + void *); +void SSL_get0_alpn_selected(const SSL *, const unsigned char **, unsigned *); +""" + +CUSTOMIZATIONS = """ +/** Secure renegotiation is supported in OpenSSL >= 0.9.8m + * But some Linux distributions have back ported some features. + */ +#ifndef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION +static const long Cryptography_HAS_SECURE_RENEGOTIATION = 0; +long (*SSL_get_secure_renegotiation_support)(SSL *) = NULL; +const long SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION = 0; +const long SSL_OP_LEGACY_SERVER_CONNECT = 0; +#else +static const long Cryptography_HAS_SECURE_RENEGOTIATION = 1; +#endif +#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 +# 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 + +/* ALPN was added in OpenSSL 1.0.2. */ +#if OPENSSL_VERSION_NUMBER < 0x10002001L +int (*SSL_CTX_set_alpn_protos)(SSL_CTX *, + const unsigned char*, + unsigned) = NULL; +int (*SSL_set_alpn_protos)(SSL *, const unsigned char*, unsigned) = NULL; +void (*SSL_CTX_set_alpn_select_cb)(SSL_CTX *, + int (*) (SSL *, + const unsigned char **, + unsigned char *, + const unsigned char *, + unsigned int, + void *), + void *) = NULL; +void (*SSL_get0_alpn_selected)(const SSL *, + const unsigned char **, + unsigned *) = NULL; +static const long Cryptography_HAS_ALPN = 0; +#else +static const long Cryptography_HAS_ALPN = 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", + ], + + "Cryptography_HAS_SECURE_RENEGOTIATION": [ + "SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", + "SSL_OP_LEGACY_SERVER_CONNECT", + "SSL_get_secure_renegotiation_support", + ], + + "Cryptography_HAS_ALPN": [ + "SSL_CTX_set_alpn_protos", + "SSL_set_alpn_protos", + "SSL_CTX_set_alpn_select_cb", + "SSL_get0_alpn_selected", + ] +} diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py new file mode 100644 index 00000000..95bc7c3b --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/x509.py @@ -0,0 +1,273 @@ +# 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 + +/* + * 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_CRL) Cryptography_STACK_OF_X509_CRL; +typedef STACK_OF(X509_REVOKED) Cryptography_STACK_OF_X509_REVOKED; +""" + +TYPES = """ +typedef ... Cryptography_STACK_OF_X509; +typedef ... Cryptography_STACK_OF_X509_CRL; +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 ... 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 *); +int X509_REQ_digest(const X509_REQ *, const EVP_MD *, + unsigned char *, unsigned int *); +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 *); + +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", + ] +} diff --git a/src/cryptography/hazmat/bindings/openssl/x509_vfy.py b/src/cryptography/hazmat/bindings/openssl/x509_vfy.py new file mode 100644 index 00000000..601926c9 --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/x509_vfy.py @@ -0,0 +1,336 @@ +# 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 + +/* + * 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(ASN1_OBJECT) Cryptography_STACK_OF_ASN1_OBJECT; +""" + +TYPES = """ +static const long Cryptography_HAS_102_VERIFICATION_ERROR_CODES; +static const long Cryptography_HAS_102_VERIFICATION_PARAMS; +static const long Cryptography_HAS_X509_V_FLAG_TRUSTED_FIRST; +static const long Cryptography_HAS_X509_V_FLAG_PARTIAL_CHAIN; +static const long Cryptography_HAS_100_VERIFICATION_ERROR_CODES; +static const long Cryptography_HAS_100_VERIFICATION_PARAMS; +static const long Cryptography_HAS_X509_V_FLAG_CHECK_SS_SIGNATURE; + +typedef ... Cryptography_STACK_OF_ASN1_OBJECT; + +typedef ... X509_STORE; +typedef ... X509_STORE_CTX; +typedef ... X509_VERIFY_PARAM; + +/* While these are defined in the source as ints, they're tagged here + as longs, just in case they ever grow to large, such as what we saw + with OP_ALL. */ + +/* Verification error codes */ +static const int X509_V_OK; +static const int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; +static const int X509_V_ERR_UNABLE_TO_GET_CRL; +static const int X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE; +static const int X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE; +static const int X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; +static const int X509_V_ERR_CERT_SIGNATURE_FAILURE; +static const int X509_V_ERR_CRL_SIGNATURE_FAILURE; +static const int X509_V_ERR_CERT_NOT_YET_VALID; +static const int X509_V_ERR_CERT_HAS_EXPIRED; +static const int X509_V_ERR_CRL_NOT_YET_VALID; +static const int X509_V_ERR_CRL_HAS_EXPIRED; +static const int X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; +static const int X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; +static const int X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; +static const int X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; +static const int X509_V_ERR_OUT_OF_MEM; +static const int X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; +static const int X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; +static const int X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; +static const int X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; +static const int X509_V_ERR_CERT_CHAIN_TOO_LONG; +static const int X509_V_ERR_CERT_REVOKED; +static const int X509_V_ERR_INVALID_CA; +static const int X509_V_ERR_PATH_LENGTH_EXCEEDED; +static const int X509_V_ERR_INVALID_PURPOSE; +static const int X509_V_ERR_CERT_UNTRUSTED; +static const int X509_V_ERR_CERT_REJECTED; +static const int X509_V_ERR_SUBJECT_ISSUER_MISMATCH; +static const int X509_V_ERR_AKID_SKID_MISMATCH; +static const int X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; +static const int X509_V_ERR_KEYUSAGE_NO_CERTSIGN; +static const int X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; +static const int X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; +static const int X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; +static const int X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; +static const int X509_V_ERR_INVALID_NON_CA; +static const int X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; +static const int X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; +static const int X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; +static const int X509_V_ERR_INVALID_EXTENSION; +static const int X509_V_ERR_INVALID_POLICY_EXTENSION; +static const int X509_V_ERR_NO_EXPLICIT_POLICY; +static const int X509_V_ERR_DIFFERENT_CRL_SCOPE; +static const int X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE; +static const int X509_V_ERR_UNNESTED_RESOURCE; +static const int X509_V_ERR_PERMITTED_VIOLATION; +static const int X509_V_ERR_EXCLUDED_VIOLATION; +static const int X509_V_ERR_SUBTREE_MINMAX; +static const int X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; +static const int X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX; +static const int X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; +static const int X509_V_ERR_CRL_PATH_VALIDATION_ERROR; +static const int X509_V_ERR_SUITE_B_INVALID_VERSION; +static const int X509_V_ERR_SUITE_B_INVALID_ALGORITHM; +static const int X509_V_ERR_SUITE_B_INVALID_CURVE; +static const int X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; +static const int X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; +static const int X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256; +static const int X509_V_ERR_HOSTNAME_MISMATCH; +static const int X509_V_ERR_EMAIL_MISMATCH; +static const int X509_V_ERR_IP_ADDRESS_MISMATCH; +static const int X509_V_ERR_APPLICATION_VERIFICATION; + +/* Verification parameters */ +static const long X509_V_FLAG_CB_ISSUER_CHECK; +static const long X509_V_FLAG_USE_CHECK_TIME; +static const long X509_V_FLAG_CRL_CHECK; +static const long X509_V_FLAG_CRL_CHECK_ALL; +static const long X509_V_FLAG_IGNORE_CRITICAL; +static const long X509_V_FLAG_X509_STRICT; +static const long X509_V_FLAG_ALLOW_PROXY_CERTS; +static const long X509_V_FLAG_POLICY_CHECK; +static const long X509_V_FLAG_EXPLICIT_POLICY; +static const long X509_V_FLAG_INHIBIT_ANY; +static const long X509_V_FLAG_INHIBIT_MAP; +static const long X509_V_FLAG_NOTIFY_POLICY; +static const long X509_V_FLAG_EXTENDED_CRL_SUPPORT; +static const long X509_V_FLAG_USE_DELTAS; +static const long X509_V_FLAG_CHECK_SS_SIGNATURE; +static const long X509_V_FLAG_TRUSTED_FIRST; +static const long X509_V_FLAG_SUITEB_128_LOS_ONLY; +static const long X509_V_FLAG_SUITEB_192_LOS; +static const long X509_V_FLAG_SUITEB_128_LOS; +static const long X509_V_FLAG_PARTIAL_CHAIN; +""" + +FUNCTIONS = """ +int X509_verify_cert(X509_STORE_CTX *); + +/* X509_STORE */ +X509_STORE *X509_STORE_new(void); +void X509_STORE_free(X509_STORE *); +int X509_STORE_add_cert(X509_STORE *, X509 *); + +/* X509_STORE_CTX */ +X509_STORE_CTX *X509_STORE_CTX_new(void); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *); +void X509_STORE_CTX_free(X509_STORE_CTX *); +int X509_STORE_CTX_init(X509_STORE_CTX *, X509_STORE *, X509 *, + Cryptography_STACK_OF_X509 *); +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *, + Cryptography_STACK_OF_X509 *); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *, X509 *); +void X509_STORE_CTX_set_chain(X509_STORE_CTX *,Cryptography_STACK_OF_X509 *); +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *, X509_VERIFY_PARAM *); +int X509_STORE_CTX_set_default(X509_STORE_CTX *, const char *); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *, + int (*)(int, X509_STORE_CTX *)); +Cryptography_STACK_OF_X509 *X509_STORE_CTX_get_chain(X509_STORE_CTX *); +Cryptography_STACK_OF_X509 *X509_STORE_CTX_get1_chain(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); + +/* X509_VERIFY_PARAM */ +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *, unsigned long); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *, unsigned long); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *, int); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *, int); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *, time_t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *, ASN1_OBJECT *); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *, + Cryptography_STACK_OF_ASN1_OBJECT *); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *, int); +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *); +""" + +MACROS = """ +/* X509_STORE_CTX */ +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *, + Cryptography_STACK_OF_X509_CRL *); + +/* X509_VERIFY_PARAM */ +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *, const char *, + size_t); +void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *, unsigned int); +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *, const char *, + size_t); +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *, const unsigned char *, + size_t); +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *, const char *); +""" + +CUSTOMIZATIONS = """ +/* OpenSSL 1.0.2+ verification error codes */ +#if OPENSSL_VERSION_NUMBER >= 0x10002000L +static const long Cryptography_HAS_102_VERIFICATION_ERROR_CODES = 1; +#else +static const long Cryptography_HAS_102_VERIFICATION_ERROR_CODES = 0; +static const long X509_V_ERR_SUITE_B_INVALID_VERSION = 0; +static const long X509_V_ERR_SUITE_B_INVALID_ALGORITHM = 0; +static const long X509_V_ERR_SUITE_B_INVALID_CURVE = 0; +static const long X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM = 0; +static const long X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED = 0; +static const long X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 = 0; +static const long X509_V_ERR_HOSTNAME_MISMATCH = 0; +static const long X509_V_ERR_EMAIL_MISMATCH = 0; +static const long X509_V_ERR_IP_ADDRESS_MISMATCH = 0; +#endif + +/* OpenSSL 1.0.2+ verification parameters */ +#if OPENSSL_VERSION_NUMBER >= 0x10002000L +static const long Cryptography_HAS_102_VERIFICATION_PARAMS = 1; +#else +static const long Cryptography_HAS_102_VERIFICATION_PARAMS = 0; +/* X509_V_FLAG_TRUSTED_FIRST is also new in 1.0.2+, but it is added separately + below because it shows up in some earlier 3rd party OpenSSL packages. */ +static const long X509_V_FLAG_SUITEB_128_LOS_ONLY = 0; +static const long X509_V_FLAG_SUITEB_192_LOS = 0; +static const long X509_V_FLAG_SUITEB_128_LOS = 0; + +int (*X509_VERIFY_PARAM_set1_host)(X509_VERIFY_PARAM *, const char *, + size_t) = NULL; +int (*X509_VERIFY_PARAM_set1_email)(X509_VERIFY_PARAM *, const char *, + size_t) = NULL; +int (*X509_VERIFY_PARAM_set1_ip)(X509_VERIFY_PARAM *, const unsigned char *, + size_t) = NULL; +int (*X509_VERIFY_PARAM_set1_ip_asc)(X509_VERIFY_PARAM *, const char *) = NULL; +void (*X509_VERIFY_PARAM_set_hostflags)(X509_VERIFY_PARAM *, + unsigned int) = NULL; +#endif + +/* OpenSSL 1.0.2+ or Solaris's backport */ +#ifdef X509_V_FLAG_PARTIAL_CHAIN +static const long Cryptography_HAS_X509_V_FLAG_PARTIAL_CHAIN = 1; +#else +static const long Cryptography_HAS_X509_V_FLAG_PARTIAL_CHAIN = 0; +static const long X509_V_FLAG_PARTIAL_CHAIN = 0; +#endif + +/* OpenSSL 1.0.2+, *or* Fedora 20's flavor of OpenSSL 1.0.1e... */ +#ifdef X509_V_FLAG_TRUSTED_FIRST +static const long Cryptography_HAS_X509_V_FLAG_TRUSTED_FIRST = 1; +#else +static const long Cryptography_HAS_X509_V_FLAG_TRUSTED_FIRST = 0; +static const long X509_V_FLAG_TRUSTED_FIRST = 0; +#endif + +/* OpenSSL 1.0.0+ verification error codes */ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +static const long Cryptography_HAS_100_VERIFICATION_ERROR_CODES = 1; +#else +static const long Cryptography_HAS_100_VERIFICATION_ERROR_CODES = 0; +static const long X509_V_ERR_DIFFERENT_CRL_SCOPE = 0; +static const long X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE = 0; +static const long X509_V_ERR_PERMITTED_VIOLATION = 0; +static const long X509_V_ERR_EXCLUDED_VIOLATION = 0; +static const long X509_V_ERR_SUBTREE_MINMAX = 0; +static const long X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE = 0; +static const long X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX = 0; +static const long X509_V_ERR_UNSUPPORTED_NAME_SYNTAX = 0; +static const long X509_V_ERR_CRL_PATH_VALIDATION_ERROR = 0; +#endif + +/* OpenSSL 1.0.0+ verification parameters */ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +static const long Cryptography_HAS_100_VERIFICATION_PARAMS = 1; +#else +static const long Cryptography_HAS_100_VERIFICATION_PARAMS = 0; +static const long X509_V_FLAG_EXTENDED_CRL_SUPPORT = 0; +static const long X509_V_FLAG_USE_DELTAS = 0; +#endif + +/* OpenSSL 0.9.8recent+ */ +#ifdef X509_V_FLAG_CHECK_SS_SIGNATURE +static const long Cryptography_HAS_X509_V_FLAG_CHECK_SS_SIGNATURE = 1; +#else +static const long Cryptography_HAS_X509_V_FLAG_CHECK_SS_SIGNATURE = 0; +static const long X509_V_FLAG_CHECK_SS_SIGNATURE = 0; +#endif +""" + +CONDITIONAL_NAMES = { + "Cryptography_HAS_102_VERIFICATION_ERROR_CODES": [ + 'X509_V_ERR_SUITE_B_INVALID_VERSION', + 'X509_V_ERR_SUITE_B_INVALID_ALGORITHM', + 'X509_V_ERR_SUITE_B_INVALID_CURVE', + 'X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM', + 'X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED', + 'X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256', + 'X509_V_ERR_HOSTNAME_MISMATCH', + 'X509_V_ERR_EMAIL_MISMATCH', + 'X509_V_ERR_IP_ADDRESS_MISMATCH' + ], + "Cryptography_HAS_102_VERIFICATION_PARAMS": [ + "X509_V_FLAG_SUITEB_128_LOS_ONLY", + "X509_V_FLAG_SUITEB_192_LOS", + "X509_V_FLAG_SUITEB_128_LOS", + "X509_VERIFY_PARAM_set1_host", + "X509_VERIFY_PARAM_set1_email", + "X509_VERIFY_PARAM_set1_ip", + "X509_VERIFY_PARAM_set1_ip_asc", + "X509_VERIFY_PARAM_set_hostflags", + ], + "Cryptography_HAS_X509_V_FLAG_TRUSTED_FIRST": [ + "X509_V_FLAG_TRUSTED_FIRST", + ], + "Cryptography_HAS_X509_V_FLAG_PARTIAL_CHAIN": [ + "X509_V_FLAG_PARTIAL_CHAIN", + ], + "Cryptography_HAS_100_VERIFICATION_ERROR_CODES": [ + 'X509_V_ERR_DIFFERENT_CRL_SCOPE', + 'X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE', + 'X509_V_ERR_UNNESTED_RESOURCE', + 'X509_V_ERR_PERMITTED_VIOLATION', + 'X509_V_ERR_EXCLUDED_VIOLATION', + 'X509_V_ERR_SUBTREE_MINMAX', + 'X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE', + 'X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX', + 'X509_V_ERR_UNSUPPORTED_NAME_SYNTAX', + 'X509_V_ERR_CRL_PATH_VALIDATION_ERROR', + ], + "Cryptography_HAS_100_VERIFICATION_PARAMS": [ + "Cryptography_HAS_100_VERIFICATION_PARAMS", + "X509_V_FLAG_EXTENDED_CRL_SUPPORT", + "X509_V_FLAG_USE_DELTAS", + ], + "Cryptography_HAS_X509_V_FLAG_CHECK_SS_SIGNATURE": [ + "X509_V_FLAG_CHECK_SS_SIGNATURE", + ] +} diff --git a/src/cryptography/hazmat/bindings/openssl/x509name.py b/src/cryptography/hazmat/bindings/openssl/x509name.py new file mode 100644 index 00000000..50abee2a --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/x509name.py @@ -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 + +/* + * 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 = {} diff --git a/src/cryptography/hazmat/bindings/openssl/x509v3.py b/src/cryptography/hazmat/bindings/openssl/x509v3.py new file mode 100644 index 00000000..cf4be1fe --- /dev/null +++ b/src/cryptography/hazmat/bindings/openssl/x509v3.py @@ -0,0 +1,103 @@ +# 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 +""" + +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 *); +void GENERAL_NAMES_free(GENERAL_NAMES *); +void *X509V3_EXT_d2i(X509_EXTENSION *); +""" + +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 = {} diff --git a/src/cryptography/hazmat/bindings/utils.py b/src/cryptography/hazmat/bindings/utils.py new file mode 100644 index 00000000..55b61292 --- /dev/null +++ b/src/cryptography/hazmat/bindings/utils.py @@ -0,0 +1,144 @@ +# 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 threading + +from cffi import FFI +from cffi.verifier import Verifier + + +class LazyLibrary(object): + def __init__(self, ffi): + self._ffi = ffi + self._lib = None + self._lock = threading.Lock() + + def __getattr__(self, name): + if self._lib is None: + with self._lock: + if self._lib is None: + self._lib = self._ffi.verifier.load_library() + + return getattr(self._lib, name) + + +def load_library_for_binding(ffi, module_prefix, modules): + lib = ffi.verifier.load_library() + + 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 lib + + +def build_ffi_for_binding(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. + """ + 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) + + # 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); + verify_source = "\n".join( + [pre_include] + + includes + + [post_include] + + functions + + customizations + ) + ffi = build_ffi( + cdef_source="\n".join(types + functions + macros), + verify_source=verify_source, + libraries=libraries, + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + ) + + return ffi + + +def build_ffi(cdef_source, verify_source, libraries=[], extra_compile_args=[], + extra_link_args=[]): + ffi = FFI() + ffi.cdef(cdef_source) + + ffi.verifier = Verifier( + ffi, + verify_source, + tmpdir='', + modulename=_create_modulename(cdef_source, verify_source, sys.version), + libraries=libraries, + ext_package="cryptography", + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + ) + return ffi + + +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) diff --git a/src/cryptography/hazmat/primitives/__init__.py b/src/cryptography/hazmat/primitives/__init__.py new file mode 100644 index 00000000..2f420574 --- /dev/null +++ b/src/cryptography/hazmat/primitives/__init__.py @@ -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 diff --git a/src/cryptography/hazmat/primitives/asymmetric/__init__.py b/src/cryptography/hazmat/primitives/asymmetric/__init__.py new file mode 100644 index 00000000..2f420574 --- /dev/null +++ b/src/cryptography/hazmat/primitives/asymmetric/__init__.py @@ -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 diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py new file mode 100644 index 00000000..83e01377 --- /dev/null +++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py @@ -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 six + +from cryptography import utils + + +def generate_parameters(key_size, backend): + return backend.generate_dsa_parameters(key_size) + + +def generate_private_key(key_size, backend): + return backend.generate_dsa_private_key_and_parameters(key_size) + + +def _check_dsa_parameters(parameters): + if utils.bit_length(parameters.p) not in [1024, 2048, 3072]: + raise ValueError("p must be exactly 1024, 2048, or 3072 bits long") + if utils.bit_length(parameters.q) not in [160, 256]: + raise ValueError("q must be exactly 160 or 256 bits long") + + if not (1 < parameters.g < parameters.p): + raise ValueError("g, p don't satisfy 1 < g < p.") + + +def _check_dsa_private_numbers(numbers): + parameters = numbers.public_numbers.parameter_numbers + _check_dsa_parameters(parameters) + if numbers.x <= 0 or numbers.x >= parameters.q: + raise ValueError("x must be > 0 and < q.") + + if numbers.public_numbers.y != pow(parameters.g, numbers.x, parameters.p): + raise ValueError("y must be equal to (g ** x % p).") + + +class DSAParameterNumbers(object): + def __init__(self, p, q, g): + if ( + not isinstance(p, six.integer_types) or + not isinstance(q, six.integer_types) or + not isinstance(g, six.integer_types) + ): + raise TypeError( + "DSAParameterNumbers p, q, and g arguments must be integers." + ) + + self._p = p + self._q = q + self._g = g + + p = utils.read_only_property("_p") + q = utils.read_only_property("_q") + g = utils.read_only_property("_g") + + def parameters(self, backend): + return backend.load_dsa_parameter_numbers(self) + + +class DSAPublicNumbers(object): + def __init__(self, y, parameter_numbers): + if not isinstance(y, six.integer_types): + raise TypeError("DSAPublicNumbers y argument must be an integer.") + + if not isinstance(parameter_numbers, DSAParameterNumbers): + raise TypeError( + "parameter_numbers must be a DSAParameterNumbers instance." + ) + + self._y = y + self._parameter_numbers = parameter_numbers + + y = utils.read_only_property("_y") + parameter_numbers = utils.read_only_property("_parameter_numbers") + + def public_key(self, backend): + return backend.load_dsa_public_numbers(self) + + +class DSAPrivateNumbers(object): + def __init__(self, x, public_numbers): + if not isinstance(x, six.integer_types): + raise TypeError("DSAPrivateNumbers x argument must be an integer.") + + if not isinstance(public_numbers, DSAPublicNumbers): + raise TypeError( + "public_numbers must be a DSAPublicNumbers instance." + ) + self._public_numbers = public_numbers + self._x = x + + x = utils.read_only_property("_x") + public_numbers = utils.read_only_property("_public_numbers") + + def private_key(self, backend): + return backend.load_dsa_private_numbers(self) diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py new file mode 100644 index 00000000..ced732fb --- /dev/null +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -0,0 +1,195 @@ +# 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.hazmat.primitives import interfaces + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT571R1(object): + name = "sect571r1" + key_size = 571 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT409R1(object): + name = "sect409r1" + key_size = 409 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT283R1(object): + name = "sect283r1" + key_size = 283 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT233R1(object): + name = "sect233r1" + key_size = 233 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT163R2(object): + name = "sect163r2" + key_size = 163 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT571K1(object): + name = "sect571k1" + key_size = 571 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT409K1(object): + name = "sect409k1" + key_size = 409 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT283K1(object): + name = "sect283k1" + key_size = 283 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT233K1(object): + name = "sect233k1" + key_size = 233 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECT163K1(object): + name = "sect163k1" + key_size = 163 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECP521R1(object): + name = "secp521r1" + key_size = 521 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECP384R1(object): + name = "secp384r1" + key_size = 384 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECP256R1(object): + name = "secp256r1" + key_size = 256 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECP224R1(object): + name = "secp224r1" + key_size = 224 + + +@utils.register_interface(interfaces.EllipticCurve) +class SECP192R1(object): + name = "secp192r1" + key_size = 192 + + +_CURVE_TYPES = { + "prime192v1": SECP192R1, + "prime256v1": SECP256R1, + + "secp192r1": SECP192R1, + "secp224r1": SECP224R1, + "secp256r1": SECP256R1, + "secp384r1": SECP384R1, + "secp521r1": SECP521R1, + + "sect163k1": SECT163K1, + "sect233k1": SECT233K1, + "sect283k1": SECT283K1, + "sect409k1": SECT409K1, + "sect571k1": SECT571K1, + + "sect163r2": SECT163R2, + "sect233r1": SECT233R1, + "sect283r1": SECT283R1, + "sect409r1": SECT409R1, + "sect571r1": SECT571R1, +} + + +@utils.register_interface(interfaces.EllipticCurveSignatureAlgorithm) +class ECDSA(object): + def __init__(self, algorithm): + self._algorithm = algorithm + + algorithm = utils.read_only_property("_algorithm") + + +def generate_private_key(curve, backend): + return backend.generate_elliptic_curve_private_key(curve) + + +class EllipticCurvePublicNumbers(object): + def __init__(self, x, y, curve): + if ( + not isinstance(x, six.integer_types) or + not isinstance(y, six.integer_types) + ): + raise TypeError("x and y must be integers.") + + if not isinstance(curve, interfaces.EllipticCurve): + raise TypeError("curve must provide the EllipticCurve interface.") + + self._y = y + self._x = x + self._curve = curve + + def public_key(self, backend): + try: + return backend.load_elliptic_curve_public_numbers(self) + except AttributeError: + return backend.elliptic_curve_public_key_from_numbers(self) + + curve = utils.read_only_property("_curve") + x = utils.read_only_property("_x") + y = utils.read_only_property("_y") + + +class EllipticCurvePrivateNumbers(object): + def __init__(self, private_value, public_numbers): + if not isinstance(private_value, six.integer_types): + raise TypeError("private_value must be an integer.") + + if not isinstance(public_numbers, EllipticCurvePublicNumbers): + raise TypeError( + "public_numbers must be an EllipticCurvePublicNumbers " + "instance." + ) + + self._private_value = private_value + self._public_numbers = public_numbers + + def private_key(self, backend): + try: + return backend.load_elliptic_curve_private_numbers(self) + except AttributeError: + return backend.elliptic_curve_private_key_from_numbers(self) + + private_value = utils.read_only_property("_private_value") + public_numbers = utils.read_only_property("_public_numbers") diff --git a/src/cryptography/hazmat/primitives/asymmetric/padding.py b/src/cryptography/hazmat/primitives/asymmetric/padding.py new file mode 100644 index 00000000..3967e065 --- /dev/null +++ b/src/cryptography/hazmat/primitives/asymmetric/padding.py @@ -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 + +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): + self._mgf = mgf + + 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 + + +@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): + if not isinstance(algorithm, interfaces.HashAlgorithm): + raise TypeError("Expected instance of interfaces.HashAlgorithm.") + + self._algorithm = algorithm diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py new file mode 100644 index 00000000..db38ed55 --- /dev/null +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -0,0 +1,191 @@ +# 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 + + +def generate_private_key(public_exponent, key_size, backend): + if not isinstance(backend, RSABackend): + raise UnsupportedAlgorithm( + "Backend object does not implement RSABackend.", + _Reasons.BACKEND_MISSING_INTERFACE + ) + + _verify_rsa_parameters(public_exponent, key_size) + return backend.generate_rsa_private_key(public_exponent, key_size) + + +def _verify_rsa_parameters(public_exponent, key_size): + if public_exponent < 3: + raise ValueError("public_exponent must be >= 3.") + + if public_exponent & 1 == 0: + raise ValueError("public_exponent must be odd.") + + if key_size < 512: + raise ValueError("key_size must be at least 512-bits.") + + +def _check_private_key_components(p, q, private_exponent, dmp1, dmq1, iqmp, + public_exponent, modulus): + 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.") + + +def _check_public_key_components(e, n): + if n < 3: + raise ValueError("n must be >= 3.") + + if e < 3 or e >= n: + raise ValueError("e must be >= 3 and < n.") + + if e & 1 == 0: + raise ValueError("e must be odd.") + + +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) + + +class RSAPrivateNumbers(object): + def __init__(self, p, q, d, dmp1, dmq1, iqmp, + public_numbers): + if ( + not isinstance(p, six.integer_types) or + not isinstance(q, six.integer_types) or + not isinstance(d, six.integer_types) or + not isinstance(dmp1, six.integer_types) or + not isinstance(dmq1, six.integer_types) or + not isinstance(iqmp, six.integer_types) + ): + raise TypeError( + "RSAPrivateNumbers p, q, d, dmp1, dmq1, iqmp arguments must" + " all be an integers." + ) + + if not isinstance(public_numbers, RSAPublicNumbers): + raise TypeError( + "RSAPrivateNumbers public_numbers must be an RSAPublicNumbers" + " instance." + ) + + self._p = p + self._q = q + self._d = d + self._dmp1 = dmp1 + self._dmq1 = dmq1 + self._iqmp = iqmp + self._public_numbers = public_numbers + + p = utils.read_only_property("_p") + q = utils.read_only_property("_q") + d = utils.read_only_property("_d") + dmp1 = utils.read_only_property("_dmp1") + dmq1 = utils.read_only_property("_dmq1") + iqmp = utils.read_only_property("_iqmp") + public_numbers = utils.read_only_property("_public_numbers") + + def private_key(self, backend): + return backend.load_rsa_private_numbers(self) + + +class RSAPublicNumbers(object): + def __init__(self, e, n): + if ( + not isinstance(e, six.integer_types) or + not isinstance(n, six.integer_types) + ): + raise TypeError("RSAPublicNumbers arguments must be integers.") + + self._e = e + self._n = n + + e = utils.read_only_property("_e") + n = utils.read_only_property("_n") + + def public_key(self, backend): + return backend.load_rsa_public_numbers(self) + + def __repr__(self): + return "".format(self._e, self._n) diff --git a/src/cryptography/hazmat/primitives/ciphers/__init__.py b/src/cryptography/hazmat/primitives/ciphers/__init__.py new file mode 100644 index 00000000..e5a8ca52 --- /dev/null +++ b/src/cryptography/hazmat/primitives/ciphers/__init__.py @@ -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", +] diff --git a/src/cryptography/hazmat/primitives/ciphers/algorithms.py b/src/cryptography/hazmat/primitives/ciphers/algorithms.py new file mode 100644 index 00000000..bd8437c2 --- /dev/null +++ b/src/cryptography/hazmat/primitives/ciphers/algorithms.py @@ -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 diff --git a/src/cryptography/hazmat/primitives/ciphers/base.py b/src/cryptography/hazmat/primitives/ciphers/base.py new file mode 100644 index 00000000..e3fe5adc --- /dev/null +++ b/src/cryptography/hazmat/primitives/ciphers/base.py @@ -0,0 +1,132 @@ +# 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 diff --git a/src/cryptography/hazmat/primitives/ciphers/modes.py b/src/cryptography/hazmat/primitives/ciphers/modes.py new file mode 100644 index 00000000..d995b876 --- /dev/null +++ b/src/cryptography/hazmat/primitives/ciphers/modes.py @@ -0,0 +1,125 @@ +# 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 _check_iv_length(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 CBC(object): + name = "CBC" + + def __init__(self, initialization_vector): + self._initialization_vector = initialization_vector + + initialization_vector = utils.read_only_property("_initialization_vector") + validate_for_algorithm = _check_iv_length + + +@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 + + initialization_vector = utils.read_only_property("_initialization_vector") + validate_for_algorithm = _check_iv_length + + +@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 + + initialization_vector = utils.read_only_property("_initialization_vector") + validate_for_algorithm = _check_iv_length + + +@utils.register_interface(interfaces.Mode) +@utils.register_interface(interfaces.ModeWithInitializationVector) +class CFB8(object): + name = "CFB8" + + def __init__(self, initialization_vector): + self._initialization_vector = initialization_vector + + initialization_vector = utils.read_only_property("_initialization_vector") + validate_for_algorithm = _check_iv_length + + +@utils.register_interface(interfaces.Mode) +@utils.register_interface(interfaces.ModeWithNonce) +class CTR(object): + name = "CTR" + + def __init__(self, nonce): + self._nonce = nonce + + nonce = utils.read_only_property("_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, min_tag_length=16): + # 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 min_tag_length < 4: + raise ValueError("min_tag_length must be >= 4") + if tag is not None and len(tag) < min_tag_length: + raise ValueError( + "Authentication tag must be {0} bytes or longer.".format( + min_tag_length) + ) + + self._initialization_vector = initialization_vector + self._tag = tag + + tag = utils.read_only_property("_tag") + initialization_vector = utils.read_only_property("_initialization_vector") + + def validate_for_algorithm(self, algorithm): + pass diff --git a/src/cryptography/hazmat/primitives/cmac.py b/src/cryptography/hazmat/primitives/cmac.py new file mode 100644 index 00000000..6f722031 --- /dev/null +++ b/src/cryptography/hazmat/primitives/cmac.py @@ -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 + +from cryptography import utils +from cryptography.exceptions import ( + AlreadyFinalized, UnsupportedAlgorithm, _Reasons +) +from cryptography.hazmat.backends.interfaces import CMACBackend +from cryptography.hazmat.primitives import interfaces + + +@utils.register_interface(interfaces.MACContext) +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 not isinstance(data, bytes): + raise TypeError("data must be bytes.") + 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 not isinstance(signature, bytes): + raise TypeError("signature must be bytes.") + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + + ctx, self._ctx = self._ctx, None + ctx.verify(signature) + + 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() + ) diff --git a/src/cryptography/hazmat/primitives/constant_time.py b/src/cryptography/hazmat/primitives/constant_time.py new file mode 100644 index 00000000..a14eda85 --- /dev/null +++ b/src/cryptography/hazmat/primitives/constant_time.py @@ -0,0 +1,47 @@ +# 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 hmac +import os + +from cryptography.hazmat.bindings.utils import LazyLibrary, build_ffi + + +with open(os.path.join(os.path.dirname(__file__), "src/constant_time.h")) as f: + TYPES = f.read() + +with open(os.path.join(os.path.dirname(__file__), "src/constant_time.c")) as f: + FUNCTIONS = f.read() + + +_ffi = build_ffi(cdef_source=TYPES, verify_source=FUNCTIONS) +_lib = LazyLibrary(_ffi) + + +if hasattr(hmac, "compare_digest"): + def bytes_eq(a, b): + if not isinstance(a, bytes) or not isinstance(b, bytes): + raise TypeError("a and b must be bytes.") + + return hmac.compare_digest(a, b) + +else: + def bytes_eq(a, b): + if not isinstance(a, bytes) or not isinstance(b, bytes): + raise TypeError("a and b must be bytes.") + + return _lib.Cryptography_constant_time_bytes_eq( + a, len(a), b, len(b) + ) == 1 diff --git a/src/cryptography/hazmat/primitives/hashes.py b/src/cryptography/hazmat/primitives/hashes.py new file mode 100644 index 00000000..8c2284e3 --- /dev/null +++ b/src/cryptography/hazmat/primitives/hashes.py @@ -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 + +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 + + algorithm = utils.read_only_property("_algorithm") + + def update(self, data): + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + if not isinstance(data, bytes): + raise TypeError("data must be bytes.") + 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 diff --git a/src/cryptography/hazmat/primitives/hmac.py b/src/cryptography/hazmat/primitives/hmac.py new file mode 100644 index 00000000..47a048ff --- /dev/null +++ b/src/cryptography/hazmat/primitives/hmac.py @@ -0,0 +1,78 @@ +# 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, UnsupportedAlgorithm, _Reasons +) +from cryptography.hazmat.backends.interfaces import HMACBackend +from cryptography.hazmat.primitives import interfaces + + +@utils.register_interface(interfaces.MACContext) +@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 + + algorithm = utils.read_only_property("_algorithm") + + def update(self, data): + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + if not isinstance(data, bytes): + raise TypeError("data must be bytes.") + self._ctx.update(data) + + 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 not isinstance(signature, bytes): + raise TypeError("signature must be bytes.") + if self._ctx is None: + raise AlreadyFinalized("Context was already finalized.") + + ctx, self._ctx = self._ctx, None + ctx.verify(signature) diff --git a/src/cryptography/hazmat/primitives/interfaces.py b/src/cryptography/hazmat/primitives/interfaces.py new file mode 100644 index 00000000..370fd68a --- /dev/null +++ b/src/cryptography/hazmat/primitives/interfaces.py @@ -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 + +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): + """ + Returns an AsymmetricSignatureContext used for signing data. + """ + + @abc.abstractmethod + def decrypt(self, ciphertext, padding): + """ + Decrypts the provided ciphertext. + """ + + @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. + """ + + +@six.add_metaclass(abc.ABCMeta) +class RSAPrivateKeyWithNumbers(RSAPrivateKey): + @abc.abstractmethod + def private_numbers(self): + """ + Returns an RSAPrivateNumbers. + """ + + +@six.add_metaclass(abc.ABCMeta) +class RSAPublicKey(object): + @abc.abstractmethod + def verifier(self, signature, padding, algorithm): + """ + Returns an AsymmetricVerificationContext used for verifying signatures. + """ + + @abc.abstractmethod + def encrypt(self, plaintext, padding): + """ + Encrypts the given plaintext. + """ + + @abc.abstractproperty + def key_size(self): + """ + The bit length of the public modulus. + """ + + +@six.add_metaclass(abc.ABCMeta) +class RSAPublicKeyWithNumbers(RSAPublicKey): + @abc.abstractmethod + def public_numbers(self): + """ + Returns an RSAPublicNumbers + """ + + +@six.add_metaclass(abc.ABCMeta) +class DSAParameters(object): + @abc.abstractmethod + def generate_private_key(self): + """ + Generates and returns a DSAPrivateKey. + """ + + +@six.add_metaclass(abc.ABCMeta) +class DSAParametersWithNumbers(DSAParameters): + @abc.abstractmethod + def parameter_numbers(self): + """ + Returns a DSAParameterNumbers. + """ + + +@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.abstractmethod + def parameters(self): + """ + The DSAParameters object associated with this private key. + """ + + @abc.abstractmethod + def signer(self, signature_algorithm): + """ + Returns an AsymmetricSignatureContext used for signing data. + """ + + +@six.add_metaclass(abc.ABCMeta) +class DSAPrivateKeyWithNumbers(DSAPrivateKey): + @abc.abstractmethod + def private_numbers(self): + """ + Returns a DSAPrivateNumbers. + """ + + +@six.add_metaclass(abc.ABCMeta) +class DSAPublicKey(object): + @abc.abstractproperty + def key_size(self): + """ + The bit length of the prime modulus. + """ + + @abc.abstractmethod + def parameters(self): + """ + The DSAParameters object associated with this public key. + """ + + @abc.abstractmethod + def verifier(self, signature, signature_algorithm): + """ + Returns an AsymmetricVerificationContext used for signing data. + """ + + +@six.add_metaclass(abc.ABCMeta) +class DSAPublicKeyWithNumbers(DSAPublicKey): + @abc.abstractmethod + def public_numbers(self): + """ + Returns a DSAPublicNumbers. + """ + + +@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 EllipticCurve(object): + @abc.abstractproperty + def name(self): + """ + The name of the curve. e.g. secp256r1. + """ + + @abc.abstractproperty + def key_size(self): + """ + The bit length of the base point of the curve. + """ + + +@six.add_metaclass(abc.ABCMeta) +class EllipticCurveSignatureAlgorithm(object): + @abc.abstractproperty + def algorithm(self): + """ + The digest algorithm used with this signature. + """ + + +@six.add_metaclass(abc.ABCMeta) +class EllipticCurvePrivateKey(object): + @abc.abstractmethod + def signer(self, signature_algorithm): + """ + Returns an AsymmetricSignatureContext used for signing data. + """ + + @abc.abstractmethod + def public_key(self): + """ + The EllipticCurvePublicKey for this private key. + """ + + @abc.abstractproperty + def curve(self): + """ + The EllipticCurve that this key is on. + """ + + +@six.add_metaclass(abc.ABCMeta) +class EllipticCurvePrivateKeyWithNumbers(EllipticCurvePrivateKey): + @abc.abstractmethod + def private_numbers(self): + """ + Returns an EllipticCurvePrivateNumbers. + """ + + +@six.add_metaclass(abc.ABCMeta) +class EllipticCurvePublicKey(object): + @abc.abstractmethod + def verifier(self, signature, signature_algorithm): + """ + Returns an AsymmetricVerificationContext used for signing data. + """ + + @abc.abstractproperty + def curve(self): + """ + The EllipticCurve that this key is on. + """ + + +@six.add_metaclass(abc.ABCMeta) +class EllipticCurvePublicKeyWithNumbers(EllipticCurvePublicKey): + @abc.abstractmethod + def public_numbers(self): + """ + Returns an EllipticCurvePublicNumbers. + """ + + +@six.add_metaclass(abc.ABCMeta) +class MACContext(object): + @abc.abstractmethod + def update(self, data): + """ + Processes the provided bytes. + """ + + @abc.abstractmethod + def finalize(self): + """ + Returns the message authentication code as bytes. + """ + + @abc.abstractmethod + def copy(self): + """ + Return a MACContext that is a copy of the current context. + """ + + @abc.abstractmethod + def verify(self, signature): + """ + Checks if the generated message authentication code matches the + signature. + """ + +# DeprecatedIn07 +CMACContext = MACContext diff --git a/src/cryptography/hazmat/primitives/kdf/__init__.py b/src/cryptography/hazmat/primitives/kdf/__init__.py new file mode 100644 index 00000000..2f420574 --- /dev/null +++ b/src/cryptography/hazmat/primitives/kdf/__init__.py @@ -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 diff --git a/src/cryptography/hazmat/primitives/kdf/hkdf.py b/src/cryptography/hazmat/primitives/kdf/hkdf.py new file mode 100644 index 00000000..04d02b26 --- /dev/null +++ b/src/cryptography/hazmat/primitives/kdf/hkdf.py @@ -0,0 +1,124 @@ +# 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 + + if not isinstance(salt, bytes) and salt is not None: + raise TypeError("salt must be bytes.") + + if salt is None: + salt = b"\x00" * (self._algorithm.digest_size // 8) + + self._salt = salt + + self._backend = backend + + self._hkdf_expand = HKDFExpand(self._algorithm, length, info, backend) + + def _extract(self, key_material): + h = hmac.HMAC(self._salt, self._algorithm, backend=self._backend) + h.update(key_material) + return h.finalize() + + def derive(self, key_material): + if not isinstance(key_material, bytes): + raise TypeError("key_material must be bytes.") + + return self._hkdf_expand.derive(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 + + +@utils.register_interface(interfaces.KeyDerivationFunction) +class HKDFExpand(object): + def __init__(self, algorithm, length, info, backend): + if not isinstance(backend, HMACBackend): + raise UnsupportedAlgorithm( + "Backend object does not implement HMACBackend.", + _Reasons.BACKEND_MISSING_INTERFACE + ) + + self._algorithm = algorithm + + self._backend = backend + + 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 not isinstance(info, bytes) and info is not None: + raise TypeError("info must be bytes.") + + if info is None: + info = b"" + + self._info = info + + self._used = False + + 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 not isinstance(key_material, bytes): + raise TypeError("key_material must be bytes.") + + if self._used: + raise AlreadyFinalized + + self._used = True + return self._expand(key_material) + + def verify(self, key_material, expected_key): + if not constant_time.bytes_eq(self.derive(key_material), expected_key): + raise InvalidKey diff --git a/src/cryptography/hazmat/primitives/kdf/pbkdf2.py b/src/cryptography/hazmat/primitives/kdf/pbkdf2.py new file mode 100644 index 00000000..97b6408c --- /dev/null +++ b/src/cryptography/hazmat/primitives/kdf/pbkdf2.py @@ -0,0 +1,66 @@ +# 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, 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 not isinstance(salt, bytes): + raise TypeError("salt must be bytes.") + 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 not isinstance(key_material, bytes): + raise TypeError("key_material must be bytes.") + 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.") diff --git a/src/cryptography/hazmat/primitives/padding.py b/src/cryptography/hazmat/primitives/padding.py new file mode 100644 index 00000000..7aeeff7c --- /dev/null +++ b/src/cryptography/hazmat/primitives/padding.py @@ -0,0 +1,164 @@ +# 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 +from cryptography.hazmat.bindings.utils import LazyLibrary, build_ffi +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 = build_ffi(cdef_source=TYPES, verify_source=FUNCTIONS) +_lib = LazyLibrary(_ffi) + + +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 not isinstance(data, bytes): + raise TypeError("data must be bytes.") + + 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 not isinstance(data, bytes): + raise TypeError("data must be bytes.") + + 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 diff --git a/src/cryptography/hazmat/primitives/serialization.py b/src/cryptography/hazmat/primitives/serialization.py new file mode 100644 index 00000000..0fb560e0 --- /dev/null +++ b/src/cryptography/hazmat/primitives/serialization.py @@ -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 + +import warnings + +from cryptography import utils + + +def load_pem_traditional_openssl_private_key(data, password, backend): + warnings.warn( + "load_pem_traditional_openssl_private_key is deprecated and will be " + "removed in a future version, use load_pem_private_key instead.", + utils.DeprecatedIn06, + stacklevel=2 + ) + + return backend.load_traditional_openssl_pem_private_key( + data, password + ) + + +def load_pem_pkcs8_private_key(data, password, backend): + warnings.warn( + "load_pem_pkcs8_private_key is deprecated and will be removed in a " + "future version, use load_pem_private_key instead.", + utils.DeprecatedIn06, + stacklevel=2 + ) + + return backend.load_pkcs8_pem_private_key(data, password) + + +def load_pem_private_key(data, password, backend): + return backend.load_pem_private_key(data, password) + + +def load_pem_public_key(data, backend): + return backend.load_pem_public_key(data) diff --git a/src/cryptography/hazmat/primitives/src/constant_time.c b/src/cryptography/hazmat/primitives/src/constant_time.c new file mode 100644 index 00000000..13ac4ab9 --- /dev/null +++ b/src/cryptography/hazmat/primitives/src/constant_time.c @@ -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. + +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; +} diff --git a/src/cryptography/hazmat/primitives/src/constant_time.h b/src/cryptography/hazmat/primitives/src/constant_time.h new file mode 100644 index 00000000..4f41034e --- /dev/null +++ b/src/cryptography/hazmat/primitives/src/constant_time.h @@ -0,0 +1,16 @@ +// 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. + + +uint8_t Cryptography_constant_time_bytes_eq(uint8_t *, size_t, uint8_t *, + size_t); diff --git a/src/cryptography/hazmat/primitives/twofactor/__init__.py b/src/cryptography/hazmat/primitives/twofactor/__init__.py new file mode 100644 index 00000000..2f420574 --- /dev/null +++ b/src/cryptography/hazmat/primitives/twofactor/__init__.py @@ -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 diff --git a/src/cryptography/hazmat/primitives/twofactor/hotp.py b/src/cryptography/hazmat/primitives/twofactor/hotp.py new file mode 100644 index 00000000..d0b476a7 --- /dev/null +++ b/src/cryptography/hazmat/primitives/twofactor/hotp.py @@ -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 + +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 = six.indexbytes(hmac_value, len(hmac_value) - 1) & 0b1111 + p = hmac_value[offset:offset + 4] + return struct.unpack(">I", p)[0] & 0x7fffffff diff --git a/src/cryptography/hazmat/primitives/twofactor/totp.py b/src/cryptography/hazmat/primitives/twofactor/totp.py new file mode 100644 index 00000000..854c5163 --- /dev/null +++ b/src/cryptography/hazmat/primitives/twofactor/totp.py @@ -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.") diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py new file mode 100644 index 00000000..03c8c0e8 --- /dev/null +++ b/src/cryptography/utils.py @@ -0,0 +1,64 @@ +# 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 inspect +import sys + + +DeprecatedIn06 = DeprecationWarning + + +def register_interface(iface): + def register_decorator(klass): + verify_interface(iface, klass) + iface.register(klass) + return klass + return register_decorator + + +def read_only_property(name): + return property(lambda self: getattr(self, name)) + + +class InterfaceNotImplemented(Exception): + pass + + +def verify_interface(iface, klass): + for method in iface.__abstractmethods__: + if not hasattr(klass, method): + raise InterfaceNotImplemented( + "{0} is missing a {1!r} method".format(klass, method) + ) + if isinstance(getattr(iface, method), abc.abstractproperty): + # Can't properly verify these yet. + continue + spec = inspect.getargspec(getattr(iface, method)) + actual = inspect.getargspec(getattr(klass, method)) + if spec != actual: + raise InterfaceNotImplemented( + "{0}.{1}'s signature differs from the expected. Expected: " + "{2!r}. Received: {3!r}".format( + klass, method, spec, actual + ) + ) + + +def bit_length(x): + if sys.version_info >= (2, 7): + return x.bit_length() + else: + return len(bin(x)) - (2 + (x <= 0)) -- cgit v1.2.3