------------------------------------------------------------ revno: 310 committer: Scott Moser branch nick: trunk timestamp: Mon 2010-09-20 09:42:56 -0400 message: fix transient 'Odd-length string' error in euca-bundle-image The problem was that the euca2ools/__init__.py was doing: iv = (hex(BN.rand(16 * 8,top=0)))[2:34].replace('L','c') then unhexlify(iv) But BN.rand(16*8) is not guaranteed to return a number that is represented by 32 hex digits. I suspect that the .replace('L','c') was added to get around this issue. By specifying 'top=0' in the BN.rand call, we guarantee that the number will have the top bit set. I've ran the following snippet past i=40,000,000 . Without the fix in place I never saw it run past 1000. while True: i=i+1 try: uh = unhexlify((hex(BN.rand(17 * 8,top=0)))[4:36]) except KeyboardInterrupt: print "tried %i times, no failures yet" % i except: print "found failure, i=%s, iv=%s len=(%s)" % (i,iv,len(iv)) sys.exit(1) diff: === modified file 'euca2ools/euca2ools/__init__.py' --- euca2ools/euca2ools/__init__.py 2010-09-03 16:18:03 +0000 +++ euca2ools/euca2ools/__init__.py 2010-09-20 13:42:56 +0000 @@ -711,10 +711,13 @@ print 'Encrypting image' enc_file = '%s.part' % file.replace('.tar.gz', '') - key = hex(BN.rand(16 * 8))[2:34].replace('L', 'c') + # get 17 bytes of randomness with top bit a '1'. + # convert to a hex string like '0x<34 hex chars>L' + # then take the last 32 of the hex digits, giving 32 random hex chars + key = hex(BN.rand(17 * 8,top=0))[4:36] if self.debug: print 'Key: %s' % key - iv = hex(BN.rand(16 * 8))[2:34].replace('L', 'c') + iv = hex(BN.rand(17 * 8,top=0))[4:36] if self.debug: print 'IV: %s' % iv