예제 #1
0
    def generateKeyAndSendNewInterest(self, probeTokenData):
        """
        """
        pib = self.keyChain.getPib()
        try:
            identity = pib.getIdentity(self.identityName)
            self.key = self.keyChain.createKey(identity)
        except Exception as e:
            identity = self.keyChain.createIdentityV2(self.identityName)
            self.key = identity.getDefaultKey()

        cert = CertificateV2()
        cert.setName(
            Name(self.key.getName()).append("cert-request").appendVersion(
                int(time.time())))
        cert.getMetaInfo().setType(ContentType.KEY)
        cert.getMetaInfo().setFreshnessPeriod(24 * 3600)
        cert.setContent(self.key.getPublicKey())

        signingInfo = SigningInfo(self.key)
        now = Common.getNowMilliseconds()
        signingInfo.setValidityPeriod(
            ValidityPeriod(now, now + 24 * 3600 * 1000.0))
        self.keyChain.sign(cert, signingInfo)
        #cert = self.keyChain.selfSign(self.key) # Does not work because validity period is greater than certserver default

        interestName = Name(self.caPrefix).append("CA").append("_NEW")
        newInterest = Interest(interestName)
        newInterest.setMustBeFresh(True)
        newInterest.setCanBePrefix(False)

        ecdhPub = "{}\n".format(self.ecdh.getBase64PubKey())
        ecdhCertReq = "{}\n".format(
            b64encode(cert.wireEncode().toBytes()).decode('utf-8'))
        probeToken = "{}\n".format(
            b64encode(probeTokenData.wireEncode().toBytes()).decode('utf-8'))

        jsonDump = json.dumps(
            {
                "ecdh-pub": ecdhPub,
                "cert-request": ecdhCertReq,
                "probe-token": probeToken
            },
            indent=4)
        print(jsonDump)
        newInterest.setApplicationParameters(jsonDump)
        newInterest.appendParametersDigestToName()

        self.keyChain.sign(newInterest, SigningInfo(self.key))

        print(newInterest.getName())

        self.face.expressInterest(newInterest, self.onNewData, self.onTimeout)
예제 #2
0
    def sendCommand(self, commandInterest, arguments, responseHandle):
        def onData(interest, data):
            # TODO: verify data
            responseHandle(commandInterest, Response(data))

        def onTimeout(interest):
            responseHandle(commandInterest, NdnCtrl.Timeout)

        interest = Interest(commandInterest)
        if arguments:
            interest.setParameters(json.dumps(arguments))
            interest.appendParametersDigestToName()
        # TODO: sign interest
        self.face_.expressInterest(interest, onData, onTimeout)
예제 #3
0
    def sendProbeInterest(self):
        probeInterest = Interest(
            Name(self.caPrefix).append("CA").append("_PROBE"))

        probeInterest.setMustBeFresh(True)
        probeInterest.setCanBePrefix(False)

        probeInterest.setApplicationParameters(
            json.dumps({"email": "*****@*****.**"}, indent=4))
        probeInterest.appendParametersDigestToName()

        print("Expressing interest: {}".format(probeInterest.getName()))
        self.face.expressInterest(probeInterest, self.onProbeData,
                                  self.onTimeout)
예제 #4
0
    async def retx_sync_interest(self):
        while self.running:
            interest = Interest(Name(self.prefix))
            interest.applicationParameters = self.encode(self.state)
            interest.appendParametersDigestToName()

            # await fetch_data_packet(self.face, interest)
            self.face.expressInterest(interest, self.on_sync_data)
            logging.info("retx")

            timeout = uniform(SYNC_INTERVAL_MIN, SYNC_INTERVAL_MAX)
            try:
                await asyncio.wait_for(self.sync_event.wait(), timeout)
            except asyncio.TimeoutError:
                pass
            self.sync_event.clear()
예제 #5
0
    def test_append_parameters_digest(self):
        name = Name("/local/ndn/prefix")
        interest = Interest(name)

        self.assertTrue(not interest.hasApplicationParameters())
        # No parameters yet, so it should do nothing.
        interest.appendParametersDigestToName()
        self.assertEqual("/local/ndn/prefix", interest.getName().toUri())

        applicationParameters = Blob(bytearray([ 0x23, 0x01, 0xC0 ]))
        interest.setApplicationParameters(applicationParameters)
        self.assertTrue(interest.hasApplicationParameters())
        interest.appendParametersDigestToName()
        self.assertEqual(name.size() + 1, interest.getName().size())
        self.assertTrue(interest.getName().getPrefix(-1).equals(name))
        SHA256_LENGTH = 32
        self.assertEqual(SHA256_LENGTH, interest.getName().get(-1).getValue().size())
        
        self.assertEqual(interest.getName().toUri(), "/local/ndn/prefix/" +
          "params-sha256=a16cc669b4c9ef6801e1569488513f9523ffb28a39e53aa6e11add8d00a413fc")
예제 #6
0
파일: gitsync.py 프로젝트: zjkmxy/GitSync
async def run(cmd: str):
    async def face_loop():
        nonlocal face, running
        while running:
            face.processEvents()
            await asyncio.sleep(0.01)

    running = True
    face = Face()
    keychain = KeyChain()
    face.setCommandSigningInfo(keychain, keychain.getDefaultCertificateName())
    event_loop = asyncio.get_event_loop()
    face_task = event_loop.create_task(face_loop())

    if cmd == "track-repo":
        if len(sys.argv) < 3:
            print("Usage:", sys.argv[0], "track-repo <repo>", file=sys.stderr)
        else:
            repo = sys.argv[2]
            interest = Interest(
                Name(LOCAL_CMD_PREFIX).append("track-repo").append(repo))
            data = await fetch_data_packet(face, interest)
            if isinstance(data, Data):
                result = struct.unpack("i", data.content.toBytes())[0]
                if result == 1:
                    print("OK")
                elif result == 2:
                    print("FAILED")
                else:
                    print("PENDING")
            else:
                print("error: Couldn't connect to",
                      interest.name.toUri(),
                      file=sys.stderr)
    elif cmd == "create-branch":
        if len(sys.argv) < 4:
            print("Usage:",
                  sys.argv[0],
                  "create-branch <repo> <branch>",
                  file=sys.stderr)
        else:
            repo = sys.argv[2]
            branch = sys.argv[3]
            interest = Interest(
                Name(LOCAL_CMD_PREFIX).append("create-branch").append(
                    repo).append(branch))
            data = await fetch_data_packet(face, interest)
            if isinstance(data, Data):
                result = struct.unpack("i", data.content.toBytes())[0]
                if result == 1:
                    print("OK")
                elif result == 2:
                    print("FAILED")
                else:
                    print("PENDING")
            else:
                print("error: Couldn't connect to",
                      interest.name.toUri(),
                      file=sys.stderr)
    elif cmd == "mount":
        if len(sys.argv) < 4:
            print("Usage:",
                  sys.argv[0],
                  "mount <repo> <branch>",
                  file=sys.stderr)
        else:
            repo = sys.argv[2]
            branch = sys.argv[3]
            interest = Interest(
                Name(LOCAL_CMD_PREFIX).append("mount").append(repo).append(
                    branch))
            data = await fetch_data_packet(face, interest)
            if isinstance(data, Data):
                print("Finished.")
            else:
                print("error: Couldn't connect to",
                      interest.name.toUri(),
                      file=sys.stderr)
    elif cmd == "unmount":
        if len(sys.argv) < 4:
            print("Usage:",
                  sys.argv[0],
                  "unmount <repo> <branch>",
                  file=sys.stderr)
        else:
            repo = sys.argv[2]
            branch = sys.argv[3]
            interest = Interest(
                Name(LOCAL_CMD_PREFIX).append("unmount").append(repo).append(
                    branch))
            data = await fetch_data_packet(face, interest)
            if isinstance(data, Data):
                print("Finished.")
            else:
                print("error: Couldn't connect to",
                      interest.name.toUri(),
                      file=sys.stderr)
    elif cmd == "commit":
        if len(sys.argv) < 6:
            print("Usage:",
                  sys.argv[0],
                  "commit <repo> <branch> <dest-branch> <message>",
                  file=sys.stderr)
        else:
            repo = sys.argv[2]
            branch = sys.argv[3]
            dest_branch = sys.argv[4]
            commit_msg = sys.argv[5]
            interest = Interest(Name(LOCAL_CMD_PREFIX).append("commit"))
            interest.applicationParameters = b'\x00'.join([
                repo.encode(),
                branch.encode(),
                dest_branch.encode(),
                commit_msg.encode()
            ])
            interest.appendParametersDigestToName()
            data = await fetch_data_packet(face, interest)
            if isinstance(data, Data):
                print("Finished.")
            else:
                print("error: Couldn't connect to",
                      interest.name.toUri(),
                      file=sys.stderr)
    else:
        print("Unrecognized command:", cmd, file=sys.stderr)

    running = False
    await face_task
예제 #7
0
    def onNewData(self, interest, data):
        """
        !! Again \n in public key??
        Got data:  {
            "ecdh-pub": "Aqxofe3QdsAfgbtS8TMxv31oudNKoSV307ci5gNXm88h\n",
            "salt": "12935684137560555161",
            "request-id": "14275252044236690531",
            "status": "0",
            "challenges": [
                {
                    "challenge-id": "Email"
                }
            ]
        }
        1. Verify data
        2. Derive shared secret
        """
        content = data.getContent()
        print("Got data: ", content)
        if not VerificationHelpers.verifyDataSignature(data, self.anchor):
            print("Cannot verify signature from: {}".format(self.caPrefix))
        else:
            print("Successfully verified data with hard-coded certificate")

        contentJson = json.loads(content.__str__())
        peerKeyBase64 = contentJson['ecdh-pub']
        self.status = contentJson['status']
        self.requestId = contentJson['request-id']
        self.challenges = contentJson['challenges']

        print(peerKeyBase64)

        serverPubKey = ec.EllipticCurvePublicKey.from_encoded_point(
            ec.SECP256R1(), b64decode(peerKeyBase64))

        shared_key = self.ecdh.private_key.exchange(ec.ECDH(), serverPubKey)
        derived_key = HKDF(algorithm=hashes.SHA256(),
                           length=32,
                           salt=contentJson['salt'].encode(),
                           info=b'handshake data',
                           backend=default_backend()).derive(shared_key)

        self.ecdh.derived_key = derived_key
        print(shared_key)
        for t in shared_key:
            print(t)

        challengeInterestName = Name(
            self.caPrefix).append("CA").append("_CHALLENGE").append(
                self.requestId)
        challengeInterest = Interest(challengeInterestName)
        challengeInterest.setMustBeFresh(True)
        challengeInterest.setCanBePrefix(False)

        # Encrypt the interest parameters
        challengeJson = json.dumps(
            {
                "selected-challenge": "Email",
                "email": "*****@*****.**"
            },
            indent=4)
        raw = self.pad(challengeJson, 16)
        print("raw", raw)
        iv = Random.new().read(AES.block_size)
        #cipher = AES.new(self.ecdh.derived_key, AES.MODE_CBC, iv)
        cipher = AES.new(shared_key, AES.MODE_CBC, iv)
        print(iv)
        xx = cipher.encrypt(raw)

        print(cipher.decrypt(xx))

        print("Printing iv:")
        for t in iv:
            print(t)

        encoder = TlvEncoder(256)
        saveLength = len(encoder)
        encoder.writeBlobTlv(632, iv)
        encoder.writeBlobTlv(630, cipher.encrypt(raw))
        #encoder.writeTypeAndLength(36, len(encoder) - saveLength)

        challengeInterest.setApplicationParameters(Blob(encoder.getOutput()))
        challengeInterest.appendParametersDigestToName()

        self.keyChain.sign(challengeInterest, SigningInfo(self.key))

        with open('foobar.tlv', 'wb') as f:
            f.write(challengeInterest.wireEncode().buf())
        self.face.expressInterest(challengeInterest, self.onChallengeData,
                                  self.onTimeout)
예제 #8
0
async def run(local_repo_path: str, repo_prefix: str):
    async def face_loop():
        nonlocal face, running
        while running:
            face.processEvents()
            await asyncio.sleep(0.01)

    options = {'cloning': False}
    running = True
    face = Face()
    keychain = KeyChain()
    face.setCommandSigningInfo(keychain, keychain.getDefaultCertificateName())
    event_loop = asyncio.get_event_loop()
    face_task = event_loop.create_task(face_loop())
    storage = FileStorage(local_repo_path)
    producer = GitProducer(face, Name(repo_prefix).append("objects"), storage)
    refs = []

    empty_cnt = 0
    while empty_cnt < 2 and running:
        cmd = sys.stdin.readline().rstrip("\n\r")
        # print("<<", cmd, file=sys.stderr)
        if cmd == "capabilities":
            print("push")
            print("fetch")
            print("option")
            print("")
            sys.stdout.flush()
        elif cmd.startswith("option"):
            opt_name, opt_val = cmd.split()[1:]
            if opt_name == "cloning":
                options['cloning'] = (opt_val == 'true')
                print("ok")
            else:
                print("unsupported")
            sys.stdout.flush()
        elif cmd == "list" or cmd == "list for-push":
            interest = Interest(Name(repo_prefix).append("ref-list"))
            data = await fetch_data_packet(face, interest)
            if isinstance(data, Data):
                reflist = data.content.toBytes().decode("utf-8")
                print(reflist)

                if reflist.strip() == "":
                    refs = {}
                else:
                    refs = [
                        item.split(" ")[1]
                        for item in reflist.strip().split("\n")
                    ]
                    refs = {name.split("/")[-1] for name in refs}
            else:
                print("error: Couldn't connect to",
                      repo_prefix,
                      file=sys.stderr)
                running = False
                print("")
            sys.stdout.flush()
        elif cmd.startswith("fetch"):
            fetcher = GitFetcher(face,
                                 Name(repo_prefix).append("objects"), storage)
            while True:
                # Fetch files
                hash_name, ref_name = cmd.split()[1:]
                fetcher.fetch(hash_name, "commit")
                await fetcher.wait_until_finish()
                # Set refs file
                ref_file_path = os.path.join(local_repo_path, ref_name)
                with open(ref_file_path, 'w') as f:
                    f.write(hash_name)
                # Read commands for next fetch
                cmd = sys.stdin.readline().rstrip("\n\r")
                if not cmd.startswith("fetch"):
                    break
            print("")
            sys.stdout.flush()
        elif cmd.startswith("push"):
            while True:
                # Push commands
                # TODO: DELETE ALL HARDCODED THINGS
                # TODO: MAKE DATA AND INTEREST REAL
                branch, commit, _ = parse_push(cmd, local_repo_path)
                repo_name = repo_prefix.split("/")[-1]

                # Create Branch if not exist
                if branch not in refs:
                    print("Non-existing branch. Try to create...",
                          file=sys.stderr)
                    interest = Interest(
                        Name(LOCAL_CMD_PREFIX).append("create-branch").append(
                            repo_name).append(branch))
                    data = await fetch_data_packet(face, interest)
                    if isinstance(data, Data):
                        result = struct.unpack("i", data.content.toBytes())[0]
                        if result == 1:
                            print("Creation succeeded", file=sys.stderr)
                        elif result == 2:
                            print("Creation is FAILED", file=sys.stderr)
                            print("error refs/heads/{} FAILED".format(branch))
                            break
                        else:
                            print("Creation is PENDING", file=sys.stderr)
                            print("error refs/heads/{} PENDING".format(branch))
                            break
                    else:
                        print("error: Couldn't connect to",
                              interest.name.toUri(),
                              file=sys.stderr)
                        break

                # BranchInfo Interest
                interest = Interest(
                    Name(repo_prefix).append("branch-info").append(branch))
                data = await fetch_data_packet(face, interest)
                branchinfo = None
                if isinstance(data, Data):
                    branchinfo = pickle.loads(data.content.toBytes())
                if branchinfo is None or 'custodian' not in branchinfo.__dict__:
                    print("ERROR Interest got no response: ",
                          interest.name,
                          file=sys.stderr)
                    print("error refs/heads/{} DISCONNECTED".format(branch))
                    break

                # Push Interest
                interest = Interest(
                    Name(branchinfo.custodian).append("push").append(
                        repo_name).append(branch))
                interest.applicationParameters = commit.encode("utf-8")
                interest.appendParametersDigestToName()
                interest.interestLifetimeMilliseconds = 20000
                interest.mustBeFresh = True
                data = await fetch_data_packet(face, interest)
                if isinstance(data, Data):
                    result = struct.unpack("i", data.content.toBytes())[0]
                    if result == 1:
                        print("OK push succeeded",
                              interest.name,
                              file=sys.stderr)
                        print("ok refs/heads/{}".format(branch))
                    elif result == 2:
                        print("ERROR push failed",
                              interest.name,
                              file=sys.stderr)
                        print("error refs/heads/{} FAILED".format(branch))
                    else:
                        print("PROCESSING push is not finished yet",
                              interest.name,
                              file=sys.stderr)
                        print("error refs/heads/{} PENDING".format(branch))
                else:
                    print("ERROR Interest got no response: ",
                          interest.name,
                          file=sys.stderr)
                    print("error refs/heads/{} DISCONNECTED".format(branch))
                    break

                # Read commands for next fetch
                cmd = sys.stdin.readline().rstrip("\n\r")
                if not cmd.startswith("push"):
                    break

            print("")
            sys.stdout.flush()
        elif cmd == "":
            empty_cnt += 1
        else:
            pass

    producer.cancel()
    running = False
    await face_task