NPc@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z yddl m Z Wn!e k rddl m Z nXyddlmZWn'e k rdefdYZnXddlmZdd lmZdd lmZddlZy dd lmZmZmZWn9e k rd efd YZdZdZnXe jZejdZddddddddgZ ejdZ!dddgZ"ejdZ#ejdZ$dZ%dZ&dZ'd Z(d!Z)d"Z*d#Z+d$Z,d%Z-d&Z.d'Z/d(Z0d)Z1d*Z2d+Z3d,Z4d-Z5d.Z6d/Z7d0Z8d1Z9d2Z:d3Z;d4Z<d5Z=d6Z>d7Z?d8Z@d9ZAd:ZBd;ZCd<ZDd=ZEd>ZFd?ZGd@ZHdAZIdBZJdCZKdDejLfdEYZMdFejNeOfdGYZPdHejQfdIYZRdJejSeOfdKYZTdLZUdMZVdNZWdS(OsV Utility functions for keyczar package. @author: arkajit.dey@gmail.com (Arkajit Dey) iN(tsha1(tsha(tBlockingIOErrorRcBseZdZddZRS(sCException raised when I/O would block on a non-blocking I/O stream.icCsJtt|j||t|ttfs=tdn||_dS(Ns$characters_written must be a integer(tsupertIOErrort__init__t isinstancetinttlongt TypeErrortcharacters_written(tselfterrnotstrerrorR ((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR.s(t__name__t __module__t__doc__R(((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR*s(tdecoder(tencoder(tuniv(tABCMetatabstractmethodtabstractpropertyRcBseZRS((RR(((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR>scCs|S(N((tfuncobj((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRAscCs t|S(N(tproperty(R((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRDss1.2.840.113549.1.1.1tntetdtptqtdptdqtinvqs1.2.840.10040.4.1tgs1.2.840.113549.1.1.5s 1.3.14.3.2.26itKEYCZAR_BACKEND_PATHScGsAtj}x.tt|D]}|j|||qW|S(N(RtSequencetrangetlentsetComponentByPosition(tvalstseqti((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt ASN1Sequencebs cCs,gtt|D]}|j|^qS(N(R$R%tgetComponentByPosition(R(R)((s0/usr/lib/python2.7/site-packages/keyczar/util.pytParseASN1SequencehscCsttjt|d}t|dkrCtjdnt|d}|dkrqtjdnt|d\}}tj|dd}i}|tkr&t|}t|d}|dkrtjdnxt tt D]"}t ||d|t |R*R4RR?R@RA(R;R9R)R8RBR(((s0/usr/lib/python2.7/site-packages/keyczar/util.pytExportDsaPkcs8s %$c CsZttjt|d}t|dkrCtjdnt|d\}}tjtjt |dj dd!d}i}|t krgt|D]}t |^q\|d<|dt BytesToBinRR?t BitStringRA(R;R8R:tbinkeyRIR(((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt ExportRsaX509s )cCsttj|dtj|dtj|d}tt|}ttjtj|d}tjd|}t||}ttj|S(NRRR!REs'%s'B( R*RR>R4RKRR?RLRA(R;R9R8RMRIR(((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt ExportDsaX509s"cCs.ttj|tj|}tj|S(s  Given the raw parameters of a DSA signature, return a Base64 signature. @param r: parameter r of DSA signature @type r: long int @param s: parameter s of DSA signature @type s: long int @return: raw byte string formatted as an ASN.1 sequence of r and s @rtype: string (R*RR>RR?(trtsR(((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt MakeDsaSigs !cCsktj|d}t|dkr7tjdnt|jd}t|jd}||fS(s Given a raw byte string, return tuple of DSA signature parameters. @param sig: byte string of ASN.1 representation @type sig: string @return: parameters r, s as a tuple @rtype: tuple @raise KeyczarErrror: if the DSA signature format is invalid iisIllegal DSA signature.i(RR.R%R0R1RR+(tsigR(RPRQ((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt ParseDsaSigs cCsdddddddddd d dd d d g}djg|D]}t|^q@t|}td|dt|d}td|td |S(s/Algorithm EMSA_PKCS1-v1_5 from PKCS 1 version 2i0i!i iii+iiiiiiitiii(tjointchrtHashR%(tmsgt modulus_sizetmagic_sha1_headertctencodedt pad_string((s0/usr/lib/python2.7/site-packages/keyczar/util.pytMakeEmsaMessages 2"cCswt|}gtt|dD]}|d|d|d!^q#}djg|D]}tt|d^qUS(s"Convert bit string to byte string.iiRUi(t_PadByteR$R%RVRWR(tbitsR)toctetsR-((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRFs <cCs2djg|D]}ttt|^q S(s"Convert byte string to bit string.RU(RVR`tIntToBintord(t byte_stringtbyte((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRKscCs$t|d}d|dd|S(sCPad a string of bits with zeros to make its length a multiple of 8.it0(R%(RaRP((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR`scCsZ|dks|dkr"t|S|ddkrDt|ddSt|ddSdS(NiiiRgt1(tstrRc(R((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRc s  cCsQg}x1|dkr9|jt|d|d?}q W|jdj|S(sHReturn a big-endian byte string representation of an arbitrary length n.iiiRU(tappendRWtreverseRV(Rtchars((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt BigIntToBytess  cCs[g|d?|d?|d?|gD]}|d^q}djg|D]}t|^qBS(sEReturn byte string of 4 big-endian ordered byte_array representing n.iiiiRU(RVRW(Rtmt byte_arraytb((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt IntToBytess5cCsOt|}ttgt|D]&}t||d|d|^qS(Nii(R%RtsumR$Rd(RetlR)((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt BytesToLong!s cCstt|t|}|t|krIt||t|}n.|t|krwt||t|}ng|D]}t|^q~}g|D]}t|^q}gt|D]}t||||A^q}dj|S(s=Return a ^ b as a byte string where a and b are byte strings.RU(tmaxR%tPadBytesRdR$RWRV(taRpRnR\R-RER)tz((s0/usr/lib/python2.7/site-packages/keyczar/util.pytXor%s1cCs |d|S(s(Prepend a byte string with n zero bytes.t((ReR((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRv2scCs3|jtd}|dkr+tdS|SdS(sTrim leading zero bytes.iRUN(tlstripRW(Rettrimmed((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt TrimBytes6s  cCs tj|S(sReturn n random bytes.(tosturandom(R((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt RandBytes>scGs1t}x|D]}|j|qW|jS(s5Return a SHA-1 hash over a variable number of inputs.(Rtupdatetdigest(tinputstmdR)((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRXCs  cGsJt}x4|D],}|jtt||j|qW|jS(s5Return a SHA-1 hash over a variable number of inputs.(RRRqR%R(RRR)((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt PrefixHashJs   cCstjdtt|S(Ns4Encode() is deprecated, use Base64WSEncode() instead(twarningstwarntDeprecationWarningRA(RQ((s0/usr/lib/python2.7/site-packages/keyczar/util.pytEncodeSscCstjt|jddS(s- Return Base64 web safe encoding of s. Suppress padding characters (=). Uses URL-safe alphabet: - replaces +, _ replaces /. Will convert s of type unicode to string type first. @param s: string to encode as Base64 @type s: string @return: Base64 representation of s. @rtype: string t=RU(tbase64turlsafe_b64encodeRitreplace(RQ((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRAXs cCstjdtt|S(Ns4Decode() is deprecated, use Base64WSDecode() instead(RRRR/(RQ((s0/usr/lib/python2.7/site-packages/keyczar/util.pytDecodehscCsdj|j}t|jdd}t|d}|dkrXtjn2|dkrq|d7}n|dkr|d7}nytj|SWnt k rtjnXd S( s Return decoded version of given Base64 string. Ignore whitespace. Uses URL-safe alphabet: - replaces +, _ replaces /. Will convert s of type unicode to string type first. @param s: Base64 string to decode @type s: string @return: original string that was encoded as Base64 @rtype: string @raise Base64DecodingError: If length of string (ignoring whitespace) is one more than a multiple of four. RUt iiis==iRN( RVt splitlinesRiRR%R0tBase64DecodingErrorRturlsafe_b64decodeR (RQR((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR/ms      s>iRQcCs*|s dStjtt|}||S(s Packs the given array into a structure composed of a four-byte, big-endian integer containing the array length, followed by the array contents. RU(tstructtpacktBIG_ENDIAN_INT_SPECIFIERR%(tarraytarray_length_header((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt PackByteArrayscGsHtjtt|}djg|D]}t|^q%}||S(s Packs the provided variable number of byte arrays into one array. The returned array is prefixed with a count of the arrays contained, in a four-byte big-endian integer, followed by the arrays in sequence, each length-prefixed by PackByteArray(). RU(RRRR%RVR(tarraystarray_count_headerRwtarray_contents((s0/usr/lib/python2.7/site-packages/keyczar/util.pytPackMultipleByteArrayss(cCsDtjt|||d!d}|d7}||||!||fS(s Unpacks a length-prefixed byte array packed by PackByteArray() from 'data', starting from position 'offset'. Returns a tuple of the data array and the offset of the first byte after the end of the extracted array. ii(RtunpackR(tdatatoffsett array_len((s0/usr/lib/python2.7/site-packages/keyczar/util.pytUnpackByteArrays! cCscd}g}x8|t|krFt||\}}|j|qW|t|ks_t|S(s` Extracts and returns a list of byte arrays that were packed by PackMultipleByteArrays(). i(R%RRjtAssertionError(RtpositiontresultR((s0/usr/lib/python2.7/site-packages/keyczar/util.pytUnpackMultipleByteArraysscCsUy*t|d}|j||jWn$tk rPtjd|nXdS(s Writes data to file at given location. @param data: contents to be written to file @type data: string @param loc: name of file to write to @type loc: string @raise KeyczarError: if unable to write to file because of IOError twsUnable to write to file %s.N(topentwritetcloseRR0R1(Rtloctf((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt WriteFiles   cCs?yt|jSWn$tk r:tjd|nXdS(s Read data from file at given location. @param loc: name of file to read from @type loc: string @return: contents of the file @rtype: string @raise KeyczarError: if unable to read from file because of IOError sUnable to read file %s.N(RtreadRR0R1(R((s0/usr/lib/python2.7/site-packages/keyczar/util.pytReadFiles  cCsy|dtkr"tjdnd}xFtttj|ttD]}|t|t |7}qNW|| S(sD Mask Generation Function (MGF1) with SHA-1 as hash. @param seed: used to generate mask, a byte string @type seed: string @param mlen: desired length of mask @type mlen: integer @return: mask, byte string of length mlen @rtype: string @raise KeyczarError: if mask length too long, > 2^32 * hash_length ii sMGF1 mask length too long.RUI( tHLENR0R1R$RtmathtceiltfloatRXRq(tseedtmlentoutputR)((s0/usr/lib/python2.7/site-packages/keyczar/util.pytMGFs ,t"BufferedIncrementalBase64WSEncodercBs,eZdZdZedZdZRS(s Web-safe Base64 encodes an input in multiple steps. Each step bar the final one will be sized to ensure no Base64 padding is required. Any unencoded data outside this optimal size will be buffered. cCs=|sdt|d}n t|}t|| |fS(s  Encodes input and returns the resulting object, buffering any data that is beyond the optimal no-padding length unless final is True Implementation of abstract method in parent. @param input: string to encode as Base64 @type input: string @param errors: required error handling scheme (see IncrementalBase64WSStreamWriter) @param final: force all data to be encoded, possibly resulting in padding #type final: boolean @return: (Base64 representation of input, length consumed) @rtype: tuple i(R%RA(R tinputR0tfinalt len_to_write((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt_buffer_encodes cCs;tt|j|d|}|t|t|jfS(s Encodes input and returns the resulting object. Note that unless final is True the returned data may not encode all the supplied input as it encodes the maximum length that will not result in padding. The remaining data is buffered for subsequent calls to encode(). @param input: string to encode as Base64 @type input: string @param final: force all data to be encoded, possibly resulting in padding #type final: boolean @return: (Base64 representation of input, length consumed) @rtype: tuple R(RRR?R%tbuffer(R RRR((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR?s cCs>d}|jr6|j|j|jt}d|_n|dS(s Flush this encoder, returning any buffered data @return: Base64 representation of buffered data @rtype: string RUi(RUi(RRR0tTrue(R R((s0/usr/lib/python2.7/site-packages/keyczar/util.pytflush/s   (RRRRtFalseR?R(((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRs  tIncrementalBase64WSStreamWritercBs8eZdZddZdZdZddZRS(s Web-safe Base64 encodes a stream in multiple steps to an output stream. Each step bar the final one will be sized to ensure no Base64 padding is required. Any unencoded data outside this optimal size will be buffered and output when flush() is called. tstrictcCs/tt|j||td||_dS(s Creates an IncrementalBase64WSStreamWriter instance. @param stream: a file-like object open for writing (binary) data. @param errors: required error handling scheme The reader may use different error handling schemes by providing the errors keyword argument. These parameters are predefined: 'strict' - raise a ValueError (or a subclass) 'ignore' - ignore the character and continue with the next 'replace'- replace with a suitable replacement character 'xmlcharrefreplace' - Replace with the appropriate XML character reference. 'backslashreplace' - Replace with backslashed escape sequences (only for encoding). R0N(RRRRR(R tstreamR0((s0/usr/lib/python2.7/site-packages/keyczar/util.pyREscCs!|jtt|jdS(s Flushes and closes the stream N(RRRR(R ((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR]s cCs9|jj}|r5|jj||jjndS(sK Flush this stream, writing any buffered data to the output stream N(RRRR(R R((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRbscCs|jj|S(s  Base64 Encodes input and returns the resulting object. @param input: string to encode as Base64 @type input: string @param errors: required error handling scheme (see __init__) @return: Base64 representation of input. @rtype: string (RR?(R RR0((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR?ks (RRRRRRR?(((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR<s    t"BufferedIncrementalBase64WSDecodercBs,eZdZdZedZdZRS(s Web-safe Base64 decodes an input in multiple steps. Each step bar the final one will be sized to a length so that no Base64 padding is required. Any undecoded data outside this optimal size will be buffered. cCs=|sdt|d}n t|}t|| |fS(s Decodes input and returns the resulting object, buffering any data that is beyond the optimal no-padding length unless final is True Implementation of abstract method in parent. @param input: string to decode from Base64 @type input: string @param errors: required error handling scheme (see IncrementalBase64WSStreamReader) @param final: force all data to be decoded, possibly resulting in padding #type final: boolean @return: (plaintext version of input, length consumed) @rtype: tuple i(R%R/(R RR0Rt len_to_read((s0/usr/lib/python2.7/site-packages/keyczar/util.pyt_buffer_decodes cCs.tt|j|d|}|t|fS(s Decodes input and returns the resulting object. Note that unless final is True the returned data may not decode all the supplied input as it uses the maximum length that would not require padding. The remaining data is buffered for subsequent calls to decode(). @param input: string to decode from Base64 @type input: string @param final: force all data to be decoded, possibly resulting in padding #type final: boolean @return: plaintext representation of input. @rtype: string R(RRR.R%(R RRR((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR.s cCs>d}|jr6|j|j|jt}d|_n|dS(s Flush this decoder, returning any buffered data @return: plaintext representation of buffered data @rtype: string RUi(RUi(RRR0R(R R((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRs   (RRRRRR.R(((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRys  tIncrementalBase64WSStreamReadercBs8eZdZddZddedZddZRS(s Web-safe Base64 decodes a stream in multiple steps. Each step bar the final one will be sized to a length so that no Base64 padding is required. Any undecoded data outside this optimal size will be buffered and decoded on a final call to read(). RcCs/tt|j||td||_dS(s Creates an IncrementalBase64WSStreamReader instance. @param stream: a file-like object open for reading (binary) data. @param errors: required error handling scheme The reader may use different error handling schemes by providing the errors keyword argument. These parameters are predefined: 'strict' - raise a ValueError (or a subclass) 'ignore' - ignore the character and continue with the next 'replace'- replace with a suitable replacement character 'xmlcharrefreplace' - Replace with the appropriate XML character reference. 'backslashreplace' - Replace with backslashed escape sequences (only for encoding). R0N(RRRRR(R RR0((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRsic CsF|jr*dj|j|_d|_nd}xtr|dkr}|dkra|jrzPqzqt|j|krPqnt|j|krPny4|dkr|jj}n|jj|}Wntk rd}nX|dk r3|j |}y|j ||j \}}Wnht k r}|r|j ||j |j \}}|jt} t| dkrqqnX|||_ |j|7_|sPqq3q3W|dkr|j} d|_n|j| } |j||_| r|dkrd} n| rB|dkrB|dkrB|jj} qBn| S(s Decodes data from the input stream and returns the resulting object. @param chars: the number of characters to read from the stream. read() will never return more than chars characters, but it might return less, if there are not enough characters available. Will return None if the underlying stream does i.e. is non-blocking and no data is available. @type chars: integer @param size: indicates the approximate maximum number of bytes to read from the stream for decoding purposes. The decoder can modify this setting as appropriate. The default value -1 indicates to read and decode as much as possible. size is intended to prevent having to decode huge files in one step. @type size: integer @param firstline: if firstline is true, and a UnicodeDecodeError happens after the first line terminator in the input only the first line will be returned, the rest of the input will be kept until the next call to read(). @type firstline: boolean @return: plaintext representation of input. Returns an empty string when the end of the input data has been reached. @rtype: string RUiiN(t linebufferRVt charbuffertNoneRR%RRRt bytebufferR.R0tUnicodeDecodeErrortstartRRR( R tsizeRlt firstlinetnewdataRtnewcharst decodedbytestexctlinesR((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRsZ#           "         cCs|jj|S(s Decodes Base64 input and returns the resulting object. @param input: string to decode from Base64 @type input: string @param errors: required error handling scheme (see __init__) @return: plaintext representation of input. @rtype: string (RR.(R RR0((s0/usr/lib/python2.7/site-packages/keyczar/util.pyR.Bs (RRRRRRR.(((s0/usr/lib/python2.7/site-packages/keyczar/util.pyRs fcsRitjfd}|jrNdj|jdg|_n|S(s| General-purpose memoization decorator. Handles functions with any number of arguments, including keyword arguments. csKtj|t|jf}|krC|||=1 paths joined using the o/s tbackendsRUN( R~RRVtdirnamet__file__RtenvirontgettBACKEND_PATHS_ENV_VARtsplittpathsep(Rt xtra_pathsR((s0/usr/lib/python2.7/site-packages/keyczar/util.pytImportBackendsts ! (XRRRtcodecsRRR~RRRthashlibRt ImportErrorRtioRRtpyasn1.codec.derRRt pyasn1.typeRR0tabcRRRttypet digest_sizeRtObjectIdentifierR2R3R4R5t SHA1RSA_OIDtSHA1_OIDtDEFAULT_STREAM_BUFF_SIZERR*R,R<RCRDRJRNRORRRTR_RFRKR`RcRmRqRtRyRvR}RRXRRRARR/RtSTRING_SPECIFIERRRRRRRRtBufferedIncrementalEncoderRt StreamWritertobjectRtBufferedIncrementalDecoderRt StreamReaderRRRR(((s0/usr/lib/python2.7/site-packages/keyczar/util.pyts                                            D=B