
    M/eF                     n   d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddlm
Z
 ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlZddlmZ ddlmZ ddlmZ  ej2                  e      Zej8                  Z G d d      Z G d d      Zddeddfde de de!de!de!dee"e!f   deee       dejF                  fdZ$	 	 	 d4de d eeee"   ee"   f      d!e%d"eeeejL                  ejN                  f         de f
d#Z(d$eejF                  ejR                  f   dee"   fd%Z*d&eejF                  ejR                  f   dee"   fd'Z+d&eejF                  ejR                  f   dee"   fd(Z,d&eejF                  ejR                  f   dee"   fd)Z-	 	 	 	 	 d5d*ej\                  d eee"      d+ee!   d,e!d-e%d.eeej^                        d/eeeejL                  ejN                  f         dejF                  fd0Z0ejb                  fd1eeejd                     eejF                     f   d2e!de fd3Z3y)6zCrypto utilities.    N)Any)Callable)List)Mapping)Optional)Sequence)Set)Tuple)Union)crypto)SSL)errorsc                       e Zd Zdeeeej                  ej                  f   f   fdZ	de
j                  deeej                  ej                  f      fdZy)_DefaultCertSelectioncertsc                     || _         y N)r   )selfr   s     2/usr/lib/python3/dist-packages/acme/crypto_util.py__init__z_DefaultCertSelection.__init__&   s	    
    
connectionreturnc                 `    |j                         }|r| j                  j                  |d       S y r   )get_servernamer   get)r   r   server_names      r   __call__z_DefaultCertSelection.__call__)   s+     //1::>>+t44r   N)__name__
__module____qualname__r   bytesr
   r   PKeyX509r   r   
Connectionr   r    r   r   r   r   %   s[    geU6;;3K-L&LM 3>> huV[[RXR]R]E]?^6_ r   r   c                   z   e Zd ZdZdeddfdej
                  deeee	e
j                  e
j                  f   f      dedeeej                   ee   gef      deeej                   gee	e
j                  e
j                  f      f      ddfd	Zd
edefdZdej                   ddfdZ G d d      Zde	eef   fdZy)	SSLSocketa  SSL wrapper for sockets.

    :ivar socket sock: Original wrapped socket.
    :ivar dict certs: Mapping from domain names (`bytes`) to
        `OpenSSL.crypto.X509`.
    :ivar method: See `OpenSSL.SSL.Context` for allowed values.
    :ivar alpn_selection: Hook to select negotiated ALPN protocol for
        connection.
    :ivar cert_selection: Hook to select certificate for connection. If given,
        `certs` parameter would be ignored, and therefore must be empty.

    Nsockr   methodalpn_selectioncert_selectionr   c                     || _         || _        || _        |s|st        d      |r|rt        d      |}|t	        |r|ni       }|| _        y )Nz*Neither cert_selection or certs specified.z(Both cert_selection and certs specified.)r)   r+   r*   
ValueErrorr   r,   )r   r)   r   r*   r+   r,   actual_cert_selections          r   r   zSSLSocket.__init__=   sg     	,eIJJeGHH Tb 	 !($95%b$Q!3r   namec                 .    t        | j                  |      S r   )getattrr)   r   r0   s     r   __getattr__zSSLSocket.__getattr__T   s    tyy$''r   r   c                    | j                  |      }|%t        j                  d|j                                y|\  }}t	        j
                  | j                        }|j                  t        j                         |j                  t        j                         |j                  |       |j                  |       | j                  |j                  | j                         |j                  |       y)a  SNI certificate callback.

        This method will set a new OpenSSL context object for this
        connection when an incoming connection provides an SNI name
        (in order to serve the appropriate certificate, if any).

        :param connection: The TLS connection object on which the SNI
            extension was received.
        :type connection: :class:`OpenSSL.Connection`

        Nz=Certificate selection for server name %s failed, dropping SSL)r,   loggerdebugr   r   Contextr*   set_optionsOP_NO_SSLv2OP_NO_SSLv3use_privatekeyuse_certificater+   set_alpn_select_callbackset_context)r   r   pairkeycertnew_contexts         r   _pick_certificate_cbzSSLSocket._pick_certificate_cbW   s     "":.<LLX#2246	Tkk$++.00""3'##D)*001D1DE{+r   c                   T    e Zd ZdZdej
                  ddfdZdedefdZ	dede
fd	Zy)
SSLSocket.FakeConnectionzFake OpenSSL.SSL.Connection.r   r   Nc                     || _         y r   )_wrapped)r   r   s     r   r   z!SSLSocket.FakeConnection.__init__w   s	    &DMr   r0   c                 .    t        | j                  |      S r   )r2   rH   r3   s     r   r4   z$SSLSocket.FakeConnection.__getattr__z   s    4==$//r   unused_argsc                     	 | j                   j                         S # t        j                  $ r}t	        j
                  |      d }~ww xY wr   )rH   shutdownr   Errorsocketerror)r   rJ   rO   s      r   rL   z!SSLSocket.FakeConnection.shutdown}   s?    *}}--//99 *
 ll5))*s    A	AA	)r   r    r!   __doc__r   r%   r   strr   r4   boolrL   r&   r   r   FakeConnectionrF   r   sB    *	's~~ 	'$ 	'	0C 	0C 	0		* 		* 		*r   rS   c                    | j                   j                         \  }}	 t        j                  | j                        }|j                  t        j                         |j                  t        j                         |j                  | j                         | j                  |j                  | j                         | j                  t        j                  ||            }|j                          t        j!                  d|       	 |j#                          ||fS # t        j$                  $ r}t'        j(                  |      d }~ww xY w#  |j+                           xY w)NzPerforming handshake with %s)r)   acceptr   r8   r*   r9   r:   r;   set_tlsext_servername_callbackrD   r+   r>   rS   r%   set_accept_stater6   r7   do_handshakerM   rN   rO   close)r   r)   addrcontextssl_sockrO   s         r   rU   zSSLSocket.accept   s   YY%%'
d	kk$++.G002243L3LM"".001D1DE**3>>'4+HIH%%' LL7>*%%' T>! 99 * ll5))*	 JJLs0   C*E 
D E E1EEE E!)r   r    r!   rP   _DEFAULT_SSL_METHODrN   r   r   r"   r
   r   r#   r$   intr   r   r%   r   r   rQ   r   r4   rD   rS   rU   r&   r   r   r(   r(   0   s#    UY2\` UY4V]] 4 fkk6;;6N0O)O!PQ44 "*(CNNDK3PRW3W*X!Y4 "*(CNN3C3;E&++BH++CN =O 4P4P +Q "R	4 4.( ( (,s~~ ,$ ,6* *,nc12 r   r(   i  i,  ) r   r0   hostporttimeoutr*   source_addressalpn_protocolsr   c           
         t        j                  |      }|j                  |       d|i}	 t        j	                  d||t        |      rdj                  |d   |d         nd       ||f}	t        j                  |	fi |}
t        j                  |
      5 }t        j                  ||      }|j                          |j!                  |        ||j#                  |       	 |j%                          |j'                          	 ddd       j)                         }|sJ |S # t        j                  $ r}t        j                  |      d}~ww xY w# t         j                  $ r}t        j                  |      d}~ww xY w# 1 sw Y   xY w)a	  Probe SNI server for SSL certificate.

    :param bytes name: Byte string to send as the server name in the
        client hello message.
    :param bytes host: Host to connect to.
    :param int port: Port to connect to.
    :param int timeout: Timeout in seconds.
    :param method: See `OpenSSL.SSL.Context` for allowed values.
    :param tuple source_address: Enables multi-path probing (selection
        of source interface). See `socket.creation_connection` for more
        info. Available only in Python 2.7+.
    :param alpn_protocols: Protocols to request using ALPN.
    :type alpn_protocols: `Sequence` of `bytes`

    :raises acme.errors.Error: In case of any problems.

    :returns: SSL certificate presented by the server.
    :rtype: OpenSSL.crypto.X509

    rc   z!Attempting to connect to %s:%d%s.z from {0}:{1}r      r_   N)r   r8   set_timeoutr6   r7   anyformatrN   create_connectionrO   r   rM   
contextlibclosingr%   set_connect_stateset_tlsext_host_nameset_alpn_protosrX   rL   get_peer_certificate)r0   r`   ra   rb   r*   rc   rd   r[   socket_kwargssocket_tupler)   rO   client
client_sslrB   s                  r   	probe_sniru      sx   . kk&!G %~6M"/t ^$ ""q!q! +-	
 ,0,''FF 
		D	! 
&V^^GV4
$$&''-%&&~6	&##%!
& **,DK4K! << "ll5!!" yy 	&,,u%%	&
& 
&sC   AD! AF" E!E4E		EE>$E99E>>FF
private_key_pemdomainsmust_stapleipaddrsc                    t        j                  t         j                  |       }t        j                         }g }|g }|g }t	        |      t	        |      z   dk(  rt        d      |D ]  }|j                  d|z           |D ]   }|j                  d|j                  z          " dj                  |      j                  d      }	t        j                  dd|		      g}
|r'|
j                  t        j                  d
dd	             |j                  |
       |j                  |       |j                  d       |j                  |d       t        j                  t         j                  |      S )a  Generate a CSR containing domains or IPs as subjectAltNames.

    :param buffer private_key_pem: Private key, in PEM PKCS#8 format.
    :param list domains: List of DNS names to include in subjectAltNames of CSR.
    :param bool must_staple: Whether to include the TLS Feature extension (aka
        OCSP Must Staple: https://tools.ietf.org/html/rfc7633).
    :param list ipaddrs: List of IPaddress(type ipaddress.IPv4Address or ipaddress.IPv6Address)
    names to include in subbjectAltNames of CSR.
    params ordered this way for backward competablity when called by positional argument.
    :returns: buffer PEM-encoded Certificate Signing Request.
    r   zAAt least one of domains or ipaddrs parameter need to be not emptyDNS:IP:, ascii   subjectAltNameFcriticalvalues   1.3.6.1.5.5.7.1.24s   DER:30:03:02:01:05sha256)r   load_privatekeyFILETYPE_PEMX509Reqlenr.   appendexplodedjoinencodeX509Extensionadd_extensions
set_pubkeyset_versionsigndump_certificate_request)rv   rw   rx   ry   private_keycsrsanlistaddressips
san_string
extensionss              r   make_csrr      sa    ((_.K
..
CG
7|CL A%\]] )v'() -us||+,- 7#**73J 		
J &..!') 	* z"NN;OOAHH[(#**S" "r   loaded_cert_or_reqc                     | j                         j                  }t        |       }||S |g|D cg c]
  }||k7  s	| c}z   S c c}w r   )get_subjectCN_pyopenssl_cert_or_req_san)r   common_namesansds       r    _pyopenssl_cert_or_req_all_namesr     sP     %00255K%&89D=t@!qK/?A@@@@s
   
AAcert_or_reqc                     d}d|z   }t        |       }|D cg c]'  }|j                  |      r|j                  |      d   ) c}S c c}w )a  Get Subject Alternative Names from certificate or CSR using pyOpenSSL.

    .. todo:: Implement directly in PyOpenSSL!

    .. note:: Although this is `acme` internal API, it is used by
        `letsencrypt`.

    :param cert_or_req: Certificate or CSR.
    :type cert_or_req: `OpenSSL.crypto.X509` or `OpenSSL.crypto.X509Req`.

    :returns: A list of Subject Alternative Names that is DNS.
    :rtype: `list` of `str`

    :DNSrf   )_pyopenssl_extract_san_list_raw
startswithsplitr   part_separatorprefix
sans_partsparts        r   r   r   #  sX    $ N^#F0=J #?doof&= JJ~&q) ? ? ?s   ,Ac                     d}d|z   }t        |       }|D cg c]"  }|j                  |      s|t        |      d $ c}S c c}w )ae  Get Subject Alternative Names IPs from certificate or CSR using pyOpenSSL.

    :param cert_or_req: Certificate or CSR.
    :type cert_or_req: `OpenSSL.crypto.X509` or `OpenSSL.crypto.X509Req`.

    :returns: A list of Subject Alternative Names that are IP Addresses.
    :rtype: `list` of `str`. note that this returns as string, not IPaddress object

    r   z
IP AddressN)r   r   r   r   s        r   _pyopenssl_cert_or_req_san_ipr   >  sG     NN*F0=J+5Q49PDVQQQs
   AAc                    t        | t        j                        r4t        j                  t        j                  |       j                  d      }n3t        j                  t        j                  |       j                  d      }t        j                  d|      }d}|g }|S |j                  d      j                  |      }|S )a  Get raw SAN string from cert or csr, parse it as UTF-8 and return.

    :param cert_or_req: Certificate or CSR.
    :type cert_or_req: `OpenSSL.crypto.X509` or `OpenSSL.crypto.X509Req`.

    :returns: raw san strings, parsed byte as utf-8
    :rtype: `list` of `str`

    zutf-8z5X509v3 Subject Alternative Name:(?: critical)?\s*(.*)r}   rf   )
isinstancer   r$   dump_certificateFILETYPE_TEXTdecoder   researchgroupr   )r   textraw_sanparts_separatorr   s        r   r   r   R  s     +v{{+&&v';';[IPPQXY..v/C/C[QXXY`a iiPRVWGO J -4MM!,<,B,B?,SJr   rA   
not_beforevalidity	force_sanr   r   c           	         |s	|sJ d       t        j                         }|j                  t        t	        j
                  t        j                  d            d             |j                  d       |g }|g }|g }|j                  t        j                  ddd             t        |      dkD  r|d   |j                         _        |j                  |j                                g }|D ]  }	|j                  d|	z           |D ]   }
|j                  d	|
j                  z          " d
j!                  |      j#                  d      }|st        |      dkD  st        |      dkD  r'|j                  t        j                  dd|             |j%                  |       |j'                  |dn|       |j)                  |       |j+                  |        |j-                  | d       |S )at  Generate new self-signed certificate.

    :type domains: `list` of `str`
    :param OpenSSL.crypto.PKey key:
    :param bool force_san:
    :param extensions: List of additional extensions to include in the cert.
    :type extensions: `list` of `OpenSSL.crypto.X509Extension`
    :type ips: `list` of (`ipaddress.IPv4Address` or `ipaddress.IPv6Address`)

    If more than one domain is provided, all of the domains are put into
    ``subjectAltName`` X.509 extension and first domain is set as the
    subject CN. If only one domain is provided no ``subjectAltName``
    extension is used, unless `force_san` is ``True``.

    z7Must provide one or more hostnames or IPs for the cert.      s   basicConstraintsTs   CA:TRUE, pathlen:0r   r{   r|   r}   r~   rf   r   Fr   r   )r   r$   set_serial_numberr^   binasciihexlifyosurandomr   r   r   r   r   r   
set_issuerr   r   r   r   gmtime_adj_notBeforegmtime_adj_notAfterr   r   )rA   rw   r   r   r   r   r   rB   r   r   ipr   s               r   gen_ss_certr   q  s   * cTTT>;;=D3x//

2?DEQ

{'<	>
 7|a '
OOD$$&'G )v'() ,ur{{*+,7#**73JCL1$C1&..
 	 	
#:#5a:FX&OOCIIc8Kr   chainfiletypec                     dt         t        j                  t        j                  f   dt
        ffddj                  fd| D              S )zDump certificate chain into a bundle.

    :param list chain: List of `OpenSSL.crypto.X509` (or wrapped in
        :class:`josepy.util.ComparableX509`).

    :returns: certificate chain bundle
    :rtype: bytes

    rB   r   c                     t        | t        j                        rEt        | j                  t        j
                        rt        j                  d      | j                  } t	        j                  |       S )NzUnexpected CSR provided.)	r   joseComparableX509wrappedr   r   r   rM   r   )rB   r   s    r   
_dump_certz(dump_pyopenssl_chain.<locals>._dump_cert  sQ    dD//0$,,7ll#=>><<D&&x66r   r   c              3   .   K   | ]  } |        y wr   r&   ).0rB   r   s     r   	<genexpr>z'dump_pyopenssl_chain.<locals>.<genexpr>  s     7Jt$7s   )r   r   r   r   r$   r"   r   )r   r   r   s    `@r   dump_pyopenssl_chainr     sA    7t22FKK?@ 7U 7 887777r   )NFN)NNi:	 TNN)4rP   r   rk   	ipaddressloggingr   r   rN   typingr   r   r   r   r   r   r	   r
   r   josepyr   OpenSSLr   r   acmer   	getLoggerr   r6   SSLv23_METHODr]   r   r(   r"   r^   rQ   r$   ru   rR   IPv4AddressIPv6Addressr   r   r   r   r   r   r#   r   r   r   r   r   r&   r   r   <module>r      s        	 	              			8	$ ''  u up 58/SZ:>6E 6 6c 6# 66AFsCx6&x76CI;;6r VZ!&\`4"e 4"huSXtCy=P7Q.R 4"4"tE)*?*?AVAV*V$WXY4" 4"nAv{{FNN?Z9[ A*.s)A?E&++v~~2M,N ?SWX[S\ ?6RuV[[&..5P/Q RVZ[^V_ R(v{{FNN7R1S X\]`Xa > BF,0FJCG[_	?V[[ ?8DI+> ?$SM???C? %T&*>*>%?@? d5)>)>	@U@U)U#VWX	?
 [[?F *0)<)<8d4+>+>&?fkkAR&R S 8#&8AF8r   