<s> from __future__ import absolute_import , division , print_function <EOL> from cryptography import utils <EOL> from cryptography . exceptions import ( <EOL> InvalidSignature , UnsupportedAlgorithm , _Reasons <EOL> ) <EOL> from cryptography . hazmat . backends . openssl . utils import _truncate_digest <EOL> from cryptography . hazmat . primitives import hashes , serialization <EOL> from cryptography . hazmat . primitives . asymmetric import ( <EOL> AsymmetricSignatureContext , AsymmetricVerificationContext , ec <EOL> ) <EOL> def _truncate_digest_for_ecdsa ( ec_key_cdata , digest , backend ) : <EOL> """<STR_LIT>""" <EOL> _lib = backend . _lib <EOL> _ffi = backend . _ffi <EOL> group = _lib . EC_KEY_get0_group ( ec_key_cdata ) <EOL> with backend . _tmp_bn_ctx ( ) as bn_ctx : <EOL> order = _lib . BN_CTX_get ( bn_ctx ) <EOL> backend . openssl_assert ( order != _ffi . NULL ) <EOL> res = _lib . EC_GROUP_get_order ( group , order , bn_ctx ) <EOL> backend . openssl_assert ( res == <NUM_LIT:1> ) <EOL> order_bits = _lib . BN_num_bits ( order ) <EOL> return _truncate_digest ( digest , order_bits ) <EOL> def _ec_key_curve_sn ( backend , ec_key ) : <EOL> group = backend . _lib . EC_KEY_get0_group ( ec_key ) <EOL> backend . openssl_assert ( group != backend . _ffi . NULL ) <EOL> nid = backend . _lib . EC_GROUP_get_curve_name ( group ) <EOL> if nid == backend . _lib . NID_undef : <EOL> raise NotImplementedError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> curve_name = backend . _lib . OBJ_nid2sn ( nid ) <EOL> backend . openssl_assert ( curve_name != backend . _ffi . NULL ) <EOL> sn = backend . _ffi . string ( curve_name ) . decode ( '<STR_LIT:ascii>' ) <EOL> return sn <EOL> def _mark_asn1_named_ec_curve ( backend , ec_cdata ) : <EOL> """<STR_LIT>""" <EOL> backend . _lib . EC_KEY_set_asn1_flag ( <EOL> ec_cdata , backend . _lib . OPENSSL_EC_NAMED_CURVE <EOL> ) <EOL> def _sn_to_elliptic_curve ( backend , sn ) : <EOL> try : <EOL> return ec . _CURVE_TYPES [ sn ] ( ) <EOL> except KeyError : <EOL> raise UnsupportedAlgorithm ( <EOL> "<STR_LIT>" . format ( sn ) , <EOL> _Reasons . UNSUPPORTED_ELLIPTIC_CURVE <EOL> ) <EOL> @ utils . register_interface ( AsymmetricSignatureContext ) <EOL> class _ECDSASignatureContext ( object ) : <EOL> def __init__ ( self , backend , private_key , algorithm ) : <EOL> self . _backend = backend <EOL> self . _private_key = private_key <EOL> self . _digest = hashes . Hash ( algorithm , backend ) <EOL> def update ( self , data ) : <EOL> self . _digest . update ( data ) <EOL> def finalize ( self ) : <EOL> ec_key = self . _private_key . _ec_key <EOL> digest = self . _digest . finalize ( ) <EOL> digest = _truncate_digest_for_ecdsa ( ec_key , digest , self . _backend ) <EOL> max_size = self . _backend . _lib . ECDSA_size ( ec_key ) <EOL> self . _backend . openssl_assert ( max_size > <NUM_LIT:0> ) <EOL> sigbuf = self . _backend . _ffi . new ( "<STR_LIT>" , max_size ) <EOL> siglen_ptr = self . _backend . _ffi . new ( "<STR_LIT>" , <NUM_LIT:1> ) <EOL> res = self . _backend . _lib . ECDSA_sign ( <EOL> <NUM_LIT:0> , <EOL> digest , <EOL> len ( digest ) , <EOL> sigbuf , <EOL> siglen_ptr , <EOL> ec_key <EOL> ) <EOL> self . _backend . openssl_assert ( res == <NUM_LIT:1> ) <EOL> return self . _backend . _ffi . buffer ( sigbuf ) [ : siglen_ptr [ <NUM_LIT:0> ] ] <EOL> @ utils . register_interface ( AsymmetricVerificationContext ) <EOL> class _ECDSAVerificationContext ( object ) : <EOL> def __init__ ( self , backend , public_key , signature , algorithm ) : <EOL> self . _backend = backend <EOL> self . _public_key = public_key <EOL> self . _signature = signature <EOL> self . _digest = hashes . Hash ( algorithm , backend ) <EOL> def update ( self , data ) : <EOL> self . _digest . update ( data ) <EOL> def verify ( self ) : <EOL> ec_key = self . _public_key . _ec_key <EOL> digest = self . _digest . finalize ( ) <EOL> digest = _truncate_digest_for_ecdsa ( ec_key , digest , self . _backend ) <EOL> res = self . _backend . _lib . ECDSA_verify ( <EOL> <NUM_LIT:0> , <EOL> digest , <EOL> len ( digest ) , <EOL> self . _signature , <EOL> len ( self . _signature ) , <EOL> ec_key <EOL> ) <EOL> if res != <NUM_LIT:1> : <EOL> self . _backend . _consume_errors ( ) <EOL> raise InvalidSignature <EOL> return True <EOL> @ utils . register_interface ( ec . EllipticCurvePrivateKeyWithSerialization ) <EOL> class _EllipticCurvePrivateKey ( object ) : <EOL> def __init__ ( self , backend , ec_key_cdata , evp_pkey ) : <EOL> self . _backend = backend <EOL> _mark_asn1_named_ec_curve ( backend , ec_key_cdata ) <EOL> self . _ec_key = ec_key_cdata <EOL> self . _evp_pkey = evp_pkey <EOL> sn = _ec_key_curve_sn ( backend , ec_key_cdata ) <EOL> self . _curve = _sn_to_elliptic_curve ( backend , sn ) <EOL> curve = utils . read_only_property ( "<STR_LIT>" ) <EOL> def signer ( self , signature_algorithm ) : <EOL> if isinstance ( signature_algorithm , ec . ECDSA ) : <EOL> return _ECDSASignatureContext ( <EOL> self . _backend , self , signature_algorithm . algorithm <EOL> ) <EOL> else : <EOL> raise UnsupportedAlgorithm ( <EOL> "<STR_LIT>" , <EOL> _Reasons . UNSUPPORTED_PUBLIC_KEY_ALGORITHM ) <EOL> def exchange ( self , algorithm , peer_public_key ) : <EOL> if not ( <EOL> self . _backend . elliptic_curve_exchange_algorithm_supported ( <EOL> algorithm , self . curve <EOL> ) <EOL> ) : <EOL> raise UnsupportedAlgorithm ( <EOL> "<STR_LIT>" , <EOL> _Reasons . UNSUPPORTED_EXCHANGE_ALGORITHM <EOL> ) <EOL> if peer_public_key . curve . name != self . curve . name : <EOL> raise ValueError ( <EOL> "<STR_LIT>" <EOL> ) <EOL> group = self . _backend . _lib . EC_KEY_get0_group ( self . _ec_key ) <EOL> z_len = ( self . _backend . _lib . EC_GROUP_get_degree ( group ) + <NUM_LIT:7> ) // <NUM_LIT:8> <EOL> self . _backend . openssl_assert ( z_len > <NUM_LIT:0> ) <EOL> z_buf = self . _backend . _ffi . new ( "<STR_LIT>" , z_len ) <EOL> peer_key = self . _backend . _lib . EC_KEY_get0_public_key ( <EOL> peer_public_key . _ec_key <EOL> ) <EOL> r = self . _backend . _lib . ECDH_compute_key ( <EOL> z_buf , z_len , peer_key , self . _ec_key , self . _backend . _ffi . NULL <EOL> ) <EOL> self . _backend . openssl_assert ( r > <NUM_LIT:0> ) <EOL> return self . _backend . _ffi . buffer ( z_buf ) [ : z_len ] <EOL> def public_key ( self ) : <EOL> group = self . _backend . _lib . EC_KEY_get0_group ( self . _ec_key ) <EOL> self . _backend . openssl_assert ( group != self . _backend . _ffi . NULL ) <EOL> curve_nid = self . _backend . _lib . EC_GROUP_get_curve_name ( group ) <EOL> public_ec_key = self . _backend . _lib . EC_KEY_new_by_curve_name ( curve_nid ) <EOL> self . _backend . openssl_assert ( public_ec_key != self . _backend . _ffi . NULL ) <EOL> public_ec_key = self . _backend . _ffi . gc ( <EOL> public_ec_key , self . _backend . _lib . EC_KEY_free <EOL> ) <EOL> point = self . _backend . _lib . EC_KEY_get0_public_key ( self . _ec_key ) <EOL> self . _backend . openssl_assert ( point != self . _backend . _ffi . NULL ) <EOL> res = self . _backend . _lib . EC_KEY_set_public_key ( public_ec_key , point ) <EOL> self . _backend . openssl_assert ( res == <NUM_LIT:1> ) <EOL> evp_pkey = self . _backend . _ec_cdata_to_evp_pkey ( public_ec_key ) <EOL> return _EllipticCurvePublicKey ( self . _backend , public_ec_key , evp_pkey ) <EOL> def private_numbers ( self ) : <EOL> bn = self . _backend . _lib . EC_KEY_get0_private_key ( self . _ec_key ) <EOL> private_value = self . _backend . _bn_to_int ( bn ) <EOL> return ec . EllipticCurvePrivateNumbers ( <EOL> private_value = private_value , <EOL> public_numbers = self . public_key ( ) . public_numbers ( ) <EOL> ) <EOL> def private_bytes ( self , encoding , format , encryption_algorithm ) : <EOL> return self . _backend . _private_key_bytes ( <EOL> encoding , <EOL> format , <EOL> encryption_algorithm , <EOL> self . _evp_pkey , <EOL> self . _ec_key <EOL> ) <EOL> @ utils . register_interface ( ec . EllipticCurvePublicKeyWithSerialization ) <EOL> class _EllipticCurvePublicKey ( object ) : <EOL> def __init__ ( self , backend , ec_key_cdata , evp_pkey ) : <EOL> self . _backend = backend <EOL> _mark_asn1_named_ec_curve ( backend , ec_key_cdata ) <EOL> self . _ec_key = ec_key_cdata <EOL> self . _evp_pkey = evp_pkey <EOL> sn = _ec_key_curve_sn ( backend , ec_key_cdata ) <EOL> self . _curve = _sn_to_elliptic_curve ( backend , sn ) <EOL> curve = utils . read_only_property ( "<STR_LIT>" ) <EOL> def verifier ( self , signature , signature_algorithm ) : <EOL> if not isinstance ( signature , bytes ) : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> if isinstance ( signature_algorithm , ec . ECDSA ) : <EOL> return _ECDSAVerificationContext ( <EOL> self . _backend , self , signature , signature_algorithm . algorithm <EOL> ) <EOL> else : <EOL> raise UnsupportedAlgorithm ( <EOL> "<STR_LIT>" , <EOL> _Reasons . UNSUPPORTED_PUBLIC_KEY_ALGORITHM ) <EOL> def public_numbers ( self ) : <EOL> set_func , get_func , group = ( <EOL> self . _backend . _ec_key_determine_group_get_set_funcs ( self . _ec_key ) <EOL> ) <EOL> point = self . _backend . _lib . EC_KEY_get0_public_key ( self . _ec_key ) <EOL> self . _backend . openssl_assert ( point != self . _backend . _ffi . NULL ) <EOL> with self . _backend . _tmp_bn_ctx ( ) as bn_ctx : <EOL> bn_x = self . _backend . _lib . BN_CTX_get ( bn_ctx ) <EOL> bn_y = self . _backend . _lib . BN_CTX_get ( bn_ctx ) <EOL> res = get_func ( group , point , bn_x , bn_y , bn_ctx ) <EOL> self . _backend . openssl_assert ( res == <NUM_LIT:1> ) <EOL> x = self . _backend . _bn_to_int ( bn_x ) <EOL> y = self . _backend . _bn_to_int ( bn_y ) <EOL> return ec . EllipticCurvePublicNumbers ( <EOL> x = x , <EOL> y = y , <EOL> curve = self . _curve <EOL> ) <EOL> def public_bytes ( self , encoding , format ) : <EOL> if format is serialization . PublicFormat . PKCS1 : <EOL> raise ValueError ( <EOL> "<STR_LIT>" <EOL> ) <EOL> return self . _backend . _public_key_bytes ( <EOL> encoding , <EOL> format , <EOL> self . _evp_pkey , <EOL> None <EOL> ) </s>
