Esempio n. 1
0
 def check_vectors(self, filename):
     mode = filename[:3].lower()
     fh = open("test_vectors/" + filename, "r")
     type = fh.readline().strip()[1:-1].lower()
     fh.readline()
     data = {}
     for line in fh:
         line = line.strip()
         if not line and data:
             key = b16decode(data["key"].encode(), True)
             iv = b16decode(data.get("iv", "").encode(), True)
             pt = b16decode(data["plaintext"].encode(), True)
             ct = b16decode(data["ciphertext"].encode(), True)
             cipher = Cipher(key=key, iv=iv or None, cipher="aes", mode=mode)
             if type == "encrypt":
                 res = cipher.encrypt(pt)
                 self.assertEqual(
                     res, ct, "%s #%s: %s != %s" % (filename, data["count"], b16encode(res), data["ciphertext"])
                 )
             data = {}
         if " = " not in line:
             continue
         k, v = line.lower().split(" = ")
         data[k] = v
     fh.close()
Esempio n. 2
0
 def check_openssl(self, cipher_name, keysize, mode):
     cipher_desc = Descriptor(cipher=cipher_name)
     for i in range(1, 2):
         key = os.urandom(keysize // 8)
         iv = os.urandom(cipher_desc.block_size)
         pt = os.urandom(i * 128 // 8)
         if cipher_name == "aes":
             cipher_spec = "aes-%d-%s" % (keysize, mode)
         elif cipher_name == "des":
             cipher_spec = "des-%s" % mode
         elif cipher_name == "blowfish":
             cipher_spec = "bf-%s" % mode
         proc = Popen(
             (
                 "openssl enc -e -%s -nopad -nosalt -K %s -iv %s"
                 % (cipher_spec, b16encode(key).decode(), b16encode(iv).decode())
             ).split(),
             stdin=PIPE,
             stdout=PIPE,
             stderr=PIPE,
         )
         out, err = proc.communicate(pt)
         self.assertFalse(err, err)
         cipher = Cipher(key=key, iv=iv, cipher=cipher_name, mode=mode)
         ct = cipher.encrypt(pt)
         self.assertEqual(
             ct,
             out,
             "%s %s %s: %s != %s" % (cipher_name, keysize, mode, b16encode(ct).decode(), b16encode(out).decode()),
         )
Esempio n. 3
0
 def check_openssl(self, cipher_name, keysize, mode):
     cipher_desc = Descriptor(cipher=cipher_name)
     for i in range(1, 2):
         key = os.urandom(keysize//8)
         iv = None if mode == 'ecb' else os.urandom(cipher_desc.block_size)
         pt = os.urandom(i * 128 // 8)
         if cipher_name == 'aes':
             cipher_spec = 'aes-%d-%s' % (keysize, mode)
         elif cipher_name == 'des':
             cipher_spec = 'des-%s' % mode
         elif cipher_name == 'blowfish':
             cipher_spec = 'bf-%s' % mode
         proc = Popen(('openssl enc -e -%s -nopad -nosalt -K %s -iv %s' %
             (cipher_spec, b16encode(key).decode(), b16encode(iv or b'\0').decode())).split(), stdin=PIPE, stdout=PIPE, stderr=PIPE)
         out, err = proc.communicate(pt)
         self.assertFalse(err, err)
         cipher = Cipher(key=key, iv=iv, cipher=cipher_name, mode=mode)
         ct = cipher.encrypt(pt)
         self.assertEqual(ct, out, '%s %s %s: %s != %s' % (cipher_name,
             keysize, mode, b16encode(ct).decode(), b16encode(out).decode()))
Esempio n. 4
0
 def check_vectors(self, filename):
     mode = filename[:3].lower()
     fh = open('test_vectors/' + filename, 'r')
     type = fh.readline().strip()[1:-1].lower()
     fh.readline()
     data = {}
     for line in fh:
         line = line.strip()
         if not line and data:
             key = b16decode(data['key'].encode(), True)
             iv  = b16decode(data.get('iv', '').encode(), True)
             pt  = b16decode(data['plaintext'].encode(), True)
             ct  = b16decode(data['ciphertext'].encode(), True)
             cipher = Cipher(key=key, iv=iv or None, cipher='aes', mode=mode)
             if type == 'encrypt':
                 res = cipher.encrypt(pt)
                 self.assertEqual(res, ct, '%s #%s: %s != %s' % (filename,
                     data['count'], b16encode(res), data['ciphertext']))
             data = {}
         if ' = ' not in line:
             continue
         k, v = line.lower().split(' = ')
         data[k] = v
     fh.close()
Esempio n. 5
0
def dumps(key, data, encrypt=True, add_time=True, nonce=16, max_age=None, extra={}, depends_on={}):
    """
    
    Basic example without encryption:
    
        >>> key = '0123456789abcdef'
    
        >>> encoded = dumps(key, 'abc123', encrypt=False)
        >>> encoded #doctest: +ELLIPSIS
        'abc123.n:...,s:...,t:...'
    
        >>> loads(key, encoded)
        'abc123'
    
    Basic example with encryption:
    
        >>> encoded = dumps(key, 'abc123')
        >>> encoded #doctest: +ELLIPSIS
        '....i:...,s:...'
    
        >>> loads(key, encoded)
        'abc123'
    
    It fails when modified:
    
        >>> loads(key, encoded + 'extra', strict=True)
        Traceback (most recent call last):
        ...
        ValueError: invalid signature
    
    We can add expiry times:
    
        >>> encoded = dumps(key, 'abc123', encrypt=False, max_age=3600)
        >>> encoded #doctest: +ELLIPSIS
        'abc123.n:...,s:...,t:...,x:...'
        
        >>> encoded = dumps(key, 'abc123', max_age=60)
        >>> loads(key, encoded)
        'abc123'
    
        >>> import mock
        >>> with mock.patch('time.time', returns=time.time() + 3600):
        ...     loads(key, encoded, strict=True)
        Traceback (most recent call last):
        ...
        ValueError: signature has expired
    
    Adding dependant data:
    
        >>> encoded = dumps(key, 'abc123', encrypt=False, depends_on=dict(key='value'))
        >>> encoded #doctest: +ELLIPSIS
        'abc123.n:...,s:...,t:...'
    
        >>> loads(key, encoded, strict=True)
        Traceback (most recent call last):
        ...
        ValueError: invalid signature
        
        >>> loads(key, encoded, depends_on=dict(key='value'))
        'abc123'
    
    Unicode:
    
        >>> encoded = dumps(key, u'¡™£¢∞§¶•')
        >>> restored = loads(key, encoded)
        >>> type(restored) is unicode
        True
        >>> restored == u'¡™£¢∞§¶•'
        True
        
        >>> data = u''.join(unichr(i) for i in range(512))
        >>> encoded = dumps(key, data)
        >>> restored = loads(key, encoded)
        >>> type(restored) is unicode
        True
        >>> restored == data
        True
    
    Repr-able types:
    
        >>> encoded = dumps(key, range(10), encrypt=False)
        >>> encoded # doctest: +ELLIPSIS
        '$5b0,1,2,3,4,5,6,7,8,9$5d.f:r,n:...,s:...,t:...'
        >>> loads(key, encoded)
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        
        >>> encoded = dumps(key, {'list': [True, False], ('tuple', 'keys'): {'sub': 1234}}, encrypt=False)
        >>> encoded # doctest: +ELLIPSIS
        "$7b'list':$5bTrue,False$5d,('tuple','keys'):$7b'sub':1234$7d$7d.f:r,n:...,s:...,t:..."
        >>> loads(key, encoded)
        {('tuple', 'keys'): {'sub': 1234}, 'list': [True, False]}
    
    Pickle-able types:
    
        >>> encoded = dumps(key, set('hello'), encrypt=False)
        >>> encoded # doctest: +ELLIPSIS
        'gAJjX19idWlsdGluX18Kc2V0CnEAXXEBKFUBaHECVQFlcQNVAWxxBFUBb3EFZYVxBlJxBy4.f:p,n:...,s:...,t:...'
        >>> loads(key, encoded)
        set(['h', 'e', 'l', 'o'])
        
        
        
    """
    
    if encrypt:
        inner_meta = dict(extra)
        outer_meta = {}    
        nonce = max(0, nonce - 16)
    else:
        inner_meta = outer_meta = dict(extra)
    
    if add_time:
        inner_meta[CREATION_TIME_KEY] = encode_int(time.time())
    if max_age:
        inner_meta[EXPIRATION_TIME_KEY] = encode_int(time.time() + max_age)
    
    # Deal with different types.
    if type(data) is bytes:
        pass
    elif type(data) is unicode:
        data = data.encode('utf8')
        inner_meta[DATA_FORMAT_KEY] = 'u'
    else:
        try:
            data = deterministic_repr.dumps(data, minimize=True)
            inner_meta[DATA_FORMAT_KEY] = 'r'
        except TypeError:
            data = pickle.dumps(data, protocol=2)
            inner_meta[DATA_FORMAT_KEY] = 'p'
    
    # Try compressing the data. Only use the compressed form if requested or
    # there is enough of a savings to justify it. If we are not encrypting then
    # the compression must also do better than the base64 encoding that would
    # be required.
    data_compressed = zlib.compress(data)
    if len(data) / len(data_compressed) > (1 if encrypt else 4 / 3):
        data = data_compressed
        inner_meta[COMPRESSION_FLAG_KEY] = '1'

    if encrypt:

        # Pack up the inner payload.
        data = encode_seal(data, inner_meta)
        
        # Encrypt it.
        iv = os.urandom(16)
        outer_meta[ENCRYPTION_IV_KEY] = encode_binary(iv)
        cipher = tomcrypt.cipher.aes(key, iv, mode='ctr')
        data = cipher.encrypt(data)
    
    if encrypt or COMPRESSION_FLAG_KEY in inner_meta or inner_meta.get(DATA_FORMAT_KEY) == 'p':
        
        # Make it transport safe.
        data = encode_binary(data)
    
    # Sign it.
    outer_meta = sign(key, data, add_time=False, nonce=nonce, hash=hashlib.sha256, extra=outer_meta, depends_on=depends_on)
    
    # Pack up outer payload.
    return encode_seal(data, outer_meta)