
                         v    d Z ddlmZ ddlZddlZddlmZ dZdZdZ	dZ
dad	 Z G d
 de      Z G d de      Zy)zPure Python crypto-related routines for oauth2client.

Uses the ``rsa``, ``pyasn1`` and ``pyasn1_modules`` packages
to parse PEM files storing PKCS#1 or PKCS#8 keys as well as
certificates.
    )pemN)_helpersz\
PKCS12 format is not supported by the RSA library.
Either install PyOpenSSL, or please convert .p12 format
to .pem format:
    $ cat key.p12 | \
    >   openssl pkcs12 -nodes -nocerts -passin pass:notasecret | \
    >   openssl rsa > key.pem
)   @                      )z-----BEGIN RSA PRIVATE KEY-----z-----END RSA PRIVATE KEY-----)z-----BEGIN PRIVATE KEY-----z-----END PRIVATE KEY-----c                     t        |       }t               }t        j                  j	                  d|d      D ];  }| ||dz    }t        d t        t        |      D              }|j                  |       = t        |      S )zConverts an iterable of 1's and 0's to bytes.

    Combines the list 8 at a time, treating each group of 8 bits
    as a single byte.
    r   r	   c              3   ,   K   | ]  \  }}||z    y wN ).0valdigits      2lib/third_party/oauth2client/_pure_python_crypt.py	<genexpr>z%_bit_list_to_bytes.<locals>.<genexpr>8   s!      @)>:3 U{)>s   )
len	bytearraysixmovesxrangesumzip_POW2appendbytes)bit_listnum_bits	byte_valsstart	curr_bitschar_vals         r   _bit_list_to_bytesr&   .   s}     8}HI!!!Xq1U519-	 @),UI)>@ @"	 2
     c                   ,    e Zd ZdZd Zd Zed        Zy)RsaVerifierzVerifies the signature on a message.

    Args:
        pubkey: rsa.key.PublicKey (or equiv), The public key to verify with.
    c                     || _         y r   )_pubkey)selfpubkeys     r   __init__zRsaVerifier.__init__E   s	    r'   c                     t        j                  |d      }	 t        j                  j	                  ||| j
                        S # t        t        j                  j                  f$ r Y yw xY w)a  Verifies a message against a signature.

        Args:
            message: string or bytes, The message to verify. If string, will be
                     encoded to bytes as utf-8.
            signature: string or bytes, The signature on the message. If
                       string, will be encoded to bytes as utf-8.

        Returns:
            True if message was signed by the private key associated with the
            public key that this object was constructed with.
        utf-8encodingF)r   	_to_bytesrsapkcs1verifyr+   
ValueErrorVerificationError)r,   message	signatures      r   r6   zRsaVerifier.verifyH   sY     $$Ww?	99##GYEECII778 		s   *A #A*)A*c                    t        j                  |      }|rddlm} ddlm} t        j                  j                  |d      }|j                  ||j                               \  }}|dk7  rt        d|      |d   d	   }t        |d
         }	t        j                  j                  |	d      }
n t        j                  j                  |d      }
 | |
      S )a  Construct an RsaVerifier instance from a string.

        Args:
            key_pem: string, public key in PEM format.
            is_x509_cert: bool, True if key_pem is an X509 cert, otherwise it
                          is expected to be an RSA key in PEM format.

        Returns:
            RsaVerifier instance.

        Raises:
            ValueError: if the key_pem can't be parsed. In either case, error
                        will begin with 'No PEM start marker'. If
                        ``is_x509_cert`` is True, will fail to find the
                        "-----BEGIN CERTIFICATE-----" error, otherwise fails
                        to find "-----BEGIN RSA PUBLIC KEY-----".
        r   decoder)rfc2459CERTIFICATEasn1Specr'   Unused bytestbsCertificatesubjectPublicKeyInfosubjectPublicKeyDERPEM)r   r3   pyasn1.codec.derr=   pyasn1_modulesr>   r4   r   load_pemdecodeCertificater7   r&   	PublicKey
load_pkcs1)clskey_pemis_x509_certr=   r>   der	asn1_cert	remaining	cert_info	key_bytesr-   s              r   from_stringzRsaVerifier.from_string[   s    & $$W-0.''""7M:C#*>>#@S@S@U>#V IyC ;;!"234JKI*95G+HII]]--i?F]]--gu=F6{r'   N)__name__
__module____qualname____doc__r.   r6   classmethodrW   r   r'   r   r)   r)   >   s%    & ! !r'   r)   c                   .    e Zd ZdZd Zd Zedd       Zy)	RsaSignerz}Signs messages with a private key.

    Args:
        pkey: rsa.key.PrivateKey (or equiv), The private key to sign with.
    c                     || _         y r   )_key)r,   pkeys     r   r.   zRsaSigner.__init__   s	    	r'   c                     t        j                  |d      }t        j                  j	                  || j
                  d      S )zSigns a message.

        Args:
            message: bytes, Message to be signed.

        Returns:
            string, The signature of the message for the given key.
        r0   r1   zSHA-256)r   r3   r4   r5   signr`   )r,   r9   s     r   rc   zRsaSigner.sign   s1     $$Ww?yy~~gtyy)<<r'   c                 X   t        j                  |      }t        j                  t	        j
                  |      t        t              \  }}|dk(  r,t        j                  j                  j                  |d      }n|dk(  rddlm} ddlm} t         |j#                         a|j%                  |t               \  }}	|	dk7  rt'        d	|	      |j)                  d
      }
t        j                  j                  j                  |
j+                         d      }nt'        d       | |      S )a  Construct an RsaSigner instance from a string.

        Args:
            key: string, private key in PEM format.
            password: string, password for private key file. Unused for PEM
                      files.

        Returns:
            RsaSigner instance.

        Raises:
            ValueError if the key cannot be parsed as PKCS#1 or PKCS#8 in
            PEM format.
        r   rF   )formatr   r<   )rfc5208r@   r'   rB   
privateKeyzNo key could be detected.)r   _from_bytesr   readPemBlocksFromFiler   StringIO_PKCS1_MARKER_PKCS8_MARKERr4   key
PrivateKeyrN   rH   r=   rI   rf   _PKCS8_SPECPrivateKeyInforK   r7   getComponentByNameasOctets)rO   rm   password	marker_idrV   ra   r=   rf   key_inforT   	pkey_infos              r   rW   zRsaSigner.from_string   s   " ""3'"88LL}m =	9 >77%%008= 1 ?D!^0."#224k")..K #1 #1HiC ;; 33LAI77%%001C1C1E8= 1 ?D 8994yr'   N)
notasecret)rX   rY   rZ   r[   r.   rc   r\   rW   r   r'   r   r^   r^      s%    
= ' 'r'   r^   )r[   rI   r   r4   r   oauth2clientr   _PKCS12_ERRORr   rk   rl   ro   r&   objectr)   r^   r   r'   r   <module>r{      sW     
 
 ! 	&2. ?& ?D> >r'   