| 634 | return derivedKey |
| 635 | |
| 636 | def decrypt(self, key, entropy = None): |
| 637 | keyHash = SHA1.new(key).digest() |
| 638 | sessionKey = HMAC.new(keyHash, self['Salt'], ALGORITHMS_DATA[self['HashAlgo']][1]) |
| 639 | if entropy is not None: |
| 640 | sessionKey.update(entropy) |
| 641 | |
| 642 | sessionKey = sessionKey.digest() |
| 643 | |
| 644 | # Derive the key |
| 645 | derivedKey = self.deriveKey(sessionKey) |
| 646 | |
| 647 | cipher = ALGORITHMS_DATA[self['CryptAlgo']][1].new(derivedKey[:ALGORITHMS_DATA[self['CryptAlgo']][0]], |
| 648 | mode=ALGORITHMS_DATA[self['CryptAlgo']][2], iv=b'\x00'*ALGORITHMS_DATA[self['CryptAlgo']][3]) |
| 649 | cleartext = unpad(cipher.decrypt(self['Data']), ALGORITHMS_DATA[self['CryptAlgo']][1].block_size) |
| 650 | |
| 651 | # Now check the signature |
| 652 | |
| 653 | # ToDo Fix this, it's just ugly, more testing so we can remove one |
| 654 | toSign = (self.rawData[20:len(self)-len(self['Sign'])-4]) |
| 655 | |
| 656 | # Calculate the different HMACKeys |
| 657 | keyHash2 = keyHash + b"\x00"*ALGORITHMS_DATA[self['HashAlgo']][1].block_size |
| 658 | ipad = bytearray([i ^ 0x36 for i in bytearray(keyHash2)][:ALGORITHMS_DATA[self['HashAlgo']][1].block_size]) |
| 659 | opad = bytearray([i ^ 0x5c for i in bytearray(keyHash2)][:ALGORITHMS_DATA[self['HashAlgo']][1].block_size]) |
| 660 | a = ALGORITHMS_DATA[self['HashAlgo']][1].new(ipad) |
| 661 | a.update(self['HMac']) |
| 662 | |
| 663 | hmacCalculated1 = ALGORITHMS_DATA[self['HashAlgo']][1].new(opad) |
| 664 | hmacCalculated1.update(a.digest()) |
| 665 | |
| 666 | if entropy is not None: |
| 667 | hmacCalculated1.update(entropy) |
| 668 | |
| 669 | hmacCalculated1.update(toSign) |
| 670 | |
| 671 | hmacCalculated3 = HMAC.new(keyHash, self['HMac'], ALGORITHMS_DATA[self['HashAlgo']][1]) |
| 672 | if entropy is not None: |
| 673 | hmacCalculated3.update(entropy) |
| 674 | |
| 675 | hmacCalculated3.update(toSign) |
| 676 | |
| 677 | if hmacCalculated1.digest() == self['Sign'] or hmacCalculated3.digest() == self['Sign']: |
| 678 | return cleartext |
| 679 | else: |
| 680 | return None |
| 681 | |
| 682 | class VAULT_ATTRIBUTE(Structure): |
| 683 | structure = ( |