Example #1
0
def create_or_recall_keys(replace: bool = False):
    """Generate keys and save to .keys file."""
    if not os.path.exists('.keys') or replace:
        # Create keypair and write to file
        my_vk, my_sk = crypto.create_keypair()
        did = crypto.bytes_to_b58(my_vk[:16])

        print('DID:', did)
        print('VK:', crypto.bytes_to_b58(my_vk))
        their_vk = input('Their VK: ')
        endpoint = input('Their Endpoint: ')

        with open('.keys', 'w+') as key_file:
            json.dump(
                {
                    'did': did,
                    'my_vk': crypto.bytes_to_b58(my_vk),
                    'my_sk': crypto.bytes_to_b58(my_sk),
                    'their_vk': their_vk,
                    'endpoint': endpoint
                }, key_file)
    else:
        with open('.keys', 'r') as key_file:
            info = json.load(key_file)
            did = info['did']
            my_vk = info['my_vk']
            my_sk = info['my_sk']
            their_vk = info['their_vk']
            endpoint = info['endpoint']

    return did, my_vk, my_sk, their_vk, endpoint
async def test_simple_messaging(backchannel):
    """Show simple messages being passed to and from the test subject."""

    expected_schema = MessageSchema({
        '@type': 'test/protocol/1.0/test',
        '@id': str,
        'msg': 'pong'
    })

    ping = Message({
        '@type': 'test/protocol/1.0/test',
        'msg': 'ping'
    })
    print('Sending message:', ping.pretty_print())
    pong = await backchannel.send_and_await_reply_async(
        ping,
        timeout=1
    )

    print('Received message:', pong.pretty_print())

    assert pong.mtc[
        CONFIDENTIALITY | INTEGRITY | AUTHENTICATED_ORIGIN | DESERIALIZE_OK
    ]
    assert not pong.mtc[NONREPUDIATION]
    assert pong.mtc.ad['sender_vk'] == crypto.bytes_to_b58(backchannel.their_vk)
    assert pong.mtc.ad['recip_vk'] == crypto.bytes_to_b58(backchannel.my_vk)

    assert expected_schema.validate(pong)
def generate_test_info(seed=None):
    """Generate connection information from seed."""
    test_keys = StaticConnection.Keys(*crypto.create_keypair(seed))
    test_keys_b58 = StaticConnection.Keys(
        crypto.bytes_to_b58(test_keys.verkey),
        crypto.bytes_to_b58(test_keys.sigkey))
    test_did = crypto.bytes_to_b58(test_keys.verkey[:16])
    return ConnectionInfo(test_keys, test_keys_b58, test_did)
Example #4
0
def store_connection(conn: StaticConnection):
    if hasattr(conn,
               'state') and (conn.state.state == ConnectionStates.COMPLETE or
                             conn.state.state == ConnectionStates.RESPONDED):
        with open('.keys', 'w+') as key_file:
            json.dump(
                {
                    'did': crypto.bytes_to_b58(conn.my_vk[:16]),
                    'my_vk': crypto.bytes_to_b58(conn.my_vk),
                    'my_sk': crypto.bytes_to_b58(conn.my_sk),
                    'their_vk': crypto.bytes_to_b58(conn.their_vk),
                    'endpoint': conn.endpoint
                }, key_file)
Example #5
0
async def test_cron_example(example_keys, test_keys, connection,
                            listening_endpoint):
    """Test the cron example."""
    with connection.next() as next_msg:
        process = await asyncio.create_subprocess_exec(
            'env/bin/python', 'examples/cron.py', '--my-verkey',
            crypto.bytes_to_b58(example_keys.verkey), '--my-sigkey',
            crypto.bytes_to_b58(example_keys.sigkey), '--their-verkey',
            crypto.bytes_to_b58(test_keys.verkey), '--endpoint',
            listening_endpoint)
        assert await process.wait() == 0
        msg = await asyncio.wait_for(next_msg, 30)

    assert 'basicmessage' in msg.type
    assert msg['content'] == 'The Cron script was executed.'
def test_pack_unpack_auth(keys, alice, bob):
    """ Test the pack-unpack loop with authcrypt. """
    alice_vk, _alice_sk, bob_vk, _bob_sk = keys
    msg = Message({'@type': 'doc;protocol/1.0/name'})
    packed_msg = alice.pack(msg)
    assert isinstance(packed_msg, bytes)

    unpacked_msg = bob.unpack(packed_msg)
    assert isinstance(unpacked_msg, Message)
    assert hasattr(unpacked_msg, 'mtc')
    assert unpacked_msg.mtc[
        CONFIDENTIALITY | INTEGRITY | DESERIALIZE_OK | AUTHENTICATED_ORIGIN
    ]
    assert unpacked_msg.mtc[NONREPUDIATION] is False
    assert unpacked_msg.mtc.ad['sender_vk'] == crypto.bytes_to_b58(alice_vk)
    assert unpacked_msg.mtc.ad['recip_vk'] == crypto.bytes_to_b58(bob_vk)
Example #7
0
    def new_frontchannel(
            self,
            *,
            their_vk: Union[bytes, str] = None,
            recipients: [Union[bytes, str]] = None,
            routing_keys: [Union[bytes, str]] = None,
            endpoint: str = None) -> StaticConnection:
        """
        Create a new connection and add it as a frontchannel.

        Args:
            fc_vk: The new frontchannel's verification key
            fc_sk: The new frontchannel's signing key
            their_vk: The test subject's verification key for this channel
            endpoint: The HTTP URL to the endpoint of the test subject.

        Returns:
            Returns the new front channel (static connection).
        """
        fc_keys = crypto.create_keypair()
        new_fc = StaticConnection(
            fc_keys,
            their_vk=their_vk,
            endpoint=endpoint,
            recipients=recipients,
            routing_keys=routing_keys
        )
        frontchannel_index = crypto.bytes_to_b58(new_fc.verkey)
        self.frontchannels[frontchannel_index] = new_fc
        return new_fc
async def responder(connection, query, comment):
    """Send a query request and return the response."""
    # Send the request
    req = Message({
        '@type':
        'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/discover-features/1.0/query',
        'query': query,
        'comment': comment,
    })
    resp = await connection.send_and_await_reply_async(req, timeout=1)
    # Validate the response
    assert resp.mtc.is_authcrypted()
    assert resp.mtc.sender == crypto.bytes_to_b58(connection.recipients[0])
    assert resp.mtc.recipient == connection.verkey_b58
    resp_schema = MessageSchema({
        '@type':
        'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/discover-features/1.0/disclose',
        '@id': str,
        'protocols': [{
            'pid': str,
            'roles': [str]
        }]
    })
    resp_schema(resp)
    # Return the response
    return resp
async def test_trust_ping_sender(backchannel, connection):
    """Test that subject sends a trust ping."""
    expected_trust_ping_schema = MessageSchema({
        "@type": Any(TYPE, ALT_TYPE),
        "@id": str,
        Optional("~timing"): {
            Optional("out_time"): str,
            Optional("expires_time"): str,
            Optional("delay_milli"): int
        },
        Optional("comment"): str,
        "response_requested": bool
    })

    with connection.next() as next_msg:
        await backchannel.trust_ping_v1_0_send_ping(connection)
        msg = await asyncio.wait_for(next_msg, 5)

    assert expected_trust_ping_schema(msg)
    assert msg.mtc.is_authcrypted()
    assert msg.mtc.sender == crypto.bytes_to_b58(connection.recipients[0])
    assert msg.mtc.recipient == connection.verkey_b58

    await connection.send_async({
        "@type": TYPE,
        "~thread": {
            "thid": msg.id
        },
    })
    def new_frontchannel(
            self,
            their_vk: Union[bytes, str],
            endpoint: str) -> StaticConnection:
        """
        Create a new connection and add it as a frontchannel.

        Args:
            fc_vk: The new frontchannel's verification key
            fc_sk: The new frontchannel's signing key
            their_vk: The test subject's verification key for this channel
            endpoint: The HTTP URL to the endpoint of the test subject.

        Returns:
            Returns the new front channel (static connection).
        """
        fc_vk, fc_sk = crypto.create_keypair()
        new_fc = StaticConnection(
            fc_vk,
            fc_sk,
            their_vk,
            endpoint
        )
        frontchannel_index = crypto.bytes_to_b58(fc_vk)
        self.frontchannels[frontchannel_index] = new_fc
        return new_fc
async def responder(connection, query, comment):
    """Send a query request and return the response."""
    # Send the request
    req = Message({
        '@type': Suite.TYPE_PREFIX + 'discover-features/1.0/query',
        'query': query,
        'comment': comment,
    })
    resp = await connection.send_and_await_reply_async(req, timeout=1)
    # Validate the response
    assert resp.mtc.is_authcrypted()
    assert resp.mtc.sender == crypto.bytes_to_b58(connection.recipients[0])
    assert resp.mtc.recipient == connection.verkey_b58
    msg_type = Suite.TYPE_PREFIX + 'discover-features/1.0/disclose'
    alt_msg_type = Suite.ALT_TYPE_PREFIX + 'discover-features/1.0/disclose'
    resp_schema = MessageSchema({
        '@type': Any(msg_type, alt_msg_type),
        '@id': str,
        'protocols': [{
            'pid': str,
            'roles': [str]
        }]
    })
    resp_schema(resp)
    # Return the response
    return resp
 async def query(self, msg, conn):
     """Handle a discover-features query message. """
     # Verify the query message
     assert msg.mtc.is_authcrypted()
     assert msg.mtc.sender == crypto.bytes_to_b58(conn.recipients[0])
     assert msg.mtc.recipient == conn.verkey_b58
     msg_schema = MessageSchema({
         '@type': str(self.type('query')),
         '@id': str,
         'query': str,
         Optional('comment'): str,
     })
     msg_schema(msg)
     query = msg['query']
     # Find the protocols which match the query message
     matchingProtocols = []
     for proto in self.protocols:
         if re.match(query, proto['pid']):
             matchingProtocols.append(proto)
     # Send the disclose message
     await conn.send_async({
         "@type": self.type("disclose"),
         "protocols": matchingProtocols,
     })
     self.query_message_count = self.query_message_count + 1
async def test_trust_ping_with_response_requested_true(connection):
    """Test that subject responds to trust pings."""

    expected_trust_pong_schema = MessageSchema({
        "@type": Any(TYPE, ALT_TYPE),
        "@id": str,
        "~thread": {
            "thid": str
        },
        Optional("~timing"): {
            Optional("in_time"): str,
            Optional("out_time"): str
        },
        Optional("comment"): str
    })

    trust_ping = Message({
        "@type": TYPE,
        # "@id" is added by the staticagent lib
        "response_requested": True
    })
    #print('Sending message:', trust_ping.pretty_print())
    trust_pong = await connection.send_and_await_reply_async(trust_ping,
                                                             timeout=1)

    #print('Received message:', trust_pong.pretty_print())

    assert trust_pong.mtc.is_authcrypted()
    # are you, you and am I, me?
    assert trust_pong.mtc.sender == crypto.bytes_to_b58(
        connection.recipients[0])
    assert trust_pong.mtc.recipient == connection.verkey_b58

    assert expected_trust_pong_schema(trust_pong)
    assert trust_pong['~thread']['thid'] == trust_ping.id
async def test_webserver_with_websockets(example_keys, test_keys,
                                         connection_ws, listening_endpoint,
                                         unused_tcp_port_factory):
    """Test the webserver with websockets example."""
    example_port = unused_tcp_port_factory()
    connection_ws.target.update(
        endpoint="http://*****:*****@type": "https://didcomm.org/"
                "basicmessage/1.0/message",
                "~l10n": {
                    "locale": "en"
                },
                "sent_time": utils.timestamp(),
                "content": "Your hovercraft is full of eels.",
            },
            return_route="all",
        )
        msg = await queue.get(timeout=30)

    assert "basicmessage" in msg.type
    assert msg["content"] == "You said: Your hovercraft is full of eels."
    process.terminate()
    await process.wait()
Example #15
0
async def test_connection_started_by_suite(config, temporary_channel):
    """ Test a connection as started by the suite. """

    with temporary_channel() as conn:
        invite_str = build_invite('test-suite-connection-started-by-suite',
                                  conn.my_vk_b58, config['endpoint'])

        print('Encoding invitation:', parse_invite(invite_str))

        print("\n\nInvitation encoded as URL: ", invite_str)

        print("Awaiting request from tested agent...")

        def condition(msg):
            print(msg)
            return msg.type == REQUEST

        request = await conn.await_message(condition=condition, timeout=30)

        REQUEST_SCHEMA(request)
        print("\nReceived request:\n", request.pretty_print())

        (_, conn.their_vk_b58, conn.endpoint) = (
            request['connection']['DIDDoc']['publicKey'][0]['controller'],
            request['connection']['DIDDoc']['publicKey'][0]['publicKeyBase58'],
            request['connection']['DIDDoc']['service'][0]['serviceEndpoint'])
        conn.their_vk = crypto.b58_to_bytes(conn.their_vk_b58)

        conn.my_vk, conn.my_sk = crypto.create_keypair()
        conn.did = crypto.bytes_to_b58(conn.my_vk[:16])
        conn.my_vk_b58 = crypto.bytes_to_b58(conn.my_vk)

        response = build_response(request.id, conn.did, conn.my_vk_b58,
                                  config['endpoint'])

        print("\nSending Response (pre signature packing):\n",
              response.pretty_print())

        response['connection~sig'] = crypto.sign_message_field(
            response['connection'], signer=conn.my_vk_b58, secret=conn.my_sk)
        del response['connection']
        print("\nSending Response (post signature packing):\n",
              response.pretty_print())

        await conn.send_async(response)
Example #16
0
    async def invitation(self, msg, _agent):
        """ Process an invitation. """
        print(msg.pretty_print())
        their_conn_key = msg['recipientKeys'][0]
        my_vk, my_sk = crypto.create_keypair()
        new_connection = StaticConnection(my_vk,
                                          my_sk,
                                          msg['recipientKeys'][0],
                                          msg['serviceEndpoint'],
                                          dispatcher=self.dispatcher)
        new_connection.did = crypto.bytes_to_b58(my_vk[:16])
        new_connection.vk_b58 = crypto.bytes_to_b58(my_vk)
        new_connection.state = ConnectionState()
        new_connection.state.role = Roles.INVITEE
        new_connection.state.transition(Events.RECV_INVITE)

        self.connections[their_conn_key] = new_connection
        await new_connection.send_async({
            '@type': self.type('request'),
            'label': 'apts-demo-agent-as-invitee',
            'connection': {
                'DID': new_connection.did,
                'DIDDoc': {
                    "@context":
                    "https://w3id.org/did/v1",
                    "id":
                    new_connection.did,
                    "publicKey": [{
                        "id": new_connection.did + "#keys-1",
                        "type": "Ed25519VerificationKey2018",
                        "controller": new_connection.did,
                        "publicKeyBase58": new_connection.vk_b58
                    }],
                    "service": [{
                        "id": new_connection.did + ";indy",
                        "type": "IndyAgent",
                        "recipientKeys": [new_connection.vk_b58],
                        "routingKeys": [],
                        "serviceEndpoint": self.endpoint,
                    }],
                }
            }
        })

        new_connection.state.transition(Events.SEND_REQ)
Example #17
0
 def verify_msg(self, typ, msg, conn, pid, schema):
     assert msg.mtc.is_authcrypted()
     assert msg.mtc.sender == crypto.bytes_to_b58(conn.recipients[0])
     assert msg.mtc.recipient == conn.verkey_b58
     schema['@type'] = "{}/{}".format(pid, typ)
     schema['@id'] = str
     msg_schema = MessageSchema(schema)
     msg_schema(msg)
     self._received_msg(msg, conn)
Example #18
0
def test_b58_inputs_without_their_info(my_test_info):
    """Test that valid b58 inputs yield expected values."""
    conn = Connection.from_parts(
        (my_test_info.keys.verkey_b58,
         crypto.bytes_to_b58(my_test_info.keys.sigkey)))
    assert conn.verkey == my_test_info.keys.verkey
    assert conn.sigkey == my_test_info.keys.sigkey
    assert conn.verkey_b58 == my_test_info.keys.verkey_b58
    assert conn.did == my_test_info.did
Example #19
0
    def remove_frontchannel(self, connection: StaticConnection):
        """
        Remove a frontchannel.

        Args:
            fc_vk: The frontchannel's verification key
        """
        frontchannel_index = crypto.bytes_to_b58(connection.verkey)
        if frontchannel_index in self.frontchannels:
            del self.frontchannels[frontchannel_index]
    def remove_frontchannel(self, connection: StaticConnection):
        """
        Remove a frontchannel.

        Args:
            fc_vk: The frontchannel's verification key
        """
        fc_vk = crypto.bytes_to_b58(connection.my_vk)
        if fc_vk in self.frontchannels:
            del self.frontchannels[fc_vk]
Example #21
0
async def test_webserver_aiohttp(example_keys, test_keys, connection,
                                 listening_endpoint, unused_tcp_port_factory):
    """Test the webserver aiohttp example."""
    example_port = unused_tcp_port_factory()
    connection.update(endpoint='http://*****:*****@type":
            "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/"
            "basicmessage/1.0/message",
            "~l10n": {
                "locale": "en"
            },
            "sent_time":
            utils.timestamp(),
            "content":
            "Your hovercraft is full of eels."
        })
        msg = await asyncio.wait_for(next_msg, 30)

    assert 'basicmessage' in msg.type
    assert msg['content'] == 'You said: Your hovercraft is full of eels.'
    process.terminate()
    await process.wait()
Example #22
0
async def test_connection_started_by_tested_agent(config, temporary_channel):
    """Test a connection as started by the agent under test."""
    invite_url = input('Input generated connection invite: ')

    invite_msg = parse_invite(invite_url)

    print("\nReceived Invite:\n", invite_msg.pretty_print())

    # Create my information for connection
    with temporary_channel(invite_msg['recipientKeys'][0],
                           invite_msg['serviceEndpoint']) as conn:

        did = crypto.bytes_to_b58(conn.my_vk[:16])
        my_vk_b58 = crypto.bytes_to_b58(conn.my_vk)

        # Send Connection Request to inviter
        request = build_request('test-connection-started-by-tested-agent', did,
                                my_vk_b58, config['endpoint'])

        print("\nSending Request:\n", request.pretty_print())
        print("Awaiting response from tested agent...")
        response = await conn.send_and_await_reply_async(
            request, condition=lambda msg: msg.type == RESPONSE, timeout=30)

        RESPONSE_SCHEMA_PRE_SIG_VERIFY(response)
        print("\nReceived Response (pre signature verification):\n",
              response.pretty_print())

        signer, response['connection'] = \
            crypto.verify_signed_message_field(response['connection~sig'])
        assert signer == invite_msg['recipientKeys'][0], 'Unexpected signer'
        del response['connection~sig']

        RESPONSE_SCHEMA_POST_SIG_VERIFY(response)
        assert response['~thread']['thid'] == request.id

        print("\nReceived Response (post signature verification):\n",
              response.pretty_print())
async def test_cron_example(example_keys, test_keys, connection,
                            listening_endpoint):
    """Test the cron example."""
    async with connection.queue() as queue:
        process = await asyncio.create_subprocess_exec(
            "poetry",
            "run",
            "python",
            "examples/cron.py",
            "--my-verkey",
            crypto.bytes_to_b58(example_keys.verkey),
            "--my-sigkey",
            crypto.bytes_to_b58(example_keys.sigkey),
            "--their-verkey",
            crypto.bytes_to_b58(test_keys.verkey),
            "--endpoint",
            listening_endpoint,
        )
        assert await process.wait() == 0
        msg = await queue.get(timeout=30)

    assert "basicmessage" in msg.type
    assert msg["content"] == "The Cron script was executed."
async def test_simple_messaging(connection):
    """Show simple messages being passed to and from the test subject."""

    expected_schema = MessageSchema({
        '@type': 'test/protocol/1.0/test',
        '@id': str,
        'msg': 'pong'
    })

    ping = Message({'@type': 'test/protocol/1.0/test', 'msg': 'ping'})
    print('Sending message:', ping.pretty_print())
    pong = await connection.send_and_await_reply_async(ping, timeout=1)

    print('Received message:', pong.pretty_print())

    assert pong.mtc.is_authcrypted()
    assert pong.mtc.sender == crypto.bytes_to_b58(connection.recipients[0])
    assert pong.mtc.recipient == connection.verkey_b58

    assert expected_schema(pong)
Example #25
0
 def create_invitation(self):
     """ Create and return an invite. """
     conn_vk, conn_sk = crypto.create_keypair()
     connection = StaticConnection(conn_vk,
                                   conn_sk,
                                   b'',
                                   '',
                                   dispatcher=self.dispatcher)
     conn_vk_b58 = crypto.bytes_to_b58(conn_vk)
     self.connections[conn_vk_b58] = connection
     connection.state = ConnectionState()
     connection.state.role = Roles.INVITER
     connection.state.transition(Events.SEND_INVITE)
     invitation = Message({
         '@type': self.type('invitation'),
         'label': 'static-iiw',
         'recipientKeys': [conn_vk_b58],
         'serviceEndpoint': self.endpoint,
         'routingKeys': []
     })
     invitation_url = '{}?c_i={}'.format(
         self.endpoint,
         crypto.bytes_to_b64(invitation.serialize().encode()))
     return connection, invitation_url
Example #26
0
from aries_staticagent import crypto

vk_bytes, sk_bytes = crypto.create_keypair()
did_bytes = vk_bytes[0:16]

vk = crypto.bytes_to_b58(vk_bytes)
sk = crypto.bytes_to_b58(sk_bytes)
did = crypto.bytes_to_b58(did_bytes)


print('For full agent:\n\tDID: {}\n\tVK: {}\n'.format(did, vk))

print('For static agent:\n\tVK: {}\n\tSK: {}'.format(vk, sk))
Example #27
0
    async def request(self, msg, _agent):
        """ Process a request. """
        print(msg.pretty_print())
        connection = self.connections[msg.mtc.ad['recip_vk']]
        connection.state.transition(Events.RECV_REQ)

        # Old connection keys, need to sign new keys with these
        conn_vk, conn_sk = connection.my_vk, connection.my_sk

        # Relationship keys, replacing connection keys
        my_vk, my_sk = crypto.create_keypair()

        # Update connection
        connection.my_vk, connection.my_sk = my_vk, my_sk
        connection.did = crypto.bytes_to_b58(my_vk[:16])
        connection.vk_b58 = crypto.bytes_to_b58(my_vk)
        connection.their_did = msg['connection']['DIDDoc']['publicKey'][0][
            'controller']
        connection.their_vk = crypto.b58_to_bytes(
            msg['connection']['DIDDoc']['publicKey'][0]['publicKeyBase58'])
        connection.endpoint = msg['connection']['DIDDoc']['service'][0][
            'serviceEndpoint']

        del self.connections[msg.mtc.ad['recip_vk']]
        self.connections[connection.vk_b58] = connection

        # Prepare response
        connection_block = {
            'DID': connection.did,
            'DIDDoc': {
                "@context":
                "https://w3id.org/did/v1",
                "id":
                connection.did,
                "publicKey": [{
                    "id": connection.did + "#keys-1",
                    "type": "Ed25519VerificationKey2018",
                    "controller": connection.did,
                    "publicKeyBase58": connection.vk_b58
                }],
                "service": [{
                    "id": connection.did + ";indy",
                    "type": "IndyAgent",
                    "recipientKeys": [connection.vk_b58],
                    "routingKeys": [],
                    "serviceEndpoint": self.endpoint,
                }],
            }
        }

        connection.state.transition(Events.SEND_RESP)

        await connection.send_async({
            '@type':
            self.type('response'),
            '~thread': {
                'thid': msg.id,
                'sender_order': 0
            },
            'connection~sig':
            crypto.sign_message_field(connection_block,
                                      crypto.bytes_to_b58(conn_vk), conn_sk)
        })
 def add_frontchannel(self, connection: StaticConnection):
     """Add an already created connection as a frontchannel."""
     frontchannel_index = crypto.bytes_to_b58(connection.my_vk)
     self.frontchannels[frontchannel_index] = connection