U +Mb>@sddlmZddlZddlZddlZddlmZddlmZm Z m Z m Z m Z ddl mZmZddlmZddlmZmZmZmZddlmZmZmZdd lmZmZmZmZm Z m!Z!dd l"m#Z#dd l$m%Z%ed d Z&eddZ'iZ(ddddddga)ddZ*e*[*ddddddga+ddZ,e,[,d d!d"d#d$d%ga-d&d'Z.e.[.d(d)d*d+d,d-ga/d.d/Z0e0[0d0d1d2d3d4d5ga1d6d7Z2e2[2Gd8d9d9e3Z4Gd:d;d;e5Z6e6e(dj7e(dj8dZ9e(dj:e9d<Z;e(t)e;[9[;b)e6e(dj7e(dj8dZ?e(dj:e?d<Z@e(t+e@[?[@b+e6e(d j7e(d j8d ZAe(d j:eAd<ZBe(t-eB[A[Bb-e6e(d(j7e(d(j8d(ZCe(d(j:eCd<ZDe(t/eD[C[Db/e6e(d0j7e(d0j8d0ZEe(d0j:eEd<ZFe(t1eF[E[Fb1Gd=d>d>e5ZGd?d@ZHdAdBZId\dCdDZJdEdFZKd]dGdHZLdIdJZMdKdLZNdMdNZOdOdPZPdQdRZQd^dSdTZReSdUkrddlTZTdVZUe(d jVWZXdWZYeTTZZe[eYD]Z\eXeUZ]qe^dXeTTeZeYdYdZeTTZZe[eYD]Z\e]eUZ]qe^d[eTTeZeYdYdZdS)_)print_functionN) namedtuple)bordtobytestostrbchr is_string) bytes_to_long long_to_bytes)Integer) DerObjectIdDerOctetString DerSequence DerBitString)_expand_subject_public_key_info_create_subject_public_key_info _extract_subject_public_key_info)load_pycryptodome_raw_lib VoidPointer SmartPointerc_size_t c_uint8_ptr c_ulonglong)get_random_bytes) getrandbitszCrypto.PublicKey._ec_wsav typedef void EcContext; typedef void EcPoint; int ec_ws_new_context(EcContext **pec_ctx, const uint8_t *modulus, const uint8_t *b, const uint8_t *order, size_t len, uint64_t seed); void ec_free_context(EcContext *ec_ctx); int ec_ws_new_point(EcPoint **pecp, const uint8_t *x, const uint8_t *y, size_t len, const EcContext *ec_ctx); void ec_free_point(EcPoint *ecp); int ec_ws_get_xy(uint8_t *x, uint8_t *y, size_t len, const EcPoint *ecp); int ec_ws_double(EcPoint *p); int ec_ws_add(EcPoint *ecpa, EcPoint *ecpb); int ec_ws_scalar(EcPoint *ecp, const uint8_t *k, size_t len, uint64_t seed); int ec_ws_clone(EcPoint **pecp2, const EcPoint *ecp); int ec_ws_copy(EcPoint *ecp1, const EcPoint *ecp2); int ec_ws_cmp(const EcPoint *ecp1, const EcPoint *ecp2); int ec_ws_neg(EcPoint *p); int ec_ws_normalize(EcPoint *ecp); int ec_ws_is_pai(EcPoint *ecp); _Curvez7p b order Gx Gy G modulus_bits oid context desc opensshp192 NIST P-192zP-192Z prime192v1Z secp192r1Znistp192c Csd}d}d}d}d}t|d}t|d}t|d}t}t|t|t|t|tt|tt d} | r|t d| t | tj } tt|t|t|t|t|dd d | d d } ttt| dS) Nl l 9{uDjSg9g(Bl 1(i&^#a;l +'1t:_|v!a:@ml H<^W]dZ{cxW\Iq@z#Error %d initializing P-192 contextz1.2.840.10045.3.1.1rzecdsa-sha2-nistp192)r r_ec_libec_ws_new_context address_ofrrlenrr ImportErrorrgetec_free_contextrr _curvesupdatedictfromkeys p192_names) pborderGxGyZ p192_modulusZp192_bZ p192_orderZec_p192_contextresultcontextrr4;/tmp/pip-target-t616c12r/lib/python/Crypto/PublicKey/ECC.py init_p192cs@        r6p224 NIST P-224zP-224Z prime224v1Z secp224r1Znistp224c Csd}d}d}d}d}t|d}t|d}t|d}t}t|t|t|t|tt|tt d} | r|t d| t | tj } tt|t|t|t|t|dd d | d d } ttt| dS) Nl?lF eY8 w-X"PVd/%PP!-l=*8%(?l!"X!#BXtJ9!'|%VA-l4~ f&Dv@h!fE0m9_ qlM/rz#Error %d initializing P-224 contextz 1.3.132.0.33r8zecdsa-sha2-nistp224)r rr!r"r#rrr$rrr%rr&r'rr r(r)r*r+ p224_names) r-r.r/r0r1Z p224_modulusZp224_bZ p224_orderZec_p224_contextr2r3r7r4r4r5 init_p224s@        r<p256 NIST P-256zP-256Z prime256v1Z secp256r1Znistp256c Csd}d}d}d}d}t|d}t|d}t|d}t}t|t|t|t|tt|tt d} | r|t d| t | tj } tt|t|t|t|t|dd d | d d } ttt| dS) Nl?@lK`Opq^cv 3,e< 1U]>{|R*ZlQ%x +Ohbi+}s@lB11e %:f=K`wrH7gHK8hklQ~o]l+fUg+<)Z?8O?q!O rz#Error %d initializing P-256 contextz1.2.840.10045.3.1.7r>zecdsa-sha2-nistp256)r rr!r"r#rrr$rrr%rr&r'rr r(r)r*r+ p256_names) r-r.r/r0r1Z p256_modulusZp256_bZ p256_orderZec_p256_contextr2r3r=r4r4r5 init_p256s@        rBp384 NIST P-384zP-384Z prime384v1Z secp384r1Znistp384c Csd}d}d}d}d}t|d}t|d}t|d}t}t|t|t|t|tt|tt d} | r|t d| t | tj } tt|t|t|t|t|dd d | d d } ttt| dS) Nl~l*'#.TEbc+Z'@=D 1 "(?7N2Z_+|S/1fls)e`gwl X_[nlv|l dxRjoyU8T( :ss"nZL8k&"_Ul_!uR/sX0 @qaNQNB&JxS8KJEY K%l0rz#Error %d initializing P-384 contextiz 1.3.132.0.34rDzecdsa-sha2-nistp384)r rr!r"r#rrr$rrr%rr&r'rr r(r)r*r+ p384_names) r-r.r/r0r1Z p384_modulusZp384_bZ p384_orderZec_p384_contextr2r3rCr4r4r5 init_p384s@        rGp521 NIST P-521zP-521Z prime521v1Z secp521r1Znistp521c Csd}d}d}d}d}t|d}t|d}t|d}t}t|t|t|t|tt|tt d} | r|t d| t | tj } tt|t|t|t|t|dd d | d d } ttt| dS) Nl#l#?VQ(zO%b95~cte1oR{V;LH w>l-rZE]"Sr&Ga9}*Fl# dp"z\}[z3"nZ;PK# `7roCQl#f=xK)H-apY$3^Q n%k{;/K!u{4-{?$Od8V1l3s: l#Pf?QE$XN!85aZU WL9YLhz f$Du13otc!% pMxjRr`Brz#Error %d initializing P-521 contexti z 1.3.132.0.35rIzecdsa-sha2-nistp521)r rr!r"r#rrr$rrr%rr&r'rr r(r)r*r+ p521_names) r-r.r/r0r1Z p521_modulusZp521_bZ p521_orderZec_p521_contextr2r3rHr4r4r5 init_p521s@        rLc@s eZdZdS)UnsupportedEccFeatureN)__name__ __module__ __qualname__r4r4r4r5rMEsrMc@seZdZdZd(ddZddZddZd d Zd d Zd dZ ddZ e ddZ e ddZ e ddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'S))EccPointa=A class to abstract a point over an Elliptic Curve. The class support special methods for: * Adding two points: ``R = S + T`` * In-place addition: ``S += T`` * Negating a point: ``R = -T`` * Comparing two points: ``if S == T: ...`` * Multiplying a point by a scalar: ``R = S*k`` * In-place multiplication by a scalar: ``T *= k`` :ivar x: The affine X-coordinate of the ECC point :vartype x: integer :ivar y: The affine Y-coordinate of the ECC point :vartype y: integer :ivar xy: The tuple with X- and Y- coordinates r=c Cszt||_Wn$tk r2tdt|YnX||_|}|jj}t||}t||}t ||ksvt ||kr~tdt |_ t |j t|t|t||}|r|dkrtdtd|t|j t j|_ dS)NzUnknown curve name %szIncorrect coordinate lengthz)The EC point does not belong to the curvez(Error %d while instantiating an EC point)r(_curveKeyError ValueErrorstr _curve_name size_in_bytesr3r r$r_pointr!Zec_ws_new_pointr#rrr&r ec_free_point) selfxycurve modulus_bytesr3xbybr2r4r4r5__init__^s2     zEccPoint.__init__cCsHt|_t|j|j}|r0td|t|jtj|_|S)Nz"Error %d while cloning an EC point) rrYr!Z ec_ws_cloner#r&rUrrZr[pointr2r4r4r5set~s   z EccPoint.setcCsdt|j|jkSNr)r!Z ec_ws_cmprYr&)r[rdr4r4r5__eq__szEccPoint.__eq__cCs,|}t|j}|r(td||S)Nz$Error %d while inverting an EC point)copyr!Z ec_ws_negrYr&rU)r[npr2r4r4r5__neg__s  zEccPoint.__neg__cCs|j\}}t|||j}|S)zReturn a copy of this point.)xyrQrW)r[r\r]rir4r4r5rhs z EccPoint.copycCs |jdkS)z*``True`` if this is the point-at-infinity.)rrrkr[r4r4r5is_point_at_infinityszEccPoint.is_point_at_infinitycCstdd|jS)zI)structpackr$).0r\r4r4r5 sz*EccKey._export_openssh.. )rrUrSopensshrrXr]rrr\rsplitrjoinrbinascii b2a_base64) r[rrr_rrmiddlecompsblobr4r4r5_export_opensshs$    zEccKey._export_opensshcKsJ|}|d}|dkr&td||dd}|r|dd}t|rbt|}|sbtd|d d }|d kr|r|r|j|f|S|Sq|j|f|SnF|d kr|r|std |r|j fd|i|S| Sn td|nX|rtd||d kr| |S|d kr(| |S|dkr<| |S||SdS)a Export this ECC key. Args: format (string): The format to use for encoding the key: - ``'DER'``. The key will be encoded in ASN.1 DER format (binary). For a public key, the ASN.1 ``subjectPublicKeyInfo`` structure defined in `RFC5480`_ will be used. For a private key, the ASN.1 ``ECPrivateKey`` structure defined in `RFC5915`_ is used instead (possibly within a PKCS#8 envelope, see the ``use_pkcs8`` flag below). - ``'PEM'``. The key will be encoded in a PEM_ envelope (ASCII). - ``'OpenSSH'``. The key will be encoded in the OpenSSH_ format (ASCII, public keys only). - ``'SEC1'``. The public key (i.e., the EC point) will be encoded into ``bytes`` according to Section 2.3.3 of `SEC1`_ (which is a subset of the older X9.62 ITU standard). passphrase (byte string or string): The passphrase to use for protecting the private key. use_pkcs8 (boolean): Only relevant for private keys. If ``True`` (default and recommended), the `PKCS#8`_ representation will be used. If ``False``, the much weaker `PEM encryption`_ mechanism will be used. protection (string): When a private key is exported with password-protection and PKCS#8 (both ``DER`` and ``PEM`` formats), this parameter MUST be present and be a valid algorithm supported by :mod:`Crypto.IO.PKCS8`. It is recommended to use ``PBKDF2WithHMAC-SHA1AndAES128-CBC``. compress (boolean): If ``True``, the method returns a more compact representation of the public key, with the X-coordinate only. If ``False`` (default), the method returns the full public key. .. warning:: If you don't provide a passphrase, the private key will be exported in the clear! .. note:: When exporting a private key with password-protection and `PKCS#8`_ (both ``DER`` and ``PEM`` formats), any extra parameters to ``export_key()`` will be passed to :mod:`Crypto.IO.PKCS8`. .. _PEM: http://www.ietf.org/rfc/rfc1421.txt .. _`PEM encryption`: http://www.ietf.org/rfc/rfc1423.txt .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt .. _OpenSSH: http://www.openssh.com/txt/rfc5656.txt .. _RFC5480: https://tools.ietf.org/html/rfc5480 .. _RFC5915: http://www.ietf.org/rfc/rfc5915.txt .. _SEC1: https://www.secg.org/sec1-v2.pdf Returns: A multi-line string (for PEM and OpenSSH) or ``bytes`` (for DER and SEC1) with the encoded key. format)rDERZOpenSSHSEC1zUnknown format '%s'rFrNzEmpty passphrase use_pkcs8Trrz8Private keys can only be encrpyted with DER using PKCS#8z2Private keys cannot be exported in the '%s' formatzUnexpected parameters: '%s'r)rhrrUrrrrrrrrrrrr)r[rargsZ ext_formatrrrr4r4r5 export_keysHA              zEccKey.export_keyN)T)rNrOrPrrbrgrrrrrrrrrrrrrrrrrrr4r4r4r5rs,"     rcKsP|d}t|}|dt}|r2tdt|tjd|j|d}t||dS)a6Generate a new private key on the given curve. Args: curve (string): Mandatory. It must be a curve name defined in :numref:`curve_names`. randfunc (callable): Optional. The RNG to read randomness from. If ``None``, :func:`Crypto.Random.get_random_bytes` is used. r^randfuncrrp)rrr)r^r) rr(rrrVr rr/r)rrr^rrr4r4r5generategs  rcKs|d}t|}|dd}|dd}d|kr8tdd||fkrTt||||d<|dd}|dk rd|kr|j|}|j||fkrtdtf|S) a(Build a new ECC key (private or public) starting from some base components. Args: curve (string): Mandatory. It must be a curve name defined in :numref:`curve_names`. d (integer): Only for a private key. It must be in the range ``[1..order-1]``. point_x (integer): Mandatory for a public key. X coordinate (affine) of the ECC point. point_y (integer): Mandatory for a public key. Y coordinate (affine) of the ECC point. Returns: :class:`EccKey` : a new ECC key object r^point_xNpoint_yrdzUnknown keyword: pointrz(Private and public ECC keys do not match) r(rrrQr&rrkrUr)rrr^rrrZpub_keyr4r4r5 constructs     rc Cs\tD]&\}}|r"|j|kr"qN||krqNq|rBtd|n td||j}t|d}|dkrt|dd|krtdt |d|d}t ||dd}n|d krFt|d|krtdt |dd}|d |d |j  |j}|dkr&| r&|j|}|d krN|rN|j|}ntd t|||d S) aConvert an encoded EC point into an EccKey object ec_point: byte string with the EC point (SEC1-encoded) curve_oid: string with the name the curve curve_name: string with the OID of the curve Either curve_id or curve_name must be specified Unsupported ECC curve (OID: %s)zUnsupported ECC curve (%s)rrprzIncorrect EC point lengthN)rrzIncorrect EC point encoding)r^rr)r(itemsrrMr-rXrr$rUr from_bytesr.sqrtrZis_evenr) ec_point curve_oidrrWr^r_Z point_typer\r]r4r4r5_import_public_ders4      rc GsZt|\}}}d}d}d}||||fkr4td||s@tdt|j}t||dS)z4Convert a subjectPublicKeyInfo into an EccKey objectr 1.3.132.1.12 1.3.132.1.13!Unsupported ECC purpose (OID: %s)zMissing ECC parametersr)rrMrUr decodevaluer) encodedrrrparamsrecdh_oid ecmqv_oidrr4r4r5_import_subjectPublicKeyInfos   rcCs@tj|dd}|ddkr$tdz6tdd|dj}|dk rT||krTtd|}Wntk rnYnX|dkrtd tD]\}}|j|krqqtd |t |dj }|j }t ||krtd t|} t |d kr(tdd|d j} t| |d} | jj} | jj} nd} } t|| | | dS)N)rr)Z nr_elementsrrpz!Incorrect ECC private key versionrrzCurve mismatchzNo curve foundrzPrivate key is too smallrrr)r^rrr)rrrUr rr(rrrMr payloadr-rXr$r rrrrr\r]r)rrrr parametersrr^Z scalar_bytesr_rZpublic_key_encrrrr4r4r5_import_private_der s8         rc Cs^ddlm}|||\}}}d}d}d}||||fkrDtd|t|j} t||| S)Nrrrrrr)rrunwraprMr rrr) rrrZalgo_oidrrrrrrr4r4r5 _import_pkcs8>s  rcGst|}t|Sr)rr)rrZsp_infor4r4r5_import_x509_certXsrc Cs@z t||WStk r2}z|W5d}~XYntttfk rJYnXz t||WStk r~}z|W5d}~XYntttfk rYnXz t||WStk r}z|W5d}~XYntttfk rYnXz t||WStk r}z|W5d}~XYntttfk r2YnXtddS)NzNot an ECC DER key)rrMrUr IndexErrorrrr)rrerrr4r4r5 _import_der^s2    rcCst|dd}g}t|dkrdtd|ddd}||dd||d|d}qtD],\}}t |j dd}|d|krlqqlt dt |d|j d S) N rprrrrrzUnsupported ECC curver)r a2b_base64rr$runpackappendr(rrrrUrr)rZ keystringZkeypartsZlkrr^rr4r4r5_import_openssh_publics  rcCsddlm}m}m}m}|||\}}||\}}|tkrFtd|t|} | jdd} ||\} }t| ddkrt dt | d | dkrt d t | dd| } t | d| d} t | | |d }||\}}t |}||\}}||t|||d S) Nrp)import_openssh_private_generic read_bytes read_string check_paddingzUnsupported ECC curve %srrrsrrz/Only uncompressed OpenSSH EC keys are supportedrzIncorrect public key length)r^)r^rrd)Z_opensshrrrrr(rMrurrUr$r rrQr)datapasswordrrrrZssh_nameZ decryptednamer^r_rrrrdrr_paddedr4r4r5_import_openssh_private_eccs(      r c Csddlm}t|}|dk r$t|}|drVt|}|||\}}}t||}|S|drt|}d} d} tj| d| d |tj d }|||\} }}|rd}zt | |}Wn@t k r} z| W5d} ~ XYnt k rt d YnX|S|d rt |St|dkr8t|dd kr8t ||St|dkrvt|ddkrv|dkrjt dt||dSt ddS)aImport an ECC key (public or private). Args: encoded (bytes or multi-line string): The ECC key to import. An ECC **public** key can be: - An X.509 certificate, binary (DER) or ASCII (PEM) - An X.509 ``subjectPublicKeyInfo``, binary (DER) or ASCII (PEM) - A SEC1_ (or X9.62) byte string. You must also provide the ``curve_name``. - An OpenSSH line (e.g. the content of ``~/.ssh/id_ecdsa``, ASCII) An ECC **private** key can be: - In binary format (DER, see section 3 of `RFC5915`_ or `PKCS#8`_) - In ASCII format (PEM or `OpenSSH 6.5+`_) Private keys can be in the clear or password-protected. For details about the PEM encoding, see `RFC1421`_/`RFC1423`_. passphrase (byte string): The passphrase to use for decrypting a private key. Encryption may be applied protected at the PEM level or at the PKCS#8 level. This parameter is ignored if the key in input is not encrypted. curve_name (string): For a SEC1 byte string only. This is the name of the ECC curve, as defined in :numref:`curve_names`. Returns: :class:`EccKey` : a new ECC key object Raises: ValueError: when the given key cannot be parsed (possibly because the pass phrase is wrong). .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt .. _RFC5915: http://www.ietf.org/rfc/rfc5915.txt .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt .. _`OpenSSH 6.5+`: https://flak.tedunangst.com/post/new-openssh-key-format-and-bcrypt-pbkdf .. _SEC1: https://www.secg.org/sec1-v2.pdf rrNs-----BEGIN OPENSSH PRIVATE KEYs-----z-----BEGIN EC PARAMETERS-----z-----END EC PARAMETERS-----z.*?r)flagsz(Invalid DER encoding inside the PEM files ecdsa-sha2-rEszNo curve name was provided)rzECC key format is not supported)rrr startswithrrr resubDOTALLrrMrUrr$rr) rrrrZ text_encodedZopenssh_encodedmarkerZenc_flagr2Zecparams_startZ ecparams_endZ der_encodedZuefr4r4r5 import_keysH0          r__main__l_,)N$c hKf-5lks       "  & & & & &.Y, 8' 2!! e