Esempio n. 1
0
    def buildCorruptWallet(self, walletPath):
        crpWlt = PyBtcWallet()
        crpWlt.createNewWallet(walletPath,
                               securePassphrase='testing',
                               doRegisterWithBDM=False)
        #not registering with the BDM, have to fill the wallet address pool manually
        crpWlt.fillAddressPool(100)

        #grab the last computed address
        lastaddr = crpWlt.addrMap[crpWlt.lastComputedChainAddr160]

        #corrupt the pubkey
        PubKey = hex_to_binary(
            '0478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455'
        )
        lastaddr.binPublicKey65 = SecureBinaryData(PubKey)
        crpWlt.addrMap[crpWlt.lastComputedChainAddr160] = lastaddr

        crpWlt.fillAddressPool(200)

        #insert a gap and inconsistent encryption
        newAddr = PyBtcAddress()
        newAddr.chaincode = lastaddr.chaincode
        newAddr.chainIndex = 250
        PrivKey = hex_to_binary(
            'e3b0c44298fc1c149afbf4c8996fb92427ae41e5978fe51ca495991b7852b855')
        newAddr.binPrivKey32_Plain = SecureBinaryData(PrivKey)
        newAddr.binPublicKey65 = CryptoECDSA().ComputePublicKey( \
                                                  newAddr.binPrivKey32_Plain)
        newAddr.addrStr20 = newAddr.binPublicKey65.getHash160()
        newAddr.isInitialized = True

        crpWlt.addrMap[newAddr.addrStr20] = newAddr
        crpWlt.lastComputedChainAddr160 = newAddr.addrStr20
        crpWlt.fillAddressPool(250)

        lastAddr = crpWlt.addrMap[crpWlt.lastComputedChainAddr160]
        PrivKey = hex_to_binary(
            'e3b0c44298fc1c149afbf4c8996fb92427ae41e5978fe51ca495991b00000000')
        lastAddr.binPrivKey32_Plain = SecureBinaryData(PrivKey)
        lastAddr.binPublicKey65 = CryptoECDSA().ComputePublicKey( \
                                                  lastAddr.binPrivKey32_Plain)
        lastAddr.keyChanged = True
        crpWlt.kdfKey = crpWlt.kdf.DeriveKey(SecureBinaryData('testing'))
        lastAddr.lock(secureKdfOutput=crpWlt.kdfKey)
        lastAddr.useEncryption = True

        crpWlt.fillAddressPool(350)

        #TODO: corrupt a private key
        #break an address entry at binary level
        return crpWlt.uniqueIDB58
Esempio n. 2
0
def extractSignedDataFromVersionsDotTxt(wholeFile, doVerify=True):
    """
   This method returns a pair: a dictionary to lookup link by OS, and
   a formatted string that is sorted by OS, and re-formatted list that
   will hash the same regardless of original format or ordering
   """

    msgBegin = wholeFile.find('# -----BEGIN-SIGNED-DATA-')
    msgBegin = wholeFile.find('\n', msgBegin + 1) + 1
    msgEnd = wholeFile.find('# -----SIGNATURE---------')
    sigBegin = wholeFile.find('\n', msgEnd + 1) + 3
    sigEnd = wholeFile.find('# -----END-SIGNED-DATA---')

    MSGRAW = wholeFile[msgBegin:msgEnd]
    SIGHEX = wholeFile[sigBegin:sigEnd].strip()

    if -1 in [msgBegin, msgEnd, sigBegin, sigEnd]:
        LOGERROR('No signed data block found')
        return ''

    if doVerify:
        Pub = SecureBinaryData(hex_to_binary(ARMORY_INFO_SIGN_PUBLICKEY))
        Msg = SecureBinaryData(MSGRAW)
        Sig = SecureBinaryData(hex_to_binary(SIGHEX))
        isVerified = CryptoECDSA().VerifyData(Msg, Sig, Pub)

        if not isVerified:
            LOGERROR('Signed data block failed verification!')
            return ''
        else:
            LOGINFO('Signature on signed data block is GOOD!')

    return MSGRAW
Esempio n. 3
0
def verifyZipSignature(outerZipFilePath):
    result = MODULE_ZIP_STATUS.Invalid
    try:
        dataToSign = None
        signature = None
        outerZipFile = ZipFile(outerZipFilePath)
        # look for a zip file in the name list.
        # There should only be 2 files in this zip:
        #    The inner zip file and the sig file
        if len(outerZipFile.namelist()) == 3:
            dataToSign = sha256(
                sha256(outerZipFile.read(INNER_ZIP_FILENAME)) +
                sha256(outerZipFile.read(PROPERTIES_FILENAME)))
            signature = outerZipFile.read(SIGNATURE_FILENAME)

        if dataToSign and signature:
            """
         Signature file contains multiple lines, of the form "key=value\n"
         The last line is the hex-encoded signature, which is over the 
         source code + everything in the sig file up to the last line.
         The key-value lines may contain properties such as signature 
         validity times/expiration, contact info of author, etc.
         """
            dataToSignSBD = SecureBinaryData(dataToSign)
            sigSBD = SecureBinaryData(hex_to_binary(signature.strip()))
            publicKeySBD = SecureBinaryData(
                hex_to_binary(ARMORY_INFO_SIGN_PUBLICKEY))
            result = MODULE_ZIP_STATUS.Valid if CryptoECDSA().VerifyData(dataToSignSBD, sigSBD, publicKeySBD) else \
                     MODULE_ZIP_STATUS.Unsigned
    except:
        # if anything goes wrong an invalid zip file indicator will get returned
        pass
    return result
Esempio n. 4
0
 def makePubKey(self, byte):
    """
    The input byte will be repeated 32 times, then treated as the x-value of 
    a compressed pubkey.  Uncompress it to get a real pubkey.  We do this so
    that we have a valid public key for our tests, in which the validity of
    our 65-byte keys are checked
    """
    sbd33 = SecureBinaryData('\x02' + byte*32)
    return CryptoECDSA().UncompressPoint(sbd33).toBinStr()
Esempio n. 5
0
def signZipFile(zipFilePath, propertiesDictionary=None):
    if propertiesDictionary:
        # Create an empty properties file
        pass
    # if it's a string treat it like a file name and open it
    # else if ti's a dictionary save it to a file and use that.

    # Read the contents of the Zip File and the properties file
    zipFileData = None
    propertiesFileData = None
    dataToSign = sha256(sha256(zipFileData) + sha256(propertiesFileData))
    dataToSignSBD = SecureBinaryData(dataToSign)
    # get the privKeySBD
    privKeySBD = None
    signature = CryptoECDSA().SignData(dataToSignSBD, privKeySBD,
                                       ENABLE_DETSIGN)
Esempio n. 6
0

sys.argv.append('--nologging')

INIT_VECTOR = '77'*16
TEST_ADDR1_PRIV_KEY_ENCR1 = '500c41607d79c766859e6d9726ef1ea0fdf095922f3324454f6c4c34abcb23a5'
TEST_ADDR1_PRIV_KEY_ENCR2 = '7966cf5886494246cc5aaf7f1a4a2777cd6126612e7029d79ef9df47f6d6927d'
TEST_ADDR1_PRIV_KEY_ENCR3 = '0db5c1e9a8d1ebc0525bdb534626033b948804a9a34871d67bf58a3df11d6888'
TEST_ADDR1_PRIV_KEY_ENCR4 = '5db1314a20ae9fc978477ab3fe16ab17b246d813a541ecdd4143fcf082b19407'

TEST_PUB_KEY1 = '046c35e36776e997883ad4269dcc0696b10d68f6864ae73b8ad6ad03e879e43062a0139095ece3bd653b809fa7e8c7d78ffe6fac75a84c8283d8a000890bfc879d'

# Create an address to use for all subsequent tests
PRIVATE_KEY = SecureBinaryData(hex_to_binary('aa'*32))
PRIVATE_CHECKSUM = PRIVATE_KEY.getHash256()[:4]
PUBLIC_KEY  = CryptoECDSA().ComputePublicKey(PRIVATE_KEY)
ADDRESS_20  = PUBLIC_KEY.getHash160()

TEST_BLOCK_NUM = 100

# We pretend that we plugged some passphrases through a KDF
FAKE_KDF_OUTPUT1 = SecureBinaryData( hex_to_binary('11'*32) )
FAKE_KDF_OUTPUT2 = SecureBinaryData( hex_to_binary('22'*32) )

class PyBtcAddressTest(TiabTest):
   # TODO: This test needs more verification of the results.
   
   def testEncryptedAddress(self):


      # test serialization and unserialization of an empty PyBtcAddrss
Esempio n. 7
0
    def testWalletRecovery(self):
        #run recovery on broken wallet
        recThread = PyBtcWalletRecovery().RecoverWallet(self.corruptWallet, \
                                                        'testing', RECOVERMODE.Full, \
                                                        returnError = 'Dict')
        recThread.join()
        brkWltResult = recThread.output

        self.assertTrue(len(brkWltResult['sequenceGaps'])==1, \
                        "Sequence Gap Undetected")
        self.assertTrue(len(brkWltResult['forkedPublicKeyChain'])==3, \
                        "Address Chain Forks Undetected")
        self.assertTrue(len(brkWltResult['unmatchedPair'])==100, \
                        "Unmatched Priv/Pub Key Undetected")
        self.assertTrue(len(brkWltResult['misc'])==50, \
                        "Wallet Encryption Inconsistency Undetected")
        self.assertTrue(len(brkWltResult['importedErr'])==50, \
                        "Unexpected Errors Found")
        self.assertTrue(brkWltResult['nErrors']==204, \
                        "Unexpected Errors Found")

        #check obfuscated keys yield the valid key
        #grab root key
        badWlt = PyBtcWallet()
        badWlt.readWalletFile(self.corruptWallet, False, False)
        rootAddr = badWlt.addrMap['ROOT']

        SecurePassphrase = SecureBinaryData('testing')
        secureKdfOutput = badWlt.kdf.DeriveKey(SecurePassphrase)

        #HMAC Q
        rootAddr.unlock(secureKdfOutput)
        Q = rootAddr.binPrivKey32_Plain.toBinStr()

        nonce = 0
        while 1:
            hmacQ = HMAC256(Q, 'LogMult%d' % nonce)
            if binary_to_int(hmacQ, BIGENDIAN) < SECP256K1_ORDER:
                hmacQ = SecureBinaryData(hmacQ)
                break
            nonce = nonce + 1

        #Bad Private Keys
        import operator
        badKeys = [
            addrObj
            for addrObj in (sorted(badWlt.addrMap.values(),
                                   key=operator.attrgetter('chainIndex')))
        ]

        #run through obdsPrivKey
        for i in range(0, len(brkWltResult['privMult'])):
            obfsPKey = SecureBinaryData(
                hex_to_binary(brkWltResult['privMult'][i]))
            pKey = CryptoECDSA().ECMultiplyScalars(obfsPKey.toBinStr(), \
                                                   hmacQ.toBinStr())

            try:
                badKeys[i + 201].unlock(secureKdfOutput)
            except:
                continue

            self.assertTrue(binary_to_hex(pKey) == \
                            badKeys[i+201].binPrivKey32_Plain.toHexStr(), \
                            'key mult error')

        #run recovery on recovered wallet
        recThread = PyBtcWalletRecovery().RecoverWallet( \
                                   'armory_%s_RECOVERED.wallet' % self.wltID, \
                                   'testing', RECOVERMODE.Full, \
                                   returnError = 'Dict')
        recThread.join()
        rcvWltResult = recThread.output

        self.assertTrue(len(rcvWltResult['importedErr'])==50, \
                        "Unexpected Errors Found")
        self.assertTrue(rcvWltResult['nErrors']==50, \
                        "Unexpected Errors Found")
        self.assertTrue(len(rcvWltResult['negativeImports'])==99, \
                        "Missing neg Imports")


# Running tests with "python <module name>" will NOT work for any Armory tests
# You must run tests with "python -m unittest <module name>" or run all tests with "python -m unittest discover"
# if __name__ == "__main__":
#    unittest.main()