diff options
47 files changed, 909 insertions, 122 deletions
diff --git a/AUTHORS.rst b/AUTHORS.rst index 250b717b..c233bc86 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -18,3 +18,4 @@ PGP key fingerprints are enclosed in parentheses. * Matthew Iversen <matt@notevencode.com> (2F04 3DCC D6E6 D5AC D262 2E0B C046 E8A8 7452 2973) * Mohammed Attia <skeuomorf@gmail.com> (854A F9C5 9FF5 6E38 B17D 9587 2D70 E1ED 5290 D357) * Michael Hart <michael.hart1994@gmail.com> +* Mark Adams <mark@markadams.me> (A18A 7DD3 283C CF2A B0CE FE0E C7A0 5E3F C972 098C) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a0d8150d..cf6d2252 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,6 +16,12 @@ Changelog * Added :class:`~cryptography.hazmat.primitives.interfaces.MACContext` as a common interface for CMAC and HMAC and deprecated :class:`~cryptography.hazmat.primitives.interfaces.CMACContext`. +* Added support for encoding and decoding :rfc:`6979` signatures in + :doc:`/hazmat/primitives/asymmetric/utils`. +* Added + :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` to + support the loading of OpenSSH public keys (:rfc:`4253`). Currently, only RSA + keys are supported. 0.6.1 - 2014-10-15 ~~~~~~~~~~~~~~~~~~ diff --git a/dev-requirements.txt b/dev-requirements.txt index 4fff76b5..092b9914 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -5,7 +5,6 @@ invoke iso8601 pep8-naming pretend -pyasn1 pytest requests sphinx diff --git a/docs/community.rst b/docs/community.rst index bf1cd1c7..2b7cdc60 100644 --- a/docs/community.rst +++ b/docs/community.rst @@ -17,4 +17,4 @@ Conduct`_. .. _`Source code`: https://github.com/pyca/cryptography .. _`Issue tracker`: https://github.com/pyca/cryptography/issues .. _`Documentation`: https://cryptography.io/ -.. _`Python Community Code of Conduct`: http://www.python.org/psf/codeofconduct/ +.. _`Python Community Code of Conduct`: https://www.python.org/psf/codeofconduct/ diff --git a/docs/conf.py b/docs/conf.py index b70114d8..fc16b38a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -268,6 +268,6 @@ texinfo_documents = [ # texinfo_show_urls = 'footnote' # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/': None} +intersphinx_mapping = {'https://docs.python.org/': None} epub_theme = 'epub' diff --git a/docs/development/c-bindings.rst b/docs/development/c-bindings.rst index 10d5fc10..993a4ab2 100644 --- a/docs/development/c-bindings.rst +++ b/docs/development/c-bindings.rst @@ -3,7 +3,7 @@ C bindings C bindings are bindings to C libraries, using cffi_ whenever possible. -.. _cffi: http://cffi.readthedocs.org +.. _cffi: https://cffi.readthedocs.org Bindings live in :py:mod:`cryptography.hazmat.bindings`. diff --git a/docs/development/submitting-patches.rst b/docs/development/submitting-patches.rst index ff650c4f..810b8748 100644 --- a/docs/development/submitting-patches.rst +++ b/docs/development/submitting-patches.rst @@ -25,6 +25,9 @@ configuration. You can also run the ``tox`` job with ``tox -e pep8``. `Write comments as complete sentences.`_ +Class names which contains acronyms or initialisms should always be +capitalized. A class should be named ``HTTPClient``, not ``HttpClient``. + Every code file must start with the boilerplate licensing notice: .. code-block:: python diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index 8c2d1361..10c20dba 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -34,10 +34,48 @@ Asymmetric ciphers `enc2-rsa-pkcs8.pem`_ was re-encrypted using a stronger PKCS#8 cipher. * `Botan's ECC private keys`_. +Custom Asymmetric Vectors +~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ``ec_private_key.pem`` - Contains an Elliptic Curve key generated by OpenSSL + from the curve ``secp256r1``. +* ``ec_private_key_encrypted.pem`` - Contains the same Elliptic Curve key as + ``ec_private_key.pem``, except that it is encrypted with AES-128 with the + password "123456". +* ``ec_public_key.pem`` - Contains the public key corresponding to + ``ec_private_key.pem``, generated using OpenSSL. +* ``rsa_private_key.pem`` - Contains an RSA 2048 bit key generated using + OpenSSL, protected by the secret "123456" with DES3 encryption. +* ``rsa_public_key.pem`` - Contains an RSA 2048 bit public generated using + OpenSSL from ``rsa_private_key.pem``. +* ``dsaparam.pem`` - Contains 2048-bit DSA parameters generated using OpenSSL; + contains no keys. +* ``dsa_private_key.pem`` - Contains a DSA 2048 bit key generated using + OpenSSL from the parameters in ``dsaparam.pem``, protected by the secret + "123456" with DES3 encryption. +* ``dsa_public_key.pem`` - Contains a DSA 2048 bit key generated using OpenSSL + from ``dsa_private_key.pem``. + + X.509 ~~~~~ * PKITS test suite from `NIST PKI Testing`_. +* ``v1_cert.pem`` from the OpenSSL source tree (`testx509.pem`_). +* ``ecdsa_root.pem`` - `DigiCert Global Root G3`_, a ``secp384r1`` ECDSA root + certificate. + +Custom X.509 Vectors +~~~~~~~~~~~~~~~~~~~~ + +* ``invalid_version.pem`` - Contains an RSA 2048 bit certificate with the + X.509 version field set to ``0x7``. +* ``post2000utctime.pem`` - Contains an RSA 2048 bit certificate with the + ``notBefore`` and ``notAfter`` fields encoded as post-2000 ``UTCTime``. +* ``dsa_selfsigned_ca.pem`` - Contains a DSA self-signed CA certificate + generated using OpenSSL. +* ``ec_no_named_curve.pem`` - Contains an ECDSA certificate that does not have + an embedded OID defining the curve. Hashes ~~~~~~ @@ -107,27 +145,8 @@ Creating test vectors When official vectors are unavailable ``cryptography`` may choose to build its own using existing vectors as source material. -Current custom vectors -~~~~~~~~~~~~~~~~~~~~~~ - -* ``ec_private_key.pem`` - Contains an Elliptic Curve key generated by OpenSSL - from the curve ``secp256r1``. -* ``ec_private_key_encrypted.pem`` - Contains the same Elliptic Curve key as - ``ec_private_key.pem``, except that it is encrypted with AES-128 with the - password "123456". -* ``ec_public_key.pem`` - Contains the public key corresponding to - ``ec_private_key.pem``, generated using OpenSSL. -* ``rsa_private_key.pem`` - Contains an RSA 2048 bit key generated using - OpenSSL, protected by the secret "123456" with DES3 encryption. -* ``rsa_public_key.pem`` - Contains an RSA 2048 bit public generated using - OpenSSL from ``rsa_private_key.pem``. -* ``dsaparam.pem`` - Contains 2048-bit DSA parameters generated using OpenSSL; - contains no keys. -* ``dsa_private_key.pem`` - Contains a DSA 2048 bit key generated using - OpenSSL from the parameters in ``dsaparam.pem``, protected by the secret - "123456" with DES3 encryption. -* ``dsa_public_key.pem`` - Contains a DSA 2048 bit key generated using OpenSSL - from ``dsa_private_key.pem``. +Custom Symmetric Vectors +~~~~~~~~~~~~~~~~~~~~~~~~ .. toctree:: :maxdepth: 1 @@ -174,3 +193,5 @@ header format (substituting the correct information): .. _`Ed25519 website`: http://ed25519.cr.yp.to/software.html .. _`NIST SP-800-38B`: http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf .. _`NIST PKI Testing`: http://csrc.nist.gov/groups/ST/crypto_apps_infra/pki/pkitesting.html +.. _`testx509.pem`: https://github.com/openssl/openssl/blob/master/test/testx509.pem +.. _`DigiCert Global Root G3`: http://cacerts.digicert.com/DigiCertGlobalRootG3.crt diff --git a/docs/hazmat/backends/openssl.rst b/docs/hazmat/backends/openssl.rst index e829798a..b48e502d 100644 --- a/docs/hazmat/backends/openssl.rst +++ b/docs/hazmat/backends/openssl.rst @@ -78,5 +78,5 @@ seeded from the same pool as ``/dev/random``. .. _`OpenSSL`: https://www.openssl.org/ .. _`initializing the RNG`: https://en.wikipedia.org/wiki/OpenSSL#Predictable_keys_.28Debian-specific.29 -.. _`Yarrow`: http://en.wikipedia.org/wiki/Yarrow_algorithm +.. _`Yarrow`: https://en.wikipedia.org/wiki/Yarrow_algorithm .. _`Microsoft documentation`: http://msdn.microsoft.com/en-us/library/windows/desktop/aa379942(v=vs.85).aspx diff --git a/docs/hazmat/bindings/openssl.rst b/docs/hazmat/bindings/openssl.rst index a6d1c484..36255b52 100644 --- a/docs/hazmat/bindings/openssl.rst +++ b/docs/hazmat/bindings/openssl.rst @@ -46,4 +46,4 @@ OpenSSL. .. _`CFFI`: https://cffi.readthedocs.org/ .. _`OpenSSL`: https://www.openssl.org/ -.. _`thread safety facilities`: http://www.openssl.org/docs/crypto/threads.html +.. _`thread safety facilities`: https://www.openssl.org/docs/crypto/threads.html diff --git a/docs/hazmat/primitives/asymmetric/dsa.rst b/docs/hazmat/primitives/asymmetric/dsa.rst index 43741ede..df3c99fc 100644 --- a/docs/hazmat/primitives/asymmetric/dsa.rst +++ b/docs/hazmat/primitives/asymmetric/dsa.rst @@ -80,7 +80,8 @@ provider. >>> signature = signer.finalize() The ``signature`` is a ``bytes`` object, whose contents is DER encoded as -described in :rfc:`6979`. +described in :rfc:`6979`. This can be decoded using +:func:`~cryptography.hazmat.primitives.asymmetric.utils.decode_rfc6979_signature`. Verification ~~~~~~~~~~~~ diff --git a/docs/hazmat/primitives/asymmetric/ec.rst b/docs/hazmat/primitives/asymmetric/ec.rst index fd20cbb2..13ab7c11 100644 --- a/docs/hazmat/primitives/asymmetric/ec.rst +++ b/docs/hazmat/primitives/asymmetric/ec.rst @@ -53,7 +53,9 @@ Elliptic Curve Signature Algorithms >>> signature = signer.finalize() The ``signature`` is a ``bytes`` object, whose contents is DER encoded as - described in :rfc:`6979`. + described in :rfc:`6979`. This can be decoded using + :func:`~cryptography.hazmat.primitives.asymmetric.utils.decode_rfc6979_signature`. + .. class:: EllipticCurvePrivateNumbers(private_value, public_numbers) diff --git a/docs/hazmat/primitives/asymmetric/index.rst b/docs/hazmat/primitives/asymmetric/index.rst index 6a5228ba..24f0f5b1 100644 --- a/docs/hazmat/primitives/asymmetric/index.rst +++ b/docs/hazmat/primitives/asymmetric/index.rst @@ -11,3 +11,4 @@ Asymmetric algorithms rsa padding serialization + utils diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index a5cebb1d..6c96090a 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -271,4 +271,4 @@ this without having to do the math themselves. .. _`use 65537`: http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html .. _`at least 2048`: http://www.ecrypt.eu.org/documents/D.SPA.20.pdf .. _`OpenPGP`: https://en.wikipedia.org/wiki/Pretty_Good_Privacy -.. _`Chinese Remainder Theorem`: http://en.wikipedia.org/wiki/RSA_%28cryptosystem%29#Using_the_Chinese_remainder_algorithm +.. _`Chinese Remainder Theorem`: https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29#Using_the_Chinese_remainder_algorithm diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index b0b37b80..a9392c7b 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -195,3 +195,42 @@ KEY-----`` or ``-----BEGIN DSA PRIVATE KEY-----``. :raises UnsupportedAlgorithm: If the serialized key is of a type that is not supported by the backend or if the key is encrypted with a symmetric cipher that is not supported by the backend. + +OpenSSH Public Key +~~~~~~~~~~~~~~~~~~ + +The format used by OpenSSH to store public keys, as specified in :rfc:`4253`. + +Currently, only RSA public keys are supported. Any other type of key will +result in an exception being thrown. + +An example RSA key in OpenSSH format (line breaks added for formatting +purposes):: + + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk + FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll + PDA7ZRBnrfiHpSQYQ874AZaAoIjgkv7DBfsE6gcDQLub0PFjWyrYQUJhtOLQEK + vY/G0vt2iRL3juawWmCFdTK3W3XvwAdgGk71i6lHt+deOPNEPN2H58E4odrZ2f + sxn/adpDqfb2sM0kPwQs0aWvrrKGvUaustkivQE4XWiSFnB0oJB/lKK/CKVKuy + ///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX + 2MzHvnbv testkey@localhost + +.. function:: load_ssh_public_key(data, backend) + + .. versionadded:: 0.7 + + Deserialize a public key from OpenSSH (:rfc:`4253`) encoded data to an + instance of the public key type for the specified backend. + + :param bytes data: The OpenSSH encoded key data. + + :param backend: An + :class:`~cryptography.hazmat.backends.interfaces.RSABackend` provider. + + :returns: A new instance of a public key type. + + :raises ValueError: If the OpenSSH data could not be properly decoded or + if the key is not in the proper format. + + :raises UnsupportedAlgorithm: If the serialized key is of a type that is + not supported. diff --git a/docs/hazmat/primitives/asymmetric/utils.rst b/docs/hazmat/primitives/asymmetric/utils.rst new file mode 100644 index 00000000..6b348801 --- /dev/null +++ b/docs/hazmat/primitives/asymmetric/utils.rst @@ -0,0 +1,26 @@ +.. hazmat:: + +Asymmetric Utilities +==================== + +.. currentmodule:: cryptography.hazmat.primitives.asymmetric.utils + + +.. function:: decode_rfc6979_signature(signature) + + Takes in :rfc:`6979` signatures generated by the DSA/ECDSA signers and + returns a tuple ``(r, s)``. + + :param bytes signature: The signature to decode. + + :returns: The decoded tuple ``(r, s)``. + +.. function:: encode_rfc6979_signature(r, s) + + Creates an :rfc:`6979` byte string from raw signature values. + + :param int r: The raw signature value ``r``. + + :param int s: The raw signature value ``s``. + + :return bytes: The encoded signature. diff --git a/docs/hazmat/primitives/interfaces.rst b/docs/hazmat/primitives/interfaces.rst index d964f25c..d87e8d66 100644 --- a/docs/hazmat/primitives/interfaces.rst +++ b/docs/hazmat/primitives/interfaces.rst @@ -9,7 +9,7 @@ properties and methods of most primitive constructs. Backends may also use this information to influence their operation. Interfaces should also be used to document argument and return types. -.. _`Abstract Base Classes`: http://docs.python.org/3.2/library/abc.html +.. _`Abstract Base Classes`: https://docs.python.org/3/library/abc.html Symmetric ciphers @@ -752,5 +752,5 @@ X509 .. _`Chinese remainder theorem`: https://en.wikipedia.org/wiki/Chinese_remainder_theorem .. _`DSA`: https://en.wikipedia.org/wiki/Digital_Signature_Algorithm .. _`CMAC`: https://en.wikipedia.org/wiki/CMAC -.. _`ECDSA`: http://en.wikipedia.org/wiki/ECDSA -.. _`EdDSA`: http://en.wikipedia.org/wiki/EdDSA +.. _`ECDSA`: https://en.wikipedia.org/wiki/ECDSA +.. _`EdDSA`: https://en.wikipedia.org/wiki/EdDSA diff --git a/docs/hazmat/primitives/symmetric-encryption.rst b/docs/hazmat/primitives/symmetric-encryption.rst index 586285b7..b21ef612 100644 --- a/docs/hazmat/primitives/symmetric-encryption.rst +++ b/docs/hazmat/primitives/symmetric-encryption.rst @@ -510,6 +510,6 @@ Interfaces .. _`Communications Security Establishment`: http://www.cse-cst.gc.ca .. _`encrypt`: https://ssd.eff.org/tech/encryption .. _`CRYPTREC`: http://www.cryptrec.go.jp/english/ -.. _`significant patterns in the output`: http://en.wikipedia.org/wiki/Cipher_block_chaining#Electronic_codebook_.28ECB.29 +.. _`significant patterns in the output`: https://en.wikipedia.org/wiki/Cipher_block_chaining#Electronic_codebook_.28ECB.29 .. _`International Data Encryption Algorithm`: https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm .. _`OpenPGP`: http://www.openpgp.org diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index b7b33436..003e37d5 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -24,6 +24,7 @@ fernet Fernet hazmat indistinguishability +initialisms interoperable introspectability invariants diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 0567f800..00000000 --- a/pytest.ini +++ /dev/null @@ -1,5 +0,0 @@ -[pytest] -addopts = -r s -markers = - requires_backend_interface: this test requires a specific backend interface - supported: parametrized test requiring only_if and skip_message @@ -36,6 +36,7 @@ VECTORS_DEPENDENCY = "cryptography_vectors=={0}".format(about['__version__']) requirements = [ CFFI_DEPENDENCY, + "pyasn1", SIX_DEPENDENCY, SETUPTOOLS_DEPENDENCY ] @@ -43,7 +44,6 @@ requirements = [ # If you add a new dep here you probably need to add it in the tox.ini as well test_requirements = [ "pytest", - "pyasn1", "pretend", "iso8601", ] diff --git a/src/cryptography/hazmat/bindings/openssl/bio.py b/src/cryptography/hazmat/bindings/openssl/bio.py index 854b2bc6..6cc1bcb2 100644 --- a/src/cryptography/hazmat/bindings/openssl/bio.py +++ b/src/cryptography/hazmat/bindings/openssl/bio.py @@ -17,7 +17,7 @@ struct bio_method_st { int (*bwrite)(BIO *, const char *, int); int (*bread)(BIO *, char *, int); int (*bputs)(BIO *, const char *); - int (*bgets)(BIO *, char*, int); + int (*bgets)(BIO *, char *, int); long (*ctrl)(BIO *, int, long, void *); int (*create)(BIO *); int (*destroy)(BIO *); @@ -27,7 +27,7 @@ struct bio_method_st { typedef struct bio_method_st BIO_METHOD; struct bio_st { BIO_METHOD *method; - long (*callback)(struct bio_st*, int, const char*, int, long, long); + long (*callback)(struct bio_st *, int, const char *, int, long, long); char *cb_arg; int init; int shutdown; @@ -89,7 +89,7 @@ static const int BIO_TYPE_FILTER; """ FUNCTIONS = """ -BIO* BIO_new(BIO_METHOD *); +BIO *BIO_new(BIO_METHOD *); int BIO_set(BIO *, BIO_METHOD *); int BIO_free(BIO *); void BIO_vfree(BIO *); diff --git a/src/cryptography/hazmat/bindings/openssl/cms.py b/src/cryptography/hazmat/bindings/openssl/cms.py index 7cbedf44..a43df5d9 100644 --- a/src/cryptography/hazmat/bindings/openssl/cms.py +++ b/src/cryptography/hazmat/bindings/openssl/cms.py @@ -25,6 +25,27 @@ typedef ... CMS_RevocationInfoChoice; typedef ... CMS_RecipientInfo; typedef ... CMS_ReceiptRequest; typedef ... CMS_Receipt; + +static const int CMS_TEXT; +static const int CMS_NOCERTS; +static const int CMS_NO_CONTENT_VERIFY; +static const int CMS_NO_ATTR_VERIFY; +static const int CMS_NOSIGS; +static const int CMS_NOINTERN; +static const int CMS_NO_SIGNER_CERT_VERIFY; +static const int CMS_NOVERIFY; +static const int CMS_DETACHED; +static const int CMS_BINARY; +static const int CMS_NOATTR; +static const int CMS_NOSMIMECAP; +static const int CMS_NOOLDMIMETYPE; +static const int CMS_CRLFEOL; +static const int CMS_STREAM; +static const int CMS_NOCRL; +static const int CMS_PARTIAL; +static const int CMS_REUSE_DIGEST; +static const int CMS_USE_KEYID; +static const int CMS_DEBUG_DECRYPT; """ FUNCTIONS = """ @@ -59,6 +80,26 @@ typedef void CMS_RevocationInfoChoice; typedef void CMS_RecipientInfo; typedef void CMS_ReceiptRequest; typedef void CMS_Receipt; +const long CMS_TEXT = 0; +const long CMS_NOCERTS = 0; +const long CMS_NO_CONTENT_VERIFY = 0; +const long CMS_NO_ATTR_VERIFY = 0; +const long CMS_NOSIGS = 0; +const long CMS_NOINTERN = 0; +const long CMS_NO_SIGNER_CERT_VERIFY = 0; +const long CMS_NOVERIFY = 0; +const long CMS_DETACHED = 0; +const long CMS_BINARY = 0; +const long CMS_NOATTR = 0; +const long CMS_NOSMIMECAP = 0; +const long CMS_NOOLDMIMETYPE = 0; +const long CMS_CRLFEOL = 0; +const long CMS_STREAM = 0; +const long CMS_NOCRL = 0; +const long CMS_PARTIAL = 0; +const long CMS_REUSE_DIGEST = 0; +const long CMS_USE_KEYID = 0; +const long CMS_DEBUG_DECRYPT = 0; 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; @@ -87,5 +128,25 @@ CONDITIONAL_NAMES = { "CMS_encrypt", "CMS_decrypt", "CMS_add1_signer", + "CMS_TEXT", + "CMS_NOCERTS", + "CMS_NO_CONTENT_VERIFY", + "CMS_NO_ATTR_VERIFY", + "CMS_NOSIGS", + "CMS_NOINTERN", + "CMS_NO_SIGNER_CERT_VERIFY", + "CMS_NOVERIFY", + "CMS_DETACHED", + "CMS_BINARY", + "CMS_NOATTR", + "CMS_NOSMIMECAP", + "CMS_NOOLDMIMETYPE", + "CMS_CRLFEOL", + "CMS_STREAM", + "CMS_NOCRL", + "CMS_PARTIAL", + "CMS_REUSE_DIGEST", + "CMS_USE_KEYID", + "CMS_DEBUG_DECRYPT", ] } diff --git a/src/cryptography/hazmat/bindings/openssl/ecdsa.py b/src/cryptography/hazmat/bindings/openssl/ecdsa.py index 30866d11..db21025c 100644 --- a/src/cryptography/hazmat/bindings/openssl/ecdsa.py +++ b/src/cryptography/hazmat/bindings/openssl/ecdsa.py @@ -34,7 +34,7 @@ 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_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 *); @@ -44,9 +44,9 @@ 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(); +const ECDSA_METHOD *ECDSA_OpenSSL(); void ECDSA_set_default_method(const ECDSA_METHOD *); -const ECDSA_METHOD* ECDSA_get_default_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 *); @@ -72,7 +72,7 @@ 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; + 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; diff --git a/src/cryptography/hazmat/bindings/openssl/err.py b/src/cryptography/hazmat/bindings/openssl/err.py index 1d43acd7..ec393c1b 100644 --- a/src/cryptography/hazmat/bindings/openssl/err.py +++ b/src/cryptography/hazmat/bindings/openssl/err.py @@ -231,11 +231,11 @@ 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 *); +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); +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); diff --git a/src/cryptography/hazmat/bindings/openssl/ssl.py b/src/cryptography/hazmat/bindings/openssl/ssl.py index 1aed28d5..9a48f586 100644 --- a/src/cryptography/hazmat/bindings/openssl/ssl.py +++ b/src/cryptography/hazmat/bindings/openssl/ssl.py @@ -15,7 +15,7 @@ TYPES = """ * Internally invented symbols to tell which versions of SSL/TLS are supported. */ static const long Cryptography_HAS_SSL2; -static const long Cryptography_HAS_SSL3_METHOD; +static const long Cryptography_HAS_SSL3; static const long Cryptography_HAS_TLSv1_1; static const long Cryptography_HAS_TLSv1_2; static const long Cryptography_HAS_SECURE_RENEGOTIATION; @@ -211,6 +211,8 @@ 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); +int SSL_CTX_check_private_key(const SSL_CTX *); + 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 *); @@ -320,7 +322,7 @@ void (*SSL_CTX_get_info_callback(SSL_CTX *))(const SSL *, int, int); 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*); +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. @@ -351,8 +353,8 @@ 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); +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 **, @@ -385,13 +387,13 @@ SSL_METHOD* (*SSLv2_server_method)(void) = NULL; static const long Cryptography_HAS_SSL2 = 1; #endif -#ifdef OPENSSL_NO_SSL3_METHOD -static const long Cryptography_HAS_SSL3_METHOD = 0; +#ifdef OPENSSL_NO_SSL3 +static const long Cryptography_HAS_SSL3 = 0; SSL_METHOD* (*SSLv3_method)(void) = NULL; SSL_METHOD* (*SSLv3_client_method)(void) = NULL; SSL_METHOD* (*SSLv3_server_method)(void) = NULL; #else -static const long Cryptography_HAS_SSL3_METHOD = 1; +static const long Cryptography_HAS_SSL3 = 1; #endif #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME @@ -485,7 +487,7 @@ 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) { +const SSL_METHOD *Cryptography_SSL_CTX_get_method(const SSL_CTX *ctx) { return ctx->method; } @@ -523,9 +525,9 @@ static const long Cryptography_HAS_NEXTPROTONEG = 1; /* ALPN was added in OpenSSL 1.0.2. */ #if OPENSSL_VERSION_NUMBER < 0x10002001L int (*SSL_CTX_set_alpn_protos)(SSL_CTX *, - const unsigned char*, + const unsigned char *, unsigned) = NULL; -int (*SSL_set_alpn_protos)(SSL *, 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 **, @@ -564,7 +566,7 @@ CONDITIONAL_NAMES = { "SSLv2_server_method", ], - "Cryptography_HAS_SSL3_METHOD": [ + "Cryptography_HAS_SSL3": [ "SSLv3_method", "SSLv3_client_method", "SSLv3_server_method", diff --git a/src/cryptography/hazmat/primitives/asymmetric/dsa.py b/src/cryptography/hazmat/primitives/asymmetric/dsa.py index 5d942e04..9b06f3e6 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/dsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/dsa.py @@ -59,6 +59,15 @@ class DSAParameterNumbers(object): def parameters(self, backend): return backend.load_dsa_parameter_numbers(self) + def __eq__(self, other): + if not isinstance(other, DSAParameterNumbers): + return NotImplemented + + return self.p == other.p and self.q == other.q and self.g == other.g + + def __ne__(self, other): + return not self == other + class DSAPublicNumbers(object): def __init__(self, y, parameter_numbers): @@ -79,6 +88,18 @@ class DSAPublicNumbers(object): def public_key(self, backend): return backend.load_dsa_public_numbers(self) + def __eq__(self, other): + if not isinstance(other, DSAPublicNumbers): + return NotImplemented + + return ( + self.y == other.y and + self.parameter_numbers == other.parameter_numbers + ) + + def __ne__(self, other): + return not self == other + class DSAPrivateNumbers(object): def __init__(self, x, public_numbers): @@ -97,3 +118,14 @@ class DSAPrivateNumbers(object): def private_key(self, backend): return backend.load_dsa_private_numbers(self) + + def __eq__(self, other): + if not isinstance(other, DSAPrivateNumbers): + return NotImplemented + + return ( + self.x == other.x and self.public_numbers == other.public_numbers + ) + + def __ne__(self, other): + return not self == other diff --git a/src/cryptography/hazmat/primitives/asymmetric/ec.py b/src/cryptography/hazmat/primitives/asymmetric/ec.py index d9c41c19..202f1c97 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/ec.py +++ b/src/cryptography/hazmat/primitives/asymmetric/ec.py @@ -161,6 +161,20 @@ class EllipticCurvePublicNumbers(object): x = utils.read_only_property("_x") y = utils.read_only_property("_y") + def __eq__(self, other): + if not isinstance(other, EllipticCurvePublicNumbers): + return NotImplemented + + return ( + self.x == other.x and + self.y == other.y and + self.curve.name == other.curve.name and + self.curve.key_size == other.curve.key_size + ) + + def __ne__(self, other): + return not self == other + class EllipticCurvePrivateNumbers(object): def __init__(self, private_value, public_numbers): @@ -184,3 +198,15 @@ class EllipticCurvePrivateNumbers(object): private_value = utils.read_only_property("_private_value") public_numbers = utils.read_only_property("_public_numbers") + + def __eq__(self, other): + if not isinstance(other, EllipticCurvePrivateNumbers): + return NotImplemented + + return ( + self.private_value == other.private_value and + self.public_numbers == other.public_numbers + ) + + def __ne__(self, other): + return not self == other diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py index 6aeed006..0cc6b22b 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -160,6 +160,23 @@ class RSAPrivateNumbers(object): def private_key(self, backend): return backend.load_rsa_private_numbers(self) + def __eq__(self, other): + if not isinstance(other, RSAPrivateNumbers): + return NotImplemented + + return ( + self.p == other.p and + self.q == other.q and + self.d == other.d and + self.dmp1 == other.dmp1 and + self.dmq1 == other.dmq1 and + self.iqmp == other.iqmp and + self.public_numbers == other.public_numbers + ) + + def __ne__(self, other): + return not self == other + class RSAPublicNumbers(object): def __init__(self, e, n): @@ -180,3 +197,12 @@ class RSAPublicNumbers(object): def __repr__(self): return "<RSAPublicNumbers(e={0}, n={1})>".format(self._e, self._n) + + def __eq__(self, other): + if not isinstance(other, RSAPublicNumbers): + return NotImplemented + + return self.e == other.e and self.n == other.n + + def __ne__(self, other): + return not self == other diff --git a/src/cryptography/hazmat/primitives/asymmetric/utils.py b/src/cryptography/hazmat/primitives/asymmetric/utils.py new file mode 100644 index 00000000..71f4ff8e --- /dev/null +++ b/src/cryptography/hazmat/primitives/asymmetric/utils.py @@ -0,0 +1,46 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import absolute_import, division, print_function + +from pyasn1.codec.der import decoder, encoder +from pyasn1.error import PyAsn1Error +from pyasn1.type import namedtype, univ + +import six + + +class _DSSSigValue(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('r', univ.Integer()), + namedtype.NamedType('s', univ.Integer()) + ) + + +def decode_rfc6979_signature(signature): + try: + data, remaining = decoder.decode(signature, asn1Spec=_DSSSigValue()) + except PyAsn1Error: + raise ValueError("Invalid signature data. Unable to decode ASN.1") + + if remaining: + raise ValueError( + "The signature contains bytes after the end of the ASN.1 sequence." + ) + r = int(data.getComponentByName('r')) + s = int(data.getComponentByName('s')) + return (r, s) + + +def encode_rfc6979_signature(r, s): + if ( + not isinstance(r, six.integer_types) or + not isinstance(s, six.integer_types) + ): + raise ValueError("Both r and s must be integers") + + sig = _DSSSigValue() + sig.setComponentByName('r', r) + sig.setComponentByName('s', s) + return encoder.encode(sig) diff --git a/src/cryptography/hazmat/primitives/serialization.py b/src/cryptography/hazmat/primitives/serialization.py index b9cf5967..0dbbc85c 100644 --- a/src/cryptography/hazmat/primitives/serialization.py +++ b/src/cryptography/hazmat/primitives/serialization.py @@ -4,9 +4,13 @@ from __future__ import absolute_import, division, print_function +import base64 +import struct import warnings from cryptography import utils +from cryptography.exceptions import UnsupportedAlgorithm +from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers def load_pem_traditional_openssl_private_key(data, password, backend): @@ -39,3 +43,76 @@ def load_pem_private_key(data, password, backend): def load_pem_public_key(data, backend): return backend.load_pem_public_key(data) + + +def load_ssh_public_key(data, backend): + key_parts = data.split(b' ') + + if len(key_parts) != 2 and len(key_parts) != 3: + raise ValueError( + 'Key is not in the proper format or contains extra data.') + + key_type = key_parts[0] + key_body = key_parts[1] + + if not key_type.startswith(b'ssh-'): + raise ValueError('SSH-formatted keys must begin with \'ssh-\'.') + + if not key_type.startswith(b'ssh-rsa'): + raise UnsupportedAlgorithm('Only RSA keys are currently supported.') + + return _load_ssh_rsa_public_key(key_body, backend) + + +def _load_ssh_rsa_public_key(key_body, backend): + data = base64.b64decode(key_body) + + key_type, rest = _read_next_string(data) + e, rest = _read_next_mpint(rest) + n, rest = _read_next_mpint(rest) + + if key_type != b'ssh-rsa': + raise ValueError( + 'Key header and key body contain different key type values.') + + if rest: + raise ValueError('Key body contains extra bytes.') + + return backend.load_rsa_public_numbers(RSAPublicNumbers(e, n)) + + +def _read_next_string(data): + """Retrieves the next RFC 4251 string value from the data.""" + str_len, = struct.unpack('>I', data[:4]) + return data[4:4 + str_len], data[4 + str_len:] + + +def _read_next_mpint(data): + """ + Reads the next mpint from the data. + + Currently, all mpints are interpreted as unsigned. + """ + mpint_data, rest = _read_next_string(data) + + return _int_from_bytes(mpint_data, byteorder='big', signed=False), rest + + +if hasattr(int, "from_bytes"): + _int_from_bytes = int.from_bytes +else: + def _int_from_bytes(data, byteorder, signed=False): + assert byteorder == 'big' + assert not signed + + if len(data) % 4 != 0: + data = (b'\x00' * (4 - (len(data) % 4))) + data + + result = 0 + + while len(data) > 0: + digit, = struct.unpack('>I', data[:4]) + result = (result << 32) + digit + data = data[4:] + + return result diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 63464dfa..78f73464 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -48,8 +48,9 @@ def verify_interface(iface, klass): ) -def bit_length(x): - if sys.version_info >= (2, 7): +if sys.version_info >= (2, 7): + def bit_length(x): return x.bit_length() - else: +else: + def bit_length(x): return len(bin(x)) - (2 + (x <= 0)) @@ -17,6 +17,9 @@ JENKINS_URL = "https://jenkins.cryptography.io/job/cryptography-wheel-builder" def wait_for_build_completed(session): + # Wait 3 seconds before actually checking if the build is complete, to + # ensure that it had time to really start. + time.sleep(3) while True: response = session.get( "{0}/lastBuild/api/json/".format(JENKINS_URL), diff --git a/tests/hazmat/primitives/test_asym_utils.py b/tests/hazmat/primitives/test_asym_utils.py new file mode 100644 index 00000000..bf55bad8 --- /dev/null +++ b/tests/hazmat/primitives/test_asym_utils.py @@ -0,0 +1,65 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import absolute_import, division, print_function + +import pytest + +from cryptography.hazmat.primitives.asymmetric.utils import ( + decode_rfc6979_signature, encode_rfc6979_signature +) + + +def test_rfc6979_signature(): + sig = encode_rfc6979_signature(1, 1) + assert sig == b"0\x06\x02\x01\x01\x02\x01\x01" + assert decode_rfc6979_signature(sig) == (1, 1) + + r_s1 = ( + 1037234182290683143945502320610861668562885151617, + 559776156650501990899426031439030258256861634312 + ) + sig2 = encode_rfc6979_signature(*r_s1) + assert sig2 == ( + b'0-\x02\x15\x00\xb5\xaf0xg\xfb\x8bT9\x00\x13\xccg\x02\r\xdf\x1f,\x0b' + b'\x81\x02\x14b\r;"\xabP1D\x0c>5\xea\xb6\xf4\x81)\x8f\x9e\x9f\x08' + ) + assert decode_rfc6979_signature(sig2) == r_s1 + + sig3 = encode_rfc6979_signature(0, 0) + assert sig3 == b"0\x06\x02\x01\x00\x02\x01\x00" + assert decode_rfc6979_signature(sig3) == (0, 0) + + sig4 = encode_rfc6979_signature(-1, 0) + assert sig4 == b"0\x06\x02\x01\xFF\x02\x01\x00" + assert decode_rfc6979_signature(sig4) == (-1, 0) + + +def test_encode_rfc6979_non_integer(): + with pytest.raises(ValueError): + encode_rfc6979_signature("h", 3) + + with pytest.raises(ValueError): + encode_rfc6979_signature("3", "2") + + with pytest.raises(ValueError): + encode_rfc6979_signature(3, "h") + + with pytest.raises(ValueError): + encode_rfc6979_signature(3.3, 1.2) + + with pytest.raises(ValueError): + encode_rfc6979_signature("hello", "world") + + +def test_decode_rfc6979_trailing_bytes(): + with pytest.raises(ValueError): + decode_rfc6979_signature(b"0\x06\x02\x01\x01\x02\x01\x01\x00\x00\x00") + + +def test_decode_rfc6979_invalid_asn1(): + with pytest.raises(ValueError): + # This byte sequence has an invalid ASN.1 sequence length as well as + # an invalid integer length for the second integer. + decode_rfc6979_signature(b"0\x07\x02\x01\x01\x02\x02\x01") diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py index 6411b7f9..8c0fb80c 100644 --- a/tests/hazmat/primitives/test_dsa.py +++ b/tests/hazmat/primitives/test_dsa.py @@ -12,14 +12,17 @@ from cryptography.exceptions import AlreadyFinalized, InvalidSignature from cryptography.hazmat.backends.interfaces import DSABackend from cryptography.hazmat.primitives import hashes, interfaces from cryptography.hazmat.primitives.asymmetric import dsa +from cryptography.hazmat.primitives.asymmetric.utils import ( + encode_rfc6979_signature +) from cryptography.utils import bit_length from .fixtures_dsa import ( DSA_KEY_1024, DSA_KEY_2048, DSA_KEY_3072 ) from ...utils import ( - der_encode_dsa_signature, load_fips_dsa_key_pair_vectors, - load_fips_dsa_sig_vectors, load_vectors_from_file, + load_fips_dsa_key_pair_vectors, load_fips_dsa_sig_vectors, + load_vectors_from_file, ) @@ -557,7 +560,7 @@ class TestDSAVerification(object): ), y=vector['y'] ).public_key(backend) - sig = der_encode_dsa_signature(vector['r'], vector['s']) + sig = encode_rfc6979_signature(vector['r'], vector['s']) verifier = public_key.verifier(sig, algorithm()) verifier.update(vector['msg']) if vector['result'] == "F": @@ -702,3 +705,67 @@ class TestDSANumbers(object): with pytest.raises(TypeError): dsa.DSAPrivateNumbers(x=None, public_numbers=public_numbers) + + +class TestDSANumberEquality(object): + def test_parameter_numbers_eq(self): + param = dsa.DSAParameterNumbers(1, 2, 3) + assert param == dsa.DSAParameterNumbers(1, 2, 3) + + def test_parameter_numbers_ne(self): + param = dsa.DSAParameterNumbers(1, 2, 3) + assert param != dsa.DSAParameterNumbers(1, 2, 4) + assert param != dsa.DSAParameterNumbers(1, 1, 3) + assert param != dsa.DSAParameterNumbers(2, 2, 3) + assert param != object() + + def test_public_numbers_eq(self): + pub = dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 3)) + assert pub == dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 3)) + + def test_public_numbers_ne(self): + pub = dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 3)) + assert pub != dsa.DSAPublicNumbers(2, dsa.DSAParameterNumbers(1, 2, 3)) + assert pub != dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(2, 2, 3)) + assert pub != dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 3, 3)) + assert pub != dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 4)) + assert pub != object() + + def test_private_numbers_eq(self): + pub = dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 3)) + priv = dsa.DSAPrivateNumbers(1, pub) + assert priv == dsa.DSAPrivateNumbers( + 1, dsa.DSAPublicNumbers( + 1, dsa.DSAParameterNumbers(1, 2, 3) + ) + ) + + def test_private_numbers_ne(self): + pub = dsa.DSAPublicNumbers(1, dsa.DSAParameterNumbers(1, 2, 3)) + priv = dsa.DSAPrivateNumbers(1, pub) + assert priv != dsa.DSAPrivateNumbers( + 2, dsa.DSAPublicNumbers( + 1, dsa.DSAParameterNumbers(1, 2, 3) + ) + ) + assert priv != dsa.DSAPrivateNumbers( + 1, dsa.DSAPublicNumbers( + 2, dsa.DSAParameterNumbers(1, 2, 3) + ) + ) + assert priv != dsa.DSAPrivateNumbers( + 1, dsa.DSAPublicNumbers( + 1, dsa.DSAParameterNumbers(2, 2, 3) + ) + ) + assert priv != dsa.DSAPrivateNumbers( + 1, dsa.DSAPublicNumbers( + 1, dsa.DSAParameterNumbers(1, 3, 3) + ) + ) + assert priv != dsa.DSAPrivateNumbers( + 1, dsa.DSAPublicNumbers( + 1, dsa.DSAParameterNumbers(1, 2, 4) + ) + ) + assert priv != object() diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index 3080a6c2..84c447c1 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -13,11 +13,13 @@ from cryptography import exceptions, utils from cryptography.hazmat.backends.interfaces import EllipticCurveBackend from cryptography.hazmat.primitives import hashes, interfaces from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.asymmetric.utils import ( + encode_rfc6979_signature +) from ...utils import ( - der_encode_dsa_signature, load_fips_ecdsa_key_pair_vectors, - load_fips_ecdsa_signing_vectors, load_vectors_from_file, - raises_unsupported_algorithm + load_fips_ecdsa_key_pair_vectors, load_fips_ecdsa_signing_vectors, + load_vectors_from_file, raises_unsupported_algorithm ) _HASH_TYPES = { @@ -305,10 +307,7 @@ class TestECDSAVectors(object): curve_type() ).public_key(backend) - signature = der_encode_dsa_signature( - vector['r'], - vector['s'] - ) + signature = encode_rfc6979_signature(vector['r'], vector['s']) verifier = key.verifier( signature, @@ -337,10 +336,7 @@ class TestECDSAVectors(object): curve_type() ).public_key(backend) - signature = der_encode_dsa_signature( - vector['r'], - vector['s'] - ) + signature = encode_rfc6979_signature(vector['r'], vector['s']) verifier = key.verifier( signature, @@ -364,3 +360,40 @@ class TestECDSAVectors(object): numbers = ec.EllipticCurvePrivateNumbers(1, pub_numbers) assert numbers.private_key(b) == b"private_key" assert pub_numbers.public_key(b) == b"public_key" + + +class TestECNumbersEquality(object): + def test_public_numbers_eq(self): + pub = ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1()) + assert pub == ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1()) + + def test_public_numbers_ne(self): + pub = ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1()) + assert pub != ec.EllipticCurvePublicNumbers(1, 2, ec.SECP384R1()) + assert pub != ec.EllipticCurvePublicNumbers(1, 3, ec.SECP192R1()) + assert pub != ec.EllipticCurvePublicNumbers(2, 2, ec.SECP192R1()) + assert pub != object() + + def test_private_numbers_eq(self): + pub = ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1()) + priv = ec.EllipticCurvePrivateNumbers(1, pub) + assert priv == ec.EllipticCurvePrivateNumbers( + 1, ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1()) + ) + + def test_private_numbers_ne(self): + pub = ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1()) + priv = ec.EllipticCurvePrivateNumbers(1, pub) + assert priv != ec.EllipticCurvePrivateNumbers( + 2, ec.EllipticCurvePublicNumbers(1, 2, ec.SECP192R1()) + ) + assert priv != ec.EllipticCurvePrivateNumbers( + 1, ec.EllipticCurvePublicNumbers(2, 2, ec.SECP192R1()) + ) + assert priv != ec.EllipticCurvePrivateNumbers( + 1, ec.EllipticCurvePublicNumbers(1, 3, ec.SECP192R1()) + ) + assert priv != ec.EllipticCurvePrivateNumbers( + 1, ec.EllipticCurvePublicNumbers(1, 2, ec.SECP521R1()) + ) + assert priv != object() diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 581976ae..095ed037 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -18,7 +18,9 @@ from cryptography.exceptions import ( from cryptography.hazmat.backends.interfaces import RSABackend from cryptography.hazmat.primitives import hashes, interfaces from cryptography.hazmat.primitives.asymmetric import padding, rsa -from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers +from cryptography.hazmat.primitives.asymmetric.rsa import ( + RSAPrivateNumbers, RSAPublicNumbers +) from .fixtures_rsa import ( RSA_KEY_1024, RSA_KEY_1025, RSA_KEY_1026, RSA_KEY_1027, RSA_KEY_1028, @@ -1647,3 +1649,52 @@ class TestRSANumbers(object): def test_public_number_repr(self): num = RSAPublicNumbers(1, 1) assert repr(num) == "<RSAPublicNumbers(e=1, n=1)>" + + +class TestRSANumbersEquality(object): + def test_public_numbers_eq(self): + num = RSAPublicNumbers(1, 2) + num2 = RSAPublicNumbers(1, 2) + assert num == num2 + + def test_public_numbers_ne(self): + num = RSAPublicNumbers(1, 2) + assert num != RSAPublicNumbers(2, 2) + assert num != RSAPublicNumbers(1, 3) + assert num != object() + + def test_private_numbers_eq(self): + pub = RSAPublicNumbers(1, 2) + num = RSAPrivateNumbers(1, 2, 3, 4, 5, 6, pub) + pub2 = RSAPublicNumbers(1, 2) + num2 = RSAPrivateNumbers(1, 2, 3, 4, 5, 6, pub2) + assert num == num2 + + def test_private_numbers_ne(self): + pub = RSAPublicNumbers(1, 2) + num = RSAPrivateNumbers(1, 2, 3, 4, 5, 6, pub) + assert num != RSAPrivateNumbers( + 1, 2, 3, 4, 5, 7, RSAPublicNumbers(1, 2) + ) + assert num != RSAPrivateNumbers( + 1, 2, 3, 4, 4, 6, RSAPublicNumbers(1, 2) + ) + assert num != RSAPrivateNumbers( + 1, 2, 3, 5, 5, 6, RSAPublicNumbers(1, 2) + ) + assert num != RSAPrivateNumbers( + 1, 2, 4, 4, 5, 6, RSAPublicNumbers(1, 2) + ) + assert num != RSAPrivateNumbers( + 1, 3, 3, 4, 5, 6, RSAPublicNumbers(1, 2) + ) + assert num != RSAPrivateNumbers( + 2, 2, 3, 4, 5, 6, RSAPublicNumbers(1, 2) + ) + assert num != RSAPrivateNumbers( + 1, 2, 3, 4, 5, 6, RSAPublicNumbers(2, 2) + ) + assert num != RSAPrivateNumbers( + 1, 2, 3, 4, 5, 6, RSAPublicNumbers(1, 3) + ) + assert num != object() diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index 726e73dd..abb55751 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -9,16 +9,17 @@ import textwrap import pytest -from cryptography.exceptions import _Reasons +from cryptography.exceptions import UnsupportedAlgorithm, _Reasons from cryptography.hazmat.backends.interfaces import ( EllipticCurveBackend, PEMSerializationBackend, PKCS8SerializationBackend, - TraditionalOpenSSLSerializationBackend + RSABackend, TraditionalOpenSSLSerializationBackend ) from cryptography.hazmat.primitives import interfaces from cryptography.hazmat.primitives.asymmetric import ec +from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers from cryptography.hazmat.primitives.serialization import ( load_pem_pkcs8_private_key, load_pem_private_key, load_pem_public_key, - load_pem_traditional_openssl_private_key + load_pem_traditional_openssl_private_key, load_ssh_public_key ) @@ -680,3 +681,118 @@ class TestPKCS8Serialization(object): pemfile.read().encode(), password, backend ) ) + + +@pytest.mark.requires_backend_interface(interface=RSABackend) +class TestSSHSerialization(object): + def test_load_ssh_public_key_unsupported(self, backend): + ssh_key = b'ssh-dss AAAAB3NzaC1kc3MAAACBAO7q0a7VsQZcdRTCqFentQt...' + + with pytest.raises(UnsupportedAlgorithm): + load_ssh_public_key(ssh_key, backend) + + def test_load_ssh_public_key_bad_format(self, backend): + ssh_key = b'not-a-real-key text' + + with pytest.raises(ValueError): + load_ssh_public_key(ssh_key, backend) + + def test_load_ssh_public_key_rsa_too_short(self, backend): + ssh_key = b'ssh-rsa' + + with pytest.raises(ValueError): + load_ssh_public_key(ssh_key, backend) + + def test_load_ssh_public_key_rsa_key_types_dont_match(self, backend): + ssh_key = ( + b"ssh-bad AAAAB3NzaC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk" + b"FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll" + b"PDA7ZRBnrfiHpSQYQ874AZaAoIjgkv7DBfsE6gcDQLub0PFjWyrYQUJhtOLQEK" + b"vY/G0vt2iRL3juawWmCFdTK3W3XvwAdgGk71i6lHt+deOPNEPN2H58E4odrZ2f" + b"sxn/adpDqfb2sM0kPwQs0aWvrrKGvUaustkivQE4XWiSFnB0oJB/lKK/CKVKuy" + b"///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX" + b"2MzHvnbv testkey@localhost extra" + ) + + with pytest.raises(ValueError): + load_ssh_public_key(ssh_key, backend) + + def test_load_ssh_public_key_rsa_extra_string_after_comment(self, backend): + ssh_key = ( + b"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk" + b"FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll" + b"PDA7ZRBnrfiHpSQYQ874AZaAoIjgkv7DBfsE6gcDQLub0PFjWyrYQUJhtOLQEK" + b"vY/G0vt2iRL3juawWmCFdTK3W3XvwAdgGk71i6lHt+deOPNEPN2H58E4odrZ2f" + b"sxn/adpDqfb2sM0kPwQs0aWvrrKGvUaustkivQE4XWiSFnB0oJB/lKK/CKVKuy" + b"///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX" + # Extra section appended + b"2MzHvnbv testkey@localhost extra" + ) + + with pytest.raises(ValueError): + load_ssh_public_key(ssh_key, backend) + + def test_load_ssh_public_key_rsa_extra_data_after_modulo(self, backend): + ssh_key = ( + b"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk" + b"FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll" + b"PDA7ZRBnrfiHpSQYQ874AZaAoIjgkv7DBfsE6gcDQLub0PFjWyrYQUJhtOLQEK" + b"vY/G0vt2iRL3juawWmCFdTK3W3XvwAdgGk71i6lHt+deOPNEPN2H58E4odrZ2f" + b"sxn/adpDqfb2sM0kPwQs0aWvrrKGvUaustkivQE4XWiSFnB0oJB/lKK/CKVKuy" + b"///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX" + b"2MzHvnbvAQ== testkey@localhost" + ) + + with pytest.raises(ValueError): + load_ssh_public_key(ssh_key, backend) + + def test_load_ssh_public_key_rsa_different_string(self, backend): + ssh_key = ( + # "AAAAB3NzA" the final A is capitalized here to cause the string + # ssh-rsa inside the base64 encoded blob to be incorrect. It should + # be a lower case 'a'. + b"ssh-rsa AAAAB3NzAC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk" + b"FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll" + b"PDA7ZRBnrfiHpSQYQ874AZaAoIjgkv7DBfsE6gcDQLub0PFjWyrYQUJhtOLQEK" + b"vY/G0vt2iRL3juawWmCFdTK3W3XvwAdgGk71i6lHt+deOPNEPN2H58E4odrZ2f" + b"sxn/adpDqfb2sM0kPwQs0aWvrrKGvUaustkivQE4XWiSFnB0oJB/lKK/CKVKuy" + b"///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX" + b"2MzHvnbvAQ== testkey@localhost" + ) + with pytest.raises(ValueError): + load_ssh_public_key(ssh_key, backend) + + def test_load_ssh_public_key_rsa(self, backend): + ssh_key = ( + b"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk" + b"FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll" + b"PDA7ZRBnrfiHpSQYQ874AZaAoIjgkv7DBfsE6gcDQLub0PFjWyrYQUJhtOLQEK" + b"vY/G0vt2iRL3juawWmCFdTK3W3XvwAdgGk71i6lHt+deOPNEPN2H58E4odrZ2f" + b"sxn/adpDqfb2sM0kPwQs0aWvrrKGvUaustkivQE4XWiSFnB0oJB/lKK/CKVKuy" + b"///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX" + b"2MzHvnbv testkey@localhost" + ) + + key = load_ssh_public_key(ssh_key, backend) + + assert key is not None + assert isinstance(key, interfaces.RSAPublicKey) + + numbers = key.public_numbers() + + expected_e = 0x10001 + expected_n = int( + '00C3BBF5D13F59322BA0A0B77EA0B6CF570241628AE24B5BA454D' + '23DCA295652B3523B67752653DFFD69587FAD9578DD6406F23691' + 'EA491C3F8B2D391D0312D9653C303B651067ADF887A5241843CEF' + '8019680A088E092FEC305FB04EA070340BB9BD0F1635B2AD84142' + '61B4E2D010ABD8FC6D2FB768912F78EE6B05A60857532B75B75EF' + 'C007601A4EF58BA947B7E75E38F3443CDD87E7C138A1DAD9D9FB3' + '19FF69DA43A9F6F6B0CD243F042CD1A5AFAEB286BD46AEB2D922B' + 'D01385D6892167074A0907F94A2BF08A54ABB2FFFFC89920861D0' + '46F8706AB88DDADBD9E8204D48B87789081E074024C8996783B31' + '7076A98ABF0A2D8550EAF2097D8CCC7BE76EF', 16) + + expected = RSAPublicNumbers(expected_e, expected_n) + + assert numbers == expected diff --git a/tests/test_utils.py b/tests/test_utils.py index 637c42bc..bc5f2e14 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -18,7 +18,7 @@ from cryptography.exceptions import UnsupportedAlgorithm, _Reasons import cryptography_vectors from .utils import ( - check_backend_support, der_encode_dsa_signature, load_cryptrec_vectors, + check_backend_support, load_cryptrec_vectors, load_fips_dsa_key_pair_vectors, load_fips_dsa_sig_vectors, load_fips_ecdsa_key_pair_vectors, load_fips_ecdsa_signing_vectors, load_hash_vectors, load_kasvs_dh_vectors, load_nist_vectors, @@ -110,26 +110,6 @@ def test_check_backend_support_no_backend(): check_backend_support(item) -def test_der_encode_dsa_signature_values(): - sig = der_encode_dsa_signature(1, 1) - assert sig == b"0\x06\x02\x01\x01\x02\x01\x01" - - sig2 = der_encode_dsa_signature( - 1037234182290683143945502320610861668562885151617, - 559776156650501990899426031439030258256861634312 - ) - assert sig2 == ( - b'0-\x02\x15\x00\xb5\xaf0xg\xfb\x8bT9\x00\x13\xccg\x02\r\xdf\x1f,\x0b' - b'\x81\x02\x14b\r;"\xabP1D\x0c>5\xea\xb6\xf4\x81)\x8f\x9e\x9f\x08' - ) - - sig3 = der_encode_dsa_signature(0, 0) - assert sig3 == b"0\x06\x02\x01\x00\x02\x01\x00" - - sig4 = der_encode_dsa_signature(-1, 0) - assert sig4 == b"0\x06\x02\x01\xFF\x02\x01\x00" - - def test_load_nist_vectors(): vector_data = textwrap.dedent(""" # CAVS 11.1 diff --git a/tests/utils.py b/tests/utils.py index 01ab4e6f..37efc580 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -9,9 +9,6 @@ import collections import re from contextlib import contextmanager -from pyasn1.codec.der import encoder -from pyasn1.type import namedtype, univ - import pytest import six @@ -73,20 +70,6 @@ def raises_unsupported_algorithm(reason): assert exc_info.value._reason is reason -class _DSSSigValue(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('r', univ.Integer()), - namedtype.NamedType('s', univ.Integer()) - ) - - -def der_encode_dsa_signature(r, s): - sig = _DSSSigValue() - sig.setComponentByName('r', r) - sig.setComponentByName('s', s) - return encoder.encode(sig) - - def load_vectors_from_file(filename, loader, mode="r"): with cryptography_vectors.open_vector_file(filename, mode) as vector_file: return loader(vector_file) @@ -7,7 +7,6 @@ deps = coverage iso8601 pretend - pyasn1 pytest ./vectors commands = @@ -77,3 +76,9 @@ application-import-names = cryptography,cryptography_vectors,tests [doc8] extensions = rst + +[pytest] +addopts = -r s +markers = + requires_backend_interface: this test requires a specific backend interface + supported: parametrized test requiring only_if and skip_message diff --git a/vectors/cryptography_vectors/x509/custom/dsa_selfsigned_ca.pem b/vectors/cryptography_vectors/x509/custom/dsa_selfsigned_ca.pem new file mode 100644 index 00000000..4348ce81 --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/dsa_selfsigned_ca.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFWjCCBRqgAwIBAgIJAKNzUuCyFC+GMAkGByqGSM44BAMwZzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgTBVRleGFzMQ8wDQYDVQQHEwZBdXN0aW4xITAfBgNVBAoTGElu +dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAxMLUHlDQSBEU0EgQ0EwHhcN +MTQxMTI3MDUxNDE3WhcNMTQxMjI3MDUxNDE3WjBnMQswCQYDVQQGEwJVUzEOMAwG +A1UECBMFVGV4YXMxDzANBgNVBAcTBkF1c3RpbjEhMB8GA1UEChMYSW50ZXJuZXQg +V2lkZ2l0cyBQdHkgTHRkMRQwEgYDVQQDEwtQeUNBIERTQSBDQTCCAzowggItBgcq +hkjOOAQBMIICIAKCAQEAv63mBI43PNTki2d+h4yOWwjAIQKuBOsstcRqUjo68cc9 +FrJPNKSWR4GuflBQDiF3d1SmcL0Zp0INYzCE5VVuM8osDn1UfqX0agegG/hmmuO9 +7AQtmyrl5uz0nwC6nayZq27/FA0s7fci7mLC+XNoV5cURMJdCjPSAX3DbWgqEFT+ +KpQo3aNVqFHObm1h4D5Bn9TKTnAzE3Q9hsqohZMPYu1b80LYFlYnaB6cwyRLpyqi +IUhACmu+gBVOhV0ELJ3Co0BfHlF76d6lBWL1bak/YIX4RKfnBcHwQ+ZXUcWDuA0p +ED5ZDMsm79qgiT2DPjZGjzkHz8p4ijy3kPA0HIoxvwIVAIIv9dI04HO5Ac9ZQfWO +H1OOcdQNAoIBAEt87XHcNTll7MENRBqaBvwklDoy1mQp3V70TUPmfXidmXcK7DLA +QV3JKXCICHLaRf743R4RWj5IATh7ptdVhh8GL9O26eqOJkEVIzm4KDFbFSjubHt5 +RY0h89uXP2/DA/k5cXTCeZ3SNRKCqi2IQsNXpzSVu6rEkyeGQUxV5g1zFp9XYQNv +uinp7r+wSfijsbfO5vP7+hNiBfEwvuLPW5w43BCV1ABvLnMzXAc1LGQTChqyuJ8T +tI9ijTzDhovuzpu3vq3p+DDqzG+iQUJcCz/MDfQWoMife/NWaNdl7JXNz76cr/Sc +/BVsZox2+mJHZ2ptOslFhEoINQnGobQ2usoDggEFAAKCAQBMCL/l8tdmScgKz31D +H2riEksheryMn2rKd23fqUU7ZlbxPlQ2hM1fZDGjFDd9Kr+gaLcIDLjdwGWvwt6l +WfC1hMl6KyNbm2m0a8beGu1CKm80GDJhi8quIZiro4gJna+wX/C17+yzsK4WmmLh +xyAir1CuaK87AzwY5u7B999GksRWzK+3nMfgjaCleG6YFs7aZR1htLt7gcJ4Pal8 +6mLfZ69ehZkf3BOv8Q/GDgZYY4a5a7eNZXUPVC+GlR4FptgbqtvNNaLlytQRmSOu +aiACCRo9FwF/k8UpcBE83BGZcLkHTKUG6skcPdN2Ml30r2s5Ee8mfSZiOlocXfSm +0T8co4HMMIHJMB0GA1UdDgQWBBSk+4h6E/zeswO7rpod7KcvElpUGzCBmQYDVR0j +BIGRMIGOgBSk+4h6E/zeswO7rpod7KcvElpUG6FrpGkwZzELMAkGA1UEBhMCVVMx +DjAMBgNVBAgTBVRleGFzMQ8wDQYDVQQHEwZBdXN0aW4xITAfBgNVBAoTGEludGVy +bmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAxMLUHlDQSBEU0EgQ0GCCQCjc1Lg +shQvhjAMBgNVHRMEBTADAQH/MAkGByqGSM44BAMDLwAwLAIUJcSoSpNqsxHuAX08 +vZo8ZQuzrkoCFF0wxktDJoa9+SVxa07QWRhDlrzO +-----END CERTIFICATE----- diff --git a/vectors/cryptography_vectors/x509/custom/ec_no_named_curve.pem b/vectors/cryptography_vectors/x509/custom/ec_no_named_curve.pem new file mode 100644 index 00000000..4edeaa1c --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/ec_no_named_curve.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICbTCCAhOgAwIBAgIBADAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztYWUxJOlpC +M0w6NUpINjpFVVZYOldVS0o6S0w2WTpSSENPOlRFU1k6SVNYTToyWVZFOkZOSFU6 +Wkk2UTAeFw0xNDEyMTIwODAyMTdaFw0xNDEyMTMwODAyMTdaMEYxRDBCBgNVBAMT +O1hZTEk6WkIzTDo1Skg2OkVVVlg6V1VLSjpLTDZZOlJIQ086VEVTWTpJU1hNOjJZ +VkU6Rk5IVTpaSTZRMIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIh +AP////8AAAABAAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAA +AAAAAAAAAAAA///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7 +zjw+J9JgSwMVAMSdNgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA +8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R +9QIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABO5cqNMX +U4PWD9x2ffa/B9xvpw3poTOAQYpRHSlGV7JTYuubeZEm2vRRLXA9n1l7+JBffxZC +r+yjS2JHNuq+0kgwCgYIKoZIzj0EAwIDSAAwRQIhAKYoc7Azt/GwTeLFBlhaLpSD +seB3qsN1kdZH4bzylonjAiA9/nVi7fbYydpym5jnW4DpHnenoZcZdWeDVnhE0J4c +WA== +-----END CERTIFICATE----- diff --git a/vectors/cryptography_vectors/x509/custom/invalid_version.pem b/vectors/cryptography_vectors/x509/custom/invalid_version.pem new file mode 100644 index 00000000..84a55626 --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/invalid_version.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBBwITBlqtEggCEIn2HtsUzORK3EHP0zANBgkqhkiG9w0BAQUF +ADBXMQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1c3Rp +bjENMAsGA1UECgwEUHlDQTEYMBYGA1UEAwwPQ3J5cHRvZ3JhcGh5IENBMB4XDTE0 +MTEyNjE0NDQ1N1oXDTM0MTEyMTIwNDQ1N1owVzELMAkGA1UEBhMCVVMxDjAMBgNV +BAgMBVRleGFzMQ8wDQYDVQQHDAZBdXN0aW4xDTALBgNVBAoMBFB5Q0ExGDAWBgNV +BAMMD0NyeXB0b2dyYXBoeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAJZPCfKbFZQ5G5gYdXbxPq7o1DFaYzeWOqBzR4M1iE1gnDTw/ZQXExVVIZga +QU3aiiL1hZ+9NdWvmViDKlj4Qa7+8FxHhuq/Weri/itFhMcEuGs+iTclWc/H1M5J +3OChClzKcugeOPP/ZevZXiKSB4pGd+b6esw40WSmIWBqwKpQOu8DxXX1LCP+xS9j +ZlARDS2VqD/LP6ZbTd5odOX6kMi4dm9mVnfREUL79hMShTPt2BB7muKm2yNWmJuh +npUWTyl0P7r+lgr1y1E+u+3YbThWe7hk2Ra21J1Xpba4v1j5WR0+IfwjbJIJA7up +eeqB3rrZBJmPyKGVX6m8gXiYtR8CAwEAAaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAd +BgNVHQ4EFgQUrc6wKzvf3ST5Tk+Idr37QF9pIjMwHwYDVR0jBBgwFoAUrc6wKzvf +3ST5Tk+Idr37QF9pIjMwDQYJKoZIhvcNAQEFBQADggEBACZusajSqo9wL+Rjn0EA +kM92FglKgZ7K3Bp1O9MPp740ytnueY7lWduiPuEjcUQUeI2nBfQYJRoucPLi/2dD +jJgxK6BoYwvm5VJH3g65G39EYnz3L8IUCYGKJ75nffVYvlqcJkfNO+lxt11hGXMA +w/QOdv4TsfjVVbLMcbhKtrMh5iaB5+QbcoBx21i8opg1qi3pwJ8Tgj6JxsKTjlc0 +xoZWDjPao8/dpvbfMsJwlHazZFAPdknZN8/oo0M5DWBQuxiFNoXllDsHrZNN8TAk +Xvr/2XumAxgJJmxDqSbRBDXnwAzj9Jq3ITl4bJ8Nw9sPpS920Owv0xKtQILbo+RR +tcA= +-----END CERTIFICATE----- diff --git a/vectors/cryptography_vectors/x509/custom/post2000utctime.pem b/vectors/cryptography_vectors/x509/custom/post2000utctime.pem new file mode 100644 index 00000000..ce5c058b --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/post2000utctime.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID8DCCAtigAwIBAgIJAKBstLlV9/TbMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxETAPBgNVBAMTCEhlbGxvIENBMB4XDTE0MTEyNjIxNDEy +MFoXDTE0MTIyNjIxNDEyMFowWDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt +U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDERMA8GA1UE +AxMISGVsbG8gQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwOvcC +BZ4n8eIoS1a7smwDkVO/gfKVtzpJEymQZF7eTS2gqRPELn0401iaANOUDRlPbm2H +fC74EtoionXoPYvnhkZ0i05/I9EOhz/XL1ehPexzL8VqsTixuzCDmbtBLNc5IU73 +FOGXbglgNAXiVWKZoFUiUQrEV0216css9fmej0jBaWqz6i1tLdq31OGzFxiLdqVy +l39uzgpK05bwFQ59ixqZhsDLkFJ+wmylbikUwnDSoZi2MvqKL9pVB509OYZLb7lt +2+Mxyss8uHg6hJTMzNiGo1JQeIR8oByl+APokhRAPopLVJlTnAuG96DapFsgSo4H +nYpbA9t7obo9cBGnAgMBAAGjgbwwgbkwHQYDVR0OBBYEFNjoncd35EcmVvGGRpWp +9mt7BACuMIGJBgNVHSMEgYEwf4AU2Oidx3fkRyZW8YZGlan2a3sEAK6hXKRaMFgx +CzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRl +cm5ldCBXaWRnaXRzIFB0eSBMdGQxETAPBgNVBAMTCEhlbGxvIENBggkAoGy0uVX3 +9NswDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAjg9y/L6+R1Wryvds +jOC64XzeTbFikWOOGxzgSpPNtMRKNIYHCYbFqIDBT9+El+fSibJjDMsh0ko9GqGy +2HSCB/Oh4WzN+Nqop+oaM9SXdPUT7fCScL2OZltjAKEPADZqWQdpBetjzxCoGgyn +im7zEn9ssvb7f5R/ziKjDYAEjCQ7osGlTEJf4SMQ6Kc3Y49JIDVNTM4ly9neol5q +L+DYV5pcjZKbknW+Ihl1R58/dQdbys8JUmUjtf1n92g/PNpCD6ux6eb8JrwGSc9h +uwUdaTL6w3Bmuxb1WQPf54U9xeUF4qEPu6T56ToNO1O3+jSwXXum7vhpv8NLjlFP +1UGfdQ== +-----END CERTIFICATE----- diff --git a/vectors/cryptography_vectors/x509/ecdsa_root.pem b/vectors/cryptography_vectors/x509/ecdsa_root.pem new file mode 100644 index 00000000..bc20c1e1 --- /dev/null +++ b/vectors/cryptography_vectors/x509/ecdsa_root.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- diff --git a/vectors/cryptography_vectors/x509/v1_cert.pem b/vectors/cryptography_vectors/x509/v1_cert.pem new file mode 100644 index 00000000..8a85d149 --- /dev/null +++ b/vectors/cryptography_vectors/x509/v1_cert.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBWzCCAQYCARgwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV +BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MDYxOTIz +MzMxMloXDTk1MDcxNzIzMzMxMlowOjELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM +RDEdMBsGA1UEAxMUU1NMZWF5L3JzYSB0ZXN0IGNlcnQwXDANBgkqhkiG9w0BAQEF +AANLADBIAkEAqtt6qS5GTxVxGZYWa0/4u+IwHf7p2LNZbcPBp9/OfIcYAXBQn8hO +/Re1uwLKXdCjIoaGs4DLdG88rkzfyK5dPQIDAQABMAwGCCqGSIb3DQIFBQADQQAE +Wc7EcF8po2/ZO6kNCwK/ICH6DobgLekA5lSLr5EvuioZniZp5lFzAw4+YzPQ7XKJ +zl9HYIMxATFyqSiD9jsx +-----END CERTIFICATE----- |