Skip to content

Code example for simple client/server communication with OSCORE #310

@SignorMercurio

Description

@SignorMercurio

Background

Thanks for the great library! I'm trying to implement a simple client/server communication demo with OSCORE, and have already read the docs here: https://aiocoap.readthedocs.io/en/latest/stateofoscore.html. However, the docs only include instructions on using the CLIs rather than code examples, which would be very helpful if added to the docs.

Attempts

So I tried to write the demo code for the client:

import asyncio
from aiocoap import *
import logging

logging.basicConfig(level=logging.INFO)

async def main():
    client = await Context.create_client_context()

    client.client_credentials.load_from_dict({
        "coap://localhost/*": {"oscore": {"contextfile": "client1/for-fileserver/"}}
    })

    request1 = Message(
        code=GET, uri='coap://localhost/sensor_data')

    print(request1.remote)
    response1 = await client.request(request1).response

    print("Response from Sensor1: %s" % response1.payload)

if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())

As well as the server:

import asyncio
from aiocoap.resource import Resource, Site
from aiocoap import *
import logging

logging.basicConfig(level=logging.DEBUG)

class SensorResource(Resource):
    async def render_get(self, request):
        response = Message(payload=b"Sensor 1 data")
        return response

async def main():
    resource = SensorResource()

    site = Site()
    site.add_resource(('sensor_data',), resource)
    server = await Context.create_server_context(site, bind=('localhost', 5683))
    server.server_credentials.load_from_dict({
        ":client1": {"oscore": {"contextfile": "server/from-client1/"}}
    })
    print("Sensor server is running...")
    await asyncio.sleep(3600)

if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())

The OSCORE context here is exactly the same with the docs, but I got an error No Object-Security option present. After some debugging, I believe the problem here is that the communication is using simple6 transport rather than the expected oscore transport.

I'm aware that simple6 is used for platforms like OSX so I switched to Linux, and it's still using udp6, not oscore. I've also tried setting request1.opt.object_security = b'', which resolves the above error but still using simple6 transport. In addition, I tried using the provided CLIs client and fileserver and got the same No Object-Security option present error with the same simple6 transport.

I wonder if there's anything wrong with the above code. I'll be happy to contribute a correct code example for simple client/server communication with OSCORE to the current docs.

Output of python3 -m aiocoap.cli.defaults

Python version: 3.8.9 (default, Feb 18 2022, 07:45:33)
[Clang 13.1.6 (clang-1316.0.21.2)]
aiocoap version: 0.4.7
Modules missing for subsystems:
    dtls: everything there
    oscore: everything there
    linkheader: everything there
    prettyprint: missing termcolor
Python platform: darwin
Default server transports:  oscore:tinydtls:tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver
Selected server transports: oscore:tinydtls:tcpserver:tcpclient:tlsserver:tlsclient:simple6:simplesocketserver
Default client transports:  oscore:tinydtls:tcpclient:tlsclient:simple6
Selected client transports: oscore:tinydtls:tcpclient:tlsclient:simple6
SO_REUSEPORT available (default, selected): True, True

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions