3 ,[A\ @s$dZddlmZmZddlZddlZddlZddlZddlm Z m Z m Z m Z m Z ddlmZy ddlZWnek rddljZYnXejeZddZd(d d Zd gdd d fddZddZddZddZdaddZddZddZ ddZ!ddZ"d)d d!Z#d"d#Z$d$d%Z%d*d&d'Z&dS)+a oauthlib.oauth1.rfc5849.signature ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This module represents a direct implementation of `section 3.4`_ of the spec. Terminology: * Client: software interfacing with an OAuth API * Server: the API provider * Resource Owner: the user who is granting authorization to the client Steps for signing a request: 1. Collect parameters from the uri query, auth header, & body 2. Normalize those parameters 3. Normalize the uri 4. Pass the normalized uri, normalized parameters, and http method to construct the base string 5. Pass the base string and any keys needed to a signing function .. _`section 3.4`: https://tools.ietf.org/html/rfc5849#section-3.4 )absolute_importunicode_literalsN) bytes_typeextract_paramssafe_string_equals unicode_type urldecode)utilscCs>tj|j}|d7}|tj|7}|d7}|tj|7}|S)aY**String Construction** Per `section 3.4.1.1`_ of the spec. For example, the HTTP request:: POST /request?b5=%3D%253D&a3=a&c%40=&a2=r%20b HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded Authorization: OAuth realm="Example", oauth_consumer_key="9djdj82h48djs9d2", oauth_token="kkk9d7dh3k39sjv7", oauth_signature_method="HMAC-SHA1", oauth_timestamp="137131201", oauth_nonce="7d8f3e4a", oauth_signature="bYT5CMsGcbgUdFHObYMEfcx6bsw%3D" c2&a3=2+q is represented by the following signature base string (line breaks are for display purposes only):: POST&http%3A%2F%2Fexample.com%2Frequest&a2%3Dr%2520b%26a3%3D2%2520q %26a3%3Da%26b5%3D%253D%25253D%26c%2540%3D%26c2%3D%26oauth_consumer_ key%3D9djdj82h48djs9d2%26oauth_nonce%3D7d8f3e4a%26oauth_signature_m ethod%3DHMAC-SHA1%26oauth_timestamp%3D137131201%26oauth_token%3Dkkk 9d7dh3k39sjv7 .. _`section 3.4.1.1`: https://tools.ietf.org/html/rfc5849#section-3.4.1.1 &)r escapeupper) http_methodZbase_string_uriZ%normalized_encoded_request_parameters base_stringr/usr/lib/python3.6/signature.pyconstruct_base_string+s (rc Cst|tstdtj|\}}}}}}| s4| rsz%collect_parameters..Z authorizationNcs g|]}s|ddkr|qS)rZrealmr)r'i) with_realmrr sz&collect_parameters..Zoauth_cSs |ddkS)NrZoauth_signaturer)r+rrr8sz$collect_parameters..) extendrdictitemsgetr Zparse_authorization_headerr startswithZunescapeappendlistfilter) Z uri_queryZbodyZheadersZexclude_oauth_signaturer,r%Z headers_lowerZauthorization_headerZ bodyparamsZunescaped_paramsr(r)r)r,rcollect_parameterss*;       r7cCs.dd|D}|jdd|D}dj|S)a **Parameters Normalization** Per `section 3.4.1.3.2`_ of the spec. For example, the list of parameters from the previous section would be normalized as follows: Encoded:: +------------------------+------------------+ | Name | Value | +------------------------+------------------+ | b5 | %3D%253D | | a3 | a | | c%40 | | | a2 | r%20b | | oauth_consumer_key | 9djdj82h48djs9d2 | | oauth_token | kkk9d7dh3k39sjv7 | | oauth_signature_method | HMAC-SHA1 | | oauth_timestamp | 137131201 | | oauth_nonce | 7d8f3e4a | | c2 | | | a3 | 2%20q | +------------------------+------------------+ Sorted:: +------------------------+------------------+ | Name | Value | +------------------------+------------------+ | a2 | r%20b | | a3 | 2%20q | | a3 | a | | b5 | %3D%253D | | c%40 | | | c2 | | | oauth_consumer_key | 9djdj82h48djs9d2 | | oauth_nonce | 7d8f3e4a | | oauth_signature_method | HMAC-SHA1 | | oauth_timestamp | 137131201 | | oauth_token | kkk9d7dh3k39sjv7 | +------------------------+------------------+ Concatenated Pairs:: +-------------------------------------+ | Name=Value | +-------------------------------------+ | a2=r%20b | | a3=2%20q | | a3=a | | b5=%3D%253D | | c%40= | | c2= | | oauth_consumer_key=9djdj82h48djs9d2 | | oauth_nonce=7d8f3e4a | | oauth_signature_method=HMAC-SHA1 | | oauth_timestamp=137131201 | | oauth_token=kkk9d7dh3k39sjv7 | +-------------------------------------+ and concatenated together into a single string (line breaks are for display purposes only):: a2=r%20b&a3=2%20q&a3=a&b5=%3D%253D&c%40=&c2=&oauth_consumer_key=9dj dj82h48djs9d2&oauth_nonce=7d8f3e4a&oauth_signature_method=HMAC-SHA1 &oauth_timestamp=137131201&oauth_token=kkk9d7dh3k39sjv7 .. _`section 3.4.1.3.2`: https://tools.ietf.org/html/rfc5849#section-3.4.1.3.2 cSs$g|]\}}tj|tj|fqSr)r r )r'r(r)rrrr-sz(normalize_parameters..cSsg|]\}}dj||qS)z{0}={1})format)r'r(r)rrrr-sr )sortjoin)r%Z key_valuesZparameter_partsrrrnormalize_parameters>sPr;cCst||j|jS)N)sign_hmac_sha1 client_secretresource_owner_secret)rclientrrrsign_hmac_sha1_with_clientsr@cCsl|}tj|pd}|d7}|tj|p&d7}|jd}|jd}tj||tj}tj|j ddj dS)aP**HMAC-SHA1** The "HMAC-SHA1" signature method uses the HMAC-SHA1 signature algorithm as defined in `RFC2104`_:: digest = HMAC-SHA1 (key, text) Per `section 3.4.2`_ of the spec. .. _`RFC2104`: https://tools.ietf.org/html/rfc2104 .. _`section 3.4.2`: https://tools.ietf.org/html/rfc5849#section-3.4.2 rr zutf-8Nr ) r r encodehmacnewhashlibZsha1binascii b2a_base64Zdigestdecode)rr=r>textkeyZkey_utf8Z text_utf8 signaturerrrr<s  r<cCs$tdkr ddlj}|j|jjatS)Nr)_jwtrs1Zjwt.algorithmsZ algorithmsZ RSAAlgorithmZhashesZSHA1)Zjwtalgorrr_jwt_rs1_signing_algorithms rMcCsHt|tr|jd}t}t||}|j||}tj|ddjdS)ai**RSA-SHA1** Per `section 3.4.3`_ of the spec. The "RSA-SHA1" signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in `RFC3447, Section 8.2`_ (also known as PKCS#1), using SHA-1 as the hash function for EMSA-PKCS1-v1_5. To use this method, the client MUST have established client credentials with the server that included its RSA public key (in a manner that is beyond the scope of this specification). .. _`section 3.4.3`: https://tools.ietf.org/html/rfc5849#section-3.4.3 .. _`RFC3447, Section 8.2`: https://tools.ietf.org/html/rfc3447#section-8.2 zutf-8Nr rA) rrrBrM_prepare_key_plusZsignrFrGrH)rZrsa_private_keyalgrJsrrr sign_rsa_sha1s     rQcCs|jstdt||jS)Nz4rsa_key is required when using RSA signature method.)Zrsa_keyrrQ)rr?rrrsign_rsa_sha1_with_clientsrRcCs,tj|p d}|d7}|tj|p"d7}|S)aSign a request using plaintext. Per `section 3.4.4`_ of the spec. The "PLAINTEXT" method does not employ a signature algorithm. It MUST be used with a transport-layer mechanism such as TLS or SSL (or sent over a secure channel with equivalent protections). It does not utilize the signature base string or the "oauth_timestamp" and "oauth_nonce" parameters. .. _`section 3.4.4`: https://tools.ietf.org/html/rfc5849#section-3.4.4 rr )r r )r=r>rKrrrsign_plaintextsrScCst|j|jS)N)rSr=r>)rr?rrrsign_plaintext_with_client$srTcCsNt|j}t|j}t|j||}t|||}t||j}|sJt j d||S)aVerify a HMAC-SHA1 signature. Per `section 3.4`_ of the spec. .. _`section 3.4`: https://tools.ietf.org/html/rfc5849#section-3.4 To satisfy `RFC2616 section 5.2`_ item 1, the request argument's uri attribute MUST be an absolute URI whose netloc part identifies the origin server or gateway on which the resource resides. Any Host item of the request argument's headers dict attribute will be ignored. .. _`RFC2616 section 5.2`: https://tools.ietf.org/html/rfc2616#section-5.2 z,Verify HMAC-SHA1 failed: sig base string: %s) r;r%r&r!rrr<rrKlogdebug)requestr=r> norm_paramsr!rrKmatchrrrverify_hmac_sha1(s    rZcCst|tr|jd}|j|S)Nzutf-8)rrrHZ prepare_key)rOZkeystrrrrrNDs  rNc Cslt|j}t|j}t|j||jd}tj|j jd}t }t ||}|j |||}|sht jd||S)afVerify a RSASSA-PKCS #1 v1.5 base64 encoded signature. Per `section 3.4.3`_ of the spec. Note this method requires the jwt and cryptography libraries. .. _`section 3.4.3`: https://tools.ietf.org/html/rfc5849#section-3.4.3 To satisfy `RFC2616 section 5.2`_ item 1, the request argument's uri attribute MUST be an absolute URI whose netloc part identifies the origin server or gateway on which the resource resides. Any Host item of the request argument's headers dict attribute will be ignored. .. _`RFC2616 section 5.2`: https://tools.ietf.org/html/rfc2616#section-5.2 zutf-8z+Verify RSA-SHA1 failed: sig base string: %s)r;r%r&r!rrrBrFZ a2b_base64rKrMrNZverifyrUrV) rWZrsa_public_keyrXr!messageZsigrOrJZ verify_okrrrverify_rsa_sha1Is    r\cCs(t||}t||j}|s$tjd|S)zVerify a PLAINTEXT signature. Per `section 3.4`_ of the spec. .. _`section 3.4`: https://tools.ietf.org/html/rfc5849#section-3.4 zVerify PLAINTEXT failed)rSrrKrUrV)rWr=r>rKrYrrrverify_plaintexths    r])N)NN)NN)'__doc__Z __future__rrrFrErCZloggingZoauthlib.commonrrrrrrr r ImportErrorZ urllib.parseparseZ getLogger__name__rUrr&r7r;r@r<rLrMrQrRrSrTrZrNr\r]rrrrs<   A Wzb1#