OSCoreEndpointContextInfo.java
/*******************************************************************************
* Copyright (c) 2019 RISE SICS and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Rikard Höglund (RISE SICS)
*
******************************************************************************/
package org.eclipse.californium.oscore;
import org.eclipse.californium.core.coap.Message;
import org.eclipse.californium.core.coap.Request;
import org.eclipse.californium.core.coap.Response;
import org.eclipse.californium.core.network.Exchange;
import org.eclipse.californium.core.network.Exchange.EndpointContextOperator;
import org.eclipse.californium.elements.Definition;
import org.eclipse.californium.elements.EndpointContext;
import org.eclipse.californium.elements.MapBasedEndpointContext;
import org.eclipse.californium.elements.MapBasedEndpointContext.Attributes;
/**
* Class that handles setting information in an EndpointContext for OSCORE
* messages.
*
* It provides functionality to set appropriate information about the OSCORE
* context used, as strings in the map inside an EndpointContext.
*
* When an application is receiving a message or sending a request it can use
* the strings in the EndpointContext to retrieve information about what OSCORE
* context was used for this messages.
*
* Information that can be retrieved is the URI associated to the OSCORE
* context, the Sender ID, Recipient ID and Context ID of the OSCORE context.
*
* This class contains methods to set the source endpoint context for incoming
* messages. It also contains a method that adds an operator on the exchange
* when sending a request that will make the new created destination endpoint
* context available via a callback. For outgoing responses the destination
* endpoint context used will be the source endpoint context created for the
* incoming request.
*/
public class OSCoreEndpointContextInfo {
/**
* Defines strings for the keys to be set in the EndpointContext.
*/
private final static String PREFIX = MapBasedEndpointContext.KEY_PREFIX_NONE_CRITICAL;
public final static Definition<String> OSCORE_SENDER_ID = new Definition<>(PREFIX + "OSCORE_SENDER_ID", String.class,
MapBasedEndpointContext.ATTRIBUTE_DEFINITIONS);
public final static Definition<String> OSCORE_RECIPIENT_ID = new Definition<>(PREFIX + "OSCORE_RECIPIENT_ID", String.class,
MapBasedEndpointContext.ATTRIBUTE_DEFINITIONS);
public final static Definition<String> OSCORE_CONTEXT_ID = new Definition<>(PREFIX + "OSCORE_CONTEXT_ID", String.class,
MapBasedEndpointContext.ATTRIBUTE_DEFINITIONS);
public final static Definition<String> OSCORE_URI = new Definition<>(PREFIX + "OSCORE_URI", String.class,
MapBasedEndpointContext.ATTRIBUTE_DEFINITIONS);
/**
* Sets information in a destination endpoint context for outgoing requests.
*
* Sending a request is a special case since an operator should be added to
* the exchange that sets the appropriate information in the endpoint
* context that will be created after the request is sent.
*
* @param oscoreCtx the OSCORE context used for this message
* @param exchange the exchange to later set the endpoint context for
*/
public static void sendingRequest(OSCoreCtx oscoreCtx, Exchange exchange) {
exchange.setEndpointContextPreOperator(new OSCoreEndpointContextOperator(oscoreCtx));
}
/**
* Class that functions as an operator on the exchange. It will set
* information about the OSCORE context used on the new endpoint context
* created after the request is sent.
*
* This new endpoint context is available using
* MessageObserver.onContextEstablished(EndpointContext).
*
*/
private static class OSCoreEndpointContextOperator implements EndpointContextOperator {
/**
* OSCORE context to take information from to set in the endpoint
* context
*/
private final OSCoreCtx oscoreCtx;
/**
* Constructor taking an OSCORE Context that the information to be set
* in the endpoint context will be taken from.
*
* @param oscoreCtx the OSCORE context to take information to set from
*/
public OSCoreEndpointContextOperator(final OSCoreCtx oscoreCtx) {
this.oscoreCtx = oscoreCtx;
}
/**
* Method that will be ran when setting the endpoint context for an
* exchange. Should perform changes to the endpoint context to add the
* OSCORE-related strings.
*
* @return the new endpoint context to use
*/
@Override
public EndpointContext apply(EndpointContext context) {
return setInfo(oscoreCtx, context);
}
}
/**
* Sets information in a source endpoint context for incoming requests.
*
* @param oscoreCtx the OSCORE context used for this message
* @param request the request to set the endpoint context for
*/
public static void receivingRequest(OSCoreCtx oscoreCtx, Request request) {
setInfoIncoming(oscoreCtx, request);
}
/**
* Sets information in a source endpoint context for incoming responses.
*
* @param oscoreCtx the OSCORE context used for this message
* @param response the response to set the endpoint context for
*/
public static void receivingResponse(OSCoreCtx oscoreCtx, Response response) {
setInfoIncoming(oscoreCtx, response);
}
/**
* Adds strings with information about the OSCORE context used to this
* source endpoint context for incoming messages.
*
* @param oscoreCtx the OSCORE context used for this message
* @param message the message to set information in the source endpoint
* context for
*/
private static void setInfoIncoming(OSCoreCtx oscoreCtx, Message message) {
// Create new MapBasedEndpointContext for source endpoint context with
// string values for OSCORE added
EndpointContext newEndpointContext = setInfo(oscoreCtx, message.getSourceContext());
message.setSourceContext(newEndpointContext);
}
/**
* Adds strings with information about the OSCORE context used to this
* endpoint context (creating a new one).
*
* @param oscoreCtx the OSCORE context used
* @param endpointContext the original endpoint context to set information
* based on
*
* @return the new endpoint context
*/
private static MapBasedEndpointContext setInfo(OSCoreCtx oscoreCtx, EndpointContext endpointContext) {
// If endpoint context is not set, keep it unset
if (endpointContext == null) {
return null;
}
// Create new MapBasedEndpointContext for this endpoint context with
// string values for OSCORE added
Attributes attributes = new Attributes();
attributes.add(OSCORE_SENDER_ID, oscoreCtx.getSenderIdString());
attributes.add(OSCORE_RECIPIENT_ID, oscoreCtx.getRecipientIdString());
attributes.add(OSCORE_CONTEXT_ID, oscoreCtx.getContextIdString());
attributes.add(OSCORE_URI, oscoreCtx.getUri());
MapBasedEndpointContext newEndpointContext = MapBasedEndpointContext.addEntries(endpointContext, attributes);
return newEndpointContext;
}
}