
    8'hR                        d dl mZ d dl m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gZ	 d dlmZmZmZ dZej#                  d	       d Zd Zd Z G d d      Zd Zd Zd Zd Zd'dZd Zerej:                   G d d	e             Ze dk(  rd dl!Z!es& e"de!jF                          e!jH                  d       d dl%m&Z&  e&       Z'e'jQ                  dddd        e'jQ                  d!d"d#d
d$%       e'jS                         \  Z*Z+e*jX                  s* e"d&       e'j[                           e!jH                  d       ej]                  e*j^                        Z0 e"e0jc                                yy# e$ r d
ZY 1w xY w)(    )absolute_import)print_functionN)util)	ChallengeHAS_CRYPTOSIGN)encodingsigningbindingsT
SigningKeyFc                     g }| r@t        j                  d| dd       d   }| d|dz    | d|z   d } }|j                  |       | r@|S )z}
    Unpack a SSH agent key blob into parts.

    See: http://blog.oddbit.com/2011/05/08/converting-openssh-public-keys/
    >IN   r   )structunpackappend)keydatapartsdlendatas       T/var/www/html/trade_iq/venv/lib/python3.12/site-packages/autobahn/wamp/cryptosign.py_unpackr   5   s`     E
}}T72A;/2  $(+WQXY-?gT  L    c           	          g }| D ]A  }|j                  t        j                  dt        |                   |j                  |       C dj	                  |      S )z)
    Pack parts into a SSH key blob.
    r   r   )r   r   packlenjoin)keypartsr   parts      r   _packr   F   sO     E V[[s4y12T 88E?r   c                 @   t        |       t        j                  k7  r#t        dj	                  t        |                   | j                         j                         }t        |      dk7  rt        d      |\  }} }|dk7  rt        dj	                  |            t        j                  |       }	 t        |      d   }t        |      d	k7  r#t        d
j	                  t        |                  ||fS # t        $ r}t        dj	                  |            d}~ww xY w)a  
    Parse an OpenSSH Ed25519 public key from a string into a raw public key.

    Example input:

        ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJukDU5fqXv/yVhSirsDWsUFyOodZyCSLxyitPPzWJW9 oberstet@office-corei7

    :param keydata: The OpenSSH Ed25519 public key data to parse.
    :type keydata: str

    :returns: pair of raw public key (32 bytes) and comment
    :rtype: tuple
    zinvalid type {} for keydata   zinvalid SSH Ed25519 public keyzssh-ed25519z%not a Ed25519 SSH public key (but {})   zcould not parse key ({})N    z9invalid length {} for embedded raw key (must be 32 bytes))typesix	text_type	Exceptionformatstripsplitr   binascii
a2b_base64r   )r   r   algocommentblobkeyes          r   _read_ssh_ed25519_pubkeyr2   Q   s    G}%5<<T']KLLMMO!!#E
5zQ899"D'7~?FFtLMMw'D>dmA 3x2~SZZ[^_b[cdee<  >299!<==>s   2C5 5	D>DDc                   .    e Zd ZdZd Zd Zd Zd Zd Zy)_SSHPacketReaderzD
    Read OpenSSH packet format which is used for key material.
    c                 @    || _         d| _        t        |      | _        y )Nr   )_packet_idxr   _len)selfpackets     r   __init__z_SSHPacketReader.__init__|   s    	K	r   c                 4    | j                   | j                  d  S N)r6   r7   r9   s    r   get_remaining_payloadz&_SSHPacketReader.get_remaining_payload   s    ||DIIJ''r   c                     | j                   |z   | j                  kD  rt        d      | j                  | j                   | j                   |z    }| xj                   |z  c_         |S )Nzincomplete packet)r7   r8   r'   r6   )r9   sizevalues      r   	get_bytesz_SSHPacketReader.get_bytes   sS    99tdii'/00TYYtyy4'78		T	r   c                 R    t        j                  d| j                  d            d   S )Nr   r   r   )r   r   rC   r>   s    r   
get_uint32z_SSHPacketReader.get_uint32   s!    }}T4>>!#45a88r   c                 @    | j                  | j                               S r=   )rC   rE   r>   s    r   
get_stringz_SSHPacketReader.get_string   s    ~~doo/00r   N)	__name__
__module____qualname____doc__r;   r?   rC   rE   rG    r   r   r4   r4   w   s      
(91r   r4   c                 L    dj                  d t        d| dz         D              S )N c              3   2   K   | ]  }t        |        y wr=   )chr).0xs     r   	<genexpr>z_makepad.<locals>.<genexpr>   s     6a3q66s   r"   )r   range)rA   s    r   _makepadrU      s"    7765D1H#5666r   c                 
   d}d}d}| j                  |      r| j                  |      st        d      | j                  |      }| t	        |      | } dj                  | j                         D cg c]  }|j                          c}      } t        j                  |       }|t	        |      d }t        |      }|j                         }|j                         }	|j                          |j                         }
|j                          |j                         }|j                         }d}|dk7  rt        d	      |	dk7  rt        d
      |
dk7  rt        dj                  |
            |rt        d      t        |      }|j                          |j                          |j                         }|dk7  r)t        dj                  |j                  d                  |j                         }|j                         }t	        |      t         j"                  k7  rt        d      t	        |      t         j$                  k7  rt        d      |j                         }|j                         }t	        |      r\t	        |      |k\  s|t'        t	        |            k7  r7t        dj                  t	        |      |t'        t	        |                        |dt         j(                   }|j                  d      }||fS c c}w )a  
    Parse an OpenSSH Ed25519 private key from a string into a raw private key.

    Example input:

        -----BEGIN OPENSSH PRIVATE KEY-----
        b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
        QyNTUxOQAAACCbpA1OX6l7/8lYUoq7A1rFBcjqHWcgki8corTz81iVvQAAAKDWjZ0Y1o2d
        GAAAAAtzc2gtZWQyNTUxOQAAACCbpA1OX6l7/8lYUoq7A1rFBcjqHWcgki8corTz81iVvQ
        AAAEArodzIMjH9MOBz0X+HDvL06rEJOMYFhzGQ5zXPM7b7fZukDU5fqXv/yVhSirsDWsUF
        yOodZyCSLxyitPPzWJW9AAAAFm9iZXJzdGV0QG9mZmljZS1jb3JlaTcBAgMEBQYH
        -----END OPENSSH PRIVATE KEY-----


    :param keydata: The OpenSSH Ed25519 private key data to parse.
    :type keydata: str

    :returns: pair of raw private key (32 bytes) and comment
    :rtype: tuple
    #-----BEGIN OPENSSH PRIVATE KEY-----z!-----END OPENSSH PRIVATE KEY-----s   openssh-key-v1 zFinvalid OpenSSH private key (does not start/end with OPENSSH preamble)rN   N   s   nonezjencrypted private keys not supported (please remove the passphrase from your private key or use SSH agent)z/passphrase encrypted private keys not supportedr"   zAmultiple private keys in a key file not supported (found {} keys)z=invalid OpenSSH private key (found remaining payload for mac)s   ssh-ed25519z6invalid key type: we only support Ed25519 (found "{}")asciizinvalid public key lengthzGinvalid OpenSSH private key (padlen={}, actual_pad={}, expected_pad={}))
startswithendswithr'   findr   r   r*   r)   r+   r,   r4   rG   rE   r?   r(   decoder
   crypto_sign_PUBLICKEYBYTEScrypto_sign_SECRETKEYBYTESrU   crypto_sign_SEEDBYTES)r   	SSH_BEGINSSH_ENDOPENSSH_KEY_V1ssh_endrR   r/   r:   cipher_namekdfnkeyskey_datamac
block_sizealgvkskr.   padseeds                       r   _read_ssh_ed25519_privkeyrp      s   < 7I2G(Ny)g.>.>w.G`aall7#Gc)nW-Ghh7==?;a	;<Gw'DN#$%Dd#F##%K



C
E
  "H

&
&
(CJg  E  F  	F
g~IJJz[bbchijj
WXXh'F





C
nPWWX[XbXbcjXklmm				B				B
2w(555344
2w(555344!G

&
&
(C
3xSX+shs3x6H/Hahhilmpiqsv  yA  BE  FI  BJ  yK  L  M  	M -x--.DnnW%G=u <s   0L c                    t        |       5 }t        j                  |j                         j	                         d         dd }t        |      dk7  r#t        dj                  t        |                  |cddd       S # 1 sw Y   yxY w)z
    Read a Ed25519 signature file created with OpenBSD signify.

    http://man.openbsd.org/OpenBSD-current/man1/signify.1
    r"   
   N@   zEbogus Ed25519 signature: raw signature length was {}, but expected 64openr+   r,   read
splitlinesr   r'   r(   )signature_filefsigs      r   _read_signify_ed25519_signaturer{      sz     
n	 !!!&&("5"5"7":;BC@s8r>cjjknorkstuu     A*B  B	c                    t        |       5 }t        j                  |j                         j	                         d         dd }t        |      dk7  r#t        dj                  t        |                  |cddd       S # 1 sw Y   yxY w)z
    Read a public key from a Ed25519 key pair created with OpenBSD signify.

    http://man.openbsd.org/OpenBSD-current/man1/signify.1
    r"   rr   Nr#   z@bogus Ed25519 public key: raw key length was {}, but expected 32rt   )pubkey_filery   pubkeys      r   _read_signify_ed25519_pubkeyr   	  s{     
k	 a$$QVVX%8%8%:1%=>rsCv;"^eefijpfqrss  r|   c                    |dv sJ ddl }t        |       5 }|j                         j                         d   }|j	                  |dd      }|dk(  r|j                         cddd       S |d	k(  r@ddl}|j                         }|j                  |d
       |j                         cddd       S t        d      # 1 sw Y   yxY w)a  

    Usage:

    1. Get the OpenBSD 5.7 release public key from here

        http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/etc/signify/Attic/openbsd-57-base.pub?rev=1.1

    2. Generate QR Code and print to terminal

        print(cryptosign._qrcode_from_signify_ed25519_pubkey('openbsd-57-base.pub'))

    3. Compare to (scroll down) QR code here

        https://www.openbsd.org/papers/bsdcan-signify.html
    )textsvgr   Nr"   Lbinary)errormoder   r   T)omithwzlogic error)pyqrcoderu   rv   rw   createterminalioBytesIOr   getvaluer'   )r~   r   r   ry   r   qrr   data_buffers           r   #_qrcode_from_signify_ed25519_pubkeyr     s    " ?"#"	k	 +a$$&q)__V3X_>6>;;=+ + U]**,KFF;tF,'')+ +" M**#+ +s   A
B:*;B:/B::Cc                 ~    t        |       }t        j                  |      }t        |      }|j	                  ||       y)a  
    Verify a Ed25519 signature created with OpenBSD signify.

    This will raise a `nacl.exceptions.BadSignatureError` if the signature is bad
    and return silently when the signature is good.

    Usage:

    1. Create a signature:

        signify-openbsd -S -s ~/.signify/crossbario-trustroot.sec -m .profile

    2. Verify the signature

        from autobahn.wamp import cryptosign

        with open('.profile', 'rb') as f:
            message = f.read()
            cryptosign._verify_signify_ed25519_signature('.signify/crossbario-trustroot.pub', '.profile.sig', message)

    http://man.openbsd.org/OpenBSD-current/man1/signify.1
    N)r   r	   	VerifyKeyr{   verify)r~   rx   messager   
verify_keyrz   s         r   !_verify_signify_ed25519_signaturer   @  s8    . *+6F""6*J
).
9Cgs#r   c                   r   e Zd ZdZddZd Zej                  d        Zej                  d        Z	ej                  dd       Z
ej                  d        Zej                  d	        Zej                  edd
              Zedd       Zej                  ed               Zej                  ed               Zy)r   z
        A cryptosign private key for signing, and hence usable for authentication or a
        public key usable for verification (but can't be used for signing).
        Nc                    t        |t        j                        s=t        |t        j                        s#t	        dj                  t        |                  |?t        |      t        j                  k(  s#t	        dj                  t        |                  || _	        || _
        t        |t        j                        | _        y)z

            :param key: A Ed25519 private signing key or a Ed25519 public verification key.
            :type key: instance of nacl.signing.VerifyKey or instance of nacl.signing.SigningKey
            zinvalid type {} for keyNinvalid type {} for comment)
isinstancer	   r   r   r'   r(   r$   r%   r&   _key_comment	_can_sign)r9   r0   r.   s      r   r;   zSigningKey.__init__o  s     sG$5$56*S'J\J\:] 9 @ @c KLLOtG}'E = D DT'] STTDI#DM'W-?-?@DNr   c                     | j                         rdj                  | j                               nd }dj                  | j                         || j                               S )Nz"{}"z+Key(can_sign={}, comment={}, public_key={}))r.   r(   can_sign
public_key)r9   r.   s     r   __str__zSigningKey.__str__  sF    8<gnnT\\^4DGAHHZacgcrcrctuur   c                     | j                   S )z
            Check if the key can be used to sign.

            :returns: `True`, iff the key can sign.
            :rtype: bool
            )r   r>   s    r   r   zSigningKey.can_sign  s     >>!r   c                     | j                   S )z
            Get the key comment (if any).

            :returns: The comment (if any) from the key.
            :rtype: str or None
            )r   r>   s    r   r.   zSigningKey.comment  s     == r   c                    t        | j                  t        j                        r| j                  j                  }n| j                  }|r|j                         S |j                  t        j                        j                  d      S )z
            Returns the public key part of a signing key or the (public) verification key.

            :returns: The public key in Hex encoding.
            :rtype: str or None
            encoderrY   )	r   r   r	   r   r   encoder   
HexEncoderr]   )r9   r   r0   s      r   r   zSigningKey.public_key  sa     $))W%7%78ii**iizz|#zz(*=*=z>EEgNNr   c                     | j                   st        d      t        |      t        j                  k7  rt        d      | j
                  j                  |      }t        j                  |j                        S )z
            Sign some data.

            :param data: The data to be signed.
            :type data: bytes

            :returns: The signature.
            :rtype: bytes
            za signing key required to signz data to be signed must be binary)
r   r'   r$   r%   binary_typer   signtxaiocreate_future_success	signature)r9   r   rz   s      r   r   zSigningKey.sign  s^     >> @AADzS__, BCC ))..&C ..s}}==r   c                   	 t        |t              s#t        dj                  t	        |                  d|j
                  vrt        d      |j
                  d   }t	        |      t        j                  k7  r#t        dj                  t	        |                  t        |      dk7  r#t        dj                  t        |                  t        j                  |      }|j                  j                         }|rDt        |      dk(  sJ dj                  t        |                   t        j                  ||      	n|	| j                  	      }t!        j"                         	fd	}t!        j$                  ||d
       S )a  
            Sign WAMP-cryptosign challenge.

            :param session: The authenticating WAMP session.
            :type session: :class:`autobahn.wamp.protocol.ApplicationSession`

            :param challenge: The WAMP-cryptosign challenge object for which a signature should be computed.
            :type challenge: instance of autobahn.wamp.types.Challenge

            :returns: A Deferred/Future that resolves to the computed signature.
            :rtype: str
            zCchallenge must be instance of autobahn.wamp.types.Challenge, not {}	challengez*missing challenge value in challenge.extraz5invalid type {} for challenge (expected a hex string)rs   z:unexpected challenge (hex) length: was {}, but expected 64r#   zCunexpected TLS transport channel ID length: was {}, but expected 32c                     t        j                  |       j                  d      }t        j                        j                  d      }||z   }t        j                  |       y )NrY   )r+   b2a_hexr]   r   resolve)signature_rawsignature_hexdata_hexrz   d2r   s       r   processz*SigningKey.sign_challenge.<locals>.process  sS     ( 0 0 ? F Fw O $++D188A#h.b#&r   N)r   r   r'   r(   r$   extrar%   r&   r   r+   a2b_hex
_transportget_channel_idr   xorr   r   create_futureadd_callbacks)
r9   sessionr   challenge_hexchallenge_rawchannel_id_rawd1r   r   r   s
           @@r   sign_challengezSigningKey.sign_challenge  sl    i3 f m mnrs|n} ~9??2 MNN &OOL9MM"cmm3 X _ _`der`s tuu=!R' ] d dehivew xyy %,,];M %//>>@N>*b0  T2w2~2~  @C  DR  @S  3T  T0xx~>$ 4B $$&B' GT2Ir   c                    |?t        |      t        j                  k(  s#t        dj	                  t        |                  t        |      t        j
                  k7  r#t        dj	                  t        |                  t        |      dk7  r#t        dj	                  t        |                  t        j                  |      } | ||      S )Nr   z%invalid key type {} (expected binary)r#   z#invalid key length {} (expected 32))	r$   r%   r&   
ValueErrorr(   r   r   r	   r   )clsr   r.   r0   s       r   from_key_byteszSigningKey.from_key_bytes  s     OtG}'E !>!E!Ed7m!TUUG}/ !H!O!OPTU\P]!^__7|r! !F!M!McRYl![\\$$W-CsG$$r   c                 x   |?t        |      t        j                  k(  s#t        dj	                  t        |                  t        |      t        j                  k7  rt        dj	                  |            t        |d      5 }|j                         }ddd       | j                  |      S # 1 sw Y   xY w)a  
            Load an Ed25519 (private) signing key (actually, the seed for the key) from a raw file of 32 bytes length.
            This can be any random byte sequence, such as generated from Python code like

                os.urandom(32)

            or from the shell

                dd if=/dev/urandom of=client02.key bs=1 count=32

            :param filename: Filename of the key.
            :type filename: str
            :param comment: Comment for key (optional).
            :type comment: str or None
            Nr   zinvalid type {} for filenamerb)r.   )r$   r%   r&   r'   r(   ru   rv   r   )r   filenamer.   ry   r   s        r   from_raw_keyzSigningKey.from_raw_key  s    " OtG}'E = D DT'] STTH~. > E Eh OPPh% #&&(# %%gw%??# #s   B00B9c                     t        |d      5 }|j                         j                  d      j                         }ddd       | j	                        S # 1 sw Y   xY w)a  
            Load an Ed25519 key from a SSH key file. The key file can be a (private) signing
            key (from a SSH private key file) or a (public) verification key (from a SSH
            public key file). A private key file must be passphrase-less.
            r   zutf-8N)ru   rv   r]   r)   from_ssh_data)r   r   ry   r   s       r   from_ssh_keyzSigningKey.from_ssh_key,  sS     h% ;&&(//'288:;$$W--; ;s   .AAc                     d}|j                  |      r4t        |      \  }}t        j                  |t        j
                        }n#t        |      \  }}t        j                  |      } | ||      S )a  
            Load an Ed25519 key from SSH key file. The key file can be a (private) signing
            key (from a SSH private key file) or a (public) verification key (from a SSH
            public key file). A private key file must be passphrase-less.
            rW   r   )rZ   rp   r	   r   r   
RawEncoderr2   r   )r   r   ra   r.   r0   s        r   r   zSigningKey.from_ssh_data9  sl     ?I!!),#<W#E (((:M:MN $<G#D ''0sG$$r   r=   )F)rH   rI   rJ   rK   r;   r   r   publicr   r.   r   r   r   classmethodr   r   r   r   rL   r   r   r   r   h  s   	
	A 	v 
	" 
	" 
	! 
	! 
	O 
	O" 
	> 
	>2 
;	 
;	z 
		% 
 
	% 
	@ 
	@6 
			. 
 
		. 
		% 
 
	%r   __main__z4NaCl library must be installed for this to function.)filer"   )OptionParserz-fz--filekeyfilezfile containing ssh key)desthelpz-p
store_trueprintpubzprint public key information)actionr   defaultr   z;Print public key must be specified as it's the only option.)r   )2
__future__r   r   r+   r   r%   r   autobahnr   autobahn.wamp.typesr   __all__naclr   r	   r
   r   r   ImportErrorr   r   r2   r4   rU   rp   r{   r   r   r   r   objectr   rH   sysprintstderrexitoptparser   parser
add_option
parse_argsoptionsargsr   print_usager   r   r0   r   rL   r   r   <module>r      s  6 ' %   
   ) !00 NNN< "#L1 187aH&+R$L 	[[b%V b% b%H zD3::V%^F
dH94  6
d<j%9  ; %%'MGTKL

!
!'//
2C	#..
-   Ns   
E1 1E<;E<