Ejemplo n.º 1
0
    def Verify(self, data, sig):
        """
    Verifies whether the signature corresponds to the given data. This is a
    stanard signature (i.e. HMAC-SHA1, RSA-SHA1, DSA-SHA1) that contains no
    version information, so this will try to verify with each key in a keyset.

    @param data: message that has been signed with sig
    @type data: string

    @param sig: Base64 string formatted as Header|Signature
    @type sig: string

    @return: True if sig corresponds to data, False otherwise.
    @rtype: boolean
    """
        sig_bytes = util.Base64WSDecode(sig)

        for version in self.versions:
            key = self._keys[version]
            # Try to verify with each key
            result = key.Verify(util.RawBytes(data), sig_bytes)
            if result:
                return True

        # None of the keys verified the signature
        return False
Ejemplo n.º 2
0
    def AttachedVerify(self, signed_data, nonce):
        """
    Verifies the signature in the signed blob corresponds to the data
    in the signed blob and the provided nonce, and returns the data.

    @param signed_data: the blob, produced by AttachedSign, containing
    data and signature.
    @type signed_data: string

    @param nonce: Nonce string that was used when the signature was
    generated.  If the provided value doesn't match, verification will
    fail.
    @type sig: string

    @return: If verification succeeds, the extracted data will be returned,
    otherwise, None
    @rtype: string
    """
        decoded_data = util.Base64WSDecode(signed_data)
        reader = util.BytesReader(decoded_data)
        writer, getoutput = util.BytesWriter()
        nonce = util.RawBytes(nonce)
        if self.AttachedVerifyIO(reader, writer, nonce):
            return util.RawString(getoutput())
        return None
Ejemplo n.º 3
0
 def __simulateReflow(self, data):
     """Helper to simulate reflowing of data"""
     endings = [b'\n', b'\r', b'\r\n']
     reflowed_data = b''
     bdata = util.RawBytes(data)
     for c in [bdata[x:x + 5] for x in range(0, len(bdata), 5)]:
         d = bytes(bytearray(c))
         reflowed_data += random.choice(endings) + d
     return reflowed_data
Ejemplo n.º 4
0
    def AttachedSign(self, data, nonce):
        """
    Sign given data and nonce and return a blob containing both data and
    signature

    For message M, and nonce N, outputs Header|len(M)|M|Sig(Header|M|N).

    @param data: message to be signed
    @type data: string

    @param nonce: nonce to be included in the signature
    @type nonce: string

    @return: signature on the data encoded as a Base64 string
    @rtype: string
    """
        return util.Base64WSEncode(
            self.primary_key.Header() +
            util.PackByteArray(util.RawBytes(data)) +
            self.__InternalSign(util.RawBytes(data), util.RawBytes(nonce)))
Ejemplo n.º 5
0
    def testBadAesCiphertextsStream(self):
        crypter = keyczar.Crypter.Read(os.path.join(TEST_DATA, "aes"))
        ciphertext = util.Base64WSDecode(crypter.Encrypt(self.input_data))
        bad = util.Base64WSEncode(b'0x00')
        char = bytes([bytearray(ciphertext)[2] ^ 44])
        ciphertext = util.Base64WSEncode(ciphertext[:2] + char +
                                         ciphertext[3:])

        try:
            stream = io.BytesIO(util.RawBytes(bad))
            decryption_stream = crypter.CreateDecryptingStreamReader(stream)
            self.__readFromStream(decryption_stream)
        except errors.ShortCiphertextError:
            pass

        try:
            stream = io.BytesIO(util.RawBytes(ciphertext))
            decryption_stream = crypter.CreateDecryptingStreamReader(stream)
            self.__readFromStream(decryption_stream)
        except errors.KeyNotFoundError:
            pass
Ejemplo n.º 6
0
 def testSimulateDecrypter(self):
   enc_data = util.RawBytes(
   'AJehaFGwoOrkzpDCnF1zqIi721eCOMYWRmLyRyn3hxyhh_mYwpnDN6jKN057gr5lz' \
           'APFYhq9zoDwFMaGMEipEl__ECOZGeaxWw')
   expected_result = util.Base64WSDecode(enc_data)
   stream = util.IncrementalBase64WSStreamReader(io.BytesIO(enc_data))
   result = stream.read(5)
   result += stream.read(15)
   read_data = True
   while read_data:
     read_data = stream.read(4096)
     result += read_data
   self.assertEqual(result, expected_result)
Ejemplo n.º 7
0
    def Sign(self, data):
        """
    Sign given data and return corresponding signature.

    For message M, outputs the signature as Header|Sig(Header.M).

    @param data: message to be signed
    @type data: string

    @return: signature on the data encoded as a Base64 string
    @rtype: string
    """
        return util.Base64WSEncode(self.primary_key.Header() +
                                   self.__InternalSign(util.RawBytes(data)))
Ejemplo n.º 8
0
    def Sign(self, data):
        """
    Sign given data and return corresponding signature. This signature
    contains no header or version information.

    For message M, outputs the signature as Sig(M).

    @param data: message to be signed
    @type data: string

    @return: signature on the data encoded as a Base64 string
    @rtype: string
    """
        signing_key = self.primary_key
        if signing_key is None:
            raise errors.NoPrimaryKeyError()
        return util.Base64WSEncode(signing_key.Sign(util.RawBytes(data)))
Ejemplo n.º 9
0
    def testStreamDecryptHandlesIOModuleBlockingExceptionRaised(self):
        """
    Test for input streams that conform to the blocking I/O module spec wrt
    buffered blocking, i.e. if the underlying raw stream is in non blocking-mode,
    a BlockingIOError is raised indicate no data available, but not EOF
    """
        crypter = keyczar.Crypter.Read(os.path.join(TEST_DATA, 'aes'))
        ciphertext = crypter.Encrypt(self.input_data)

        class PseudoBlockingStream(object):
            """
      A 'stream' that raises BlockingIOError every 2nd call to read() to
      simultate buffered blocking
      """
            def __init__(self, string):
                self.current_posn = 0
                self.string = string
                self.raise_exception = True

            def read(self, size=-1):
                result = None
                start = self.current_posn
                if not self.raise_exception:
                    if size < 0:
                        end = size
                        self.current_posn = len(self.string)
                    else:
                        end = (start + size)
                        self.current_posn = end
                    result = self.string[start:end]
                else:
                    if start > len(self.string):
                        result = b''
                    else:
                        self.raise_exception = False
                        raise io.BlockingIOError(1, 'Dummy error',
                                                 self.current_posn)

                self.raise_exception = not self.raise_exception
                return result

        decryption_stream = crypter.CreateDecryptingStreamReader(
            PseudoBlockingStream(util.RawBytes(ciphertext)))
        result = self.__readFromStream(decryption_stream, len_to_read=-1)
        self.assertEqual(self.input_data, result)
Ejemplo n.º 10
0
    def Verify(self, data, sig):
        """
    Verifies whether the signature corresponds to the given data.

    @param data: message that has been signed with sig
    @type data: string

    @param sig: Base64 string formatted as Header|Signature
    @type sig: string

    @return: True if sig corresponds to data, False otherwise.
    @rtype: boolean
    """
        sig_bytes = util.Base64WSDecode(sig)
        if len(sig_bytes) < constants.HEADER_SIZE:
            raise errors.ShortSignatureError(len(sig_bytes))
        return self.__InternalVerify(sig_bytes[:constants.HEADER_SIZE],
                                     sig_bytes[constants.HEADER_SIZE:],
                                     util.RawBytes(data))
Ejemplo n.º 11
0
    def testStreamDecryptHandlesIOModuleBlockingNoneReturned(self):
        """
    Test for input streams that conform to the blocking I/O module spec, i.e.
    read() returns None to indicate no data available, but not EOF
    """
        crypter = keyczar.Crypter.Read(os.path.join(TEST_DATA, 'aes'))
        ciphertext = crypter.Encrypt(self.input_data)

        class PseudoBlockingStream(object):
            """
      A 'stream' that blocks every 2nd call to read() to simultate blocking i/o
      """
            def __init__(self, string):
                self.current_posn = 0
                self.string = string
                self.return_none = False

            def read(self, size=-1):
                result = None
                start = self.current_posn
                if not self.return_none:
                    if size < 0:
                        end = size
                        self.current_posn = len(self.string)
                    else:
                        end = (start + size)
                        self.current_posn = end
                    result = self.string[start:end]
                else:
                    if start > len(self.string):
                        result = b''

                self.return_none = not self.return_none
                return result

        decryption_stream = crypter.CreateDecryptingStreamReader(
            PseudoBlockingStream(util.RawBytes(ciphertext)))
        result = self.__readFromStream(decryption_stream, len_to_read=-1)
        self.assertEqual(self.input_data, result)
Ejemplo n.º 12
0
    def __testStandardEncryptAndStreamDecrypt(self, subdir, input_data,
                                              stream_buffer_size, len_to_read,
                                              stream_source):
        crypter = keyczar.Crypter.Read(os.path.join(TEST_DATA, subdir))
        ciphertext = crypter.Encrypt(input_data)
        ciphertext_stream = io.BytesIO(util.RawBytes(ciphertext))

        if stream_source is None:
            decoder = None
            ciphertext_stream = io.BytesIO(util.Base64WSDecode(ciphertext))
        else:
            decoder = util.IncrementalBase64WSStreamReader
        decryption_stream = crypter.CreateDecryptingStreamReader(
            ciphertext_stream, decoder=decoder, buffer_size=stream_buffer_size)
        plaintext = self.__readFromStream(decryption_stream, len_to_read)
        self.assertEqual(
            len(input_data), len(plaintext),
            'Wrong length for buffer:%d, read len:%d' %
            (stream_buffer_size, len_to_read))
        self.assertEqual(
            input_data, plaintext, 'Not equals for buffer:%d, read len:%d' %
            (stream_buffer_size, len_to_read))
Ejemplo n.º 13
0
    def Sign(self, data, expire_date):
        """
    Sign given data and return corresponding signature.

    For message M, outputs the signature as Header|Sig(Header.M).

    @param data: message to be signed
    @type data: string

    @param expire_date: datetime when signature expires
    @type expire_date: datetime (UTC)

    @return: signature on the data encoded as a Base64 string
    @rtype: string
    """

        expire_milli = util.UnixTimeMilliseconds(expire_date)
        expire_bytes = util.LongLongToBytes(expire_milli)

        return util.Base64WSEncode(self.primary_key.Header() + expire_bytes +
                                   self.__InternalSign(expire_bytes +
                                                       util.RawBytes(data)))
Ejemplo n.º 14
0
    def Encrypt(self, data, encoder=util.Base64WSEncode):
        """
    Encrypt the data and return the ciphertext.

    @param data: message to encrypt
    @type data: string

    @param encoder: function to perform final encoding. Defaults to Base64, use
    None for no encoding.
    @type encoder: function

    @return: ciphertext, by default Base64 encoded
    @rtype: string

    @raise NoPrimaryKeyError: if no primary key can be found to encrypt
    """

        reader = io.BufferedReader(io.BytesIO(util.RawBytes(data)))
        output = io.BytesIO()
        writer = io.BufferedWriter(output)
        self.EncryptIO(reader, writer)
        ciphertext = output.getvalue()
        return encoder(ciphertext) if encoder else ciphertext
Ejemplo n.º 15
0
 def __testRead(self, input_data, expected_result):
   for size in [1, 5, 4096, 99999, -1]:
     stream = util.IncrementalBase64WSStreamReader(io.BytesIO(util.RawBytes(input_data)))
     self.assertEqual(util.RawString(self.__readStream(stream, size)), util.RawString(expected_result))