Skip to content

Commit

Permalink
bumped the version of the scandium fork
Browse files Browse the repository at this point in the history
  • Loading branch information
jvermillard committed Aug 4, 2014
1 parent b48a32a commit 3a7bdee
Show file tree
Hide file tree
Showing 16 changed files with 415 additions and 579 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
import leshan.server.lwm2m.observation.ObservationRegistry;
import leshan.server.lwm2m.resource.RegisterResource;
import leshan.server.lwm2m.security.SecureEndpoint;
import leshan.server.lwm2m.security.SecurityStore;
import leshan.server.lwm2m.security.SecurityRegistry;
import leshan.server.lwm2m.security.SecurityStore;

import org.apache.commons.lang.Validate;
import org.eclipse.californium.scandium.DTLSConnector;
Expand Down Expand Up @@ -131,7 +131,10 @@ public LwM2mServer(InetSocketAddress localAddress, InetSocketAddress localAddres
securityRegistry = new SecurityRegistry();
}

Endpoint secureEndpoint = new SecureEndpoint(new DTLSConnector(localAddressSecure, securityRegistry));
DTLSConnector connector = new DTLSConnector(localAddressSecure, null);
connector.getConfig().setServerPsk(securityRegistry);

Endpoint secureEndpoint = new SecureEndpoint(connector);
coapServer.addEndpoint(secureEndpoint);

// define /rd resource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
* Contributors:
* Matthias Kovatsch - creator and main architect
* Stefan Jucker - DTLS implementation
* Julien Vermillard - Sierra Wireless
******************************************************************************/
package org.eclipse.californium.scandium;

import java.io.File;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -51,36 +52,25 @@
import org.eclipse.californium.scandium.dtls.ResumingServerHandshaker;
import org.eclipse.californium.scandium.dtls.ServerHandshaker;
import org.eclipse.californium.scandium.dtls.ServerHello;
import org.eclipse.californium.scandium.dtls.pskstore.PskStore;
import org.eclipse.californium.scandium.util.ByteArrayUtils;
import org.eclipse.californium.scandium.util.ScProperties;

import ch.ethz.inf.vs.elements.Connector;
import ch.ethz.inf.vs.elements.ConnectorBase;
import ch.ethz.inf.vs.elements.RawData;

/**
* A {@link Connector} implementation for securing the inner datagrams using the DTLS standard.
*
*/
public class DTLSConnector extends ConnectorBase {

/*
* Note: DTLSConnector can also implement the interface Connector instead of extending ConnectorBase
*/

private final static Logger LOGGER = Logger.getLogger(DTLSConnector.class.getCanonicalName());

public static final String KEY_STORE_LOCATION = ScProperties.std.getProperty("KEY_STORE_LOCATION".replace("/",
File.pathSeparator));
public static final String TRUST_STORE_LOCATION = ScProperties.std.getProperty("TRUST_STORE_LOCATION".replace("/",
File.pathSeparator));

private int maxFragmentLength = ScProperties.std.getInt("MAX_FRAGMENT_LENGTH");

/** The overhead for the record header (13 bytes) and the handshake header (12 bytes) is 25 bytes */
private int maxPayloadSize = maxFragmentLength + 25;

/** The initial timer value for retransmission; rfc6347, section: 4.2.4.1 */
private int retransmission_timeout = ScProperties.std.getInt("RETRANSMISSION_TIMEOUT");

/** Maximal number of retransmissions before the attempt to transmit a message is canceled */
private int max_retransmit = ScProperties.std.getInt("MAX_RETRANSMIT");
/** all the configuration options for the DTLS connector */
private final DTLSConnectorConfig config = new DTLSConnectorConfig(this);

private final InetSocketAddress address;

Expand All @@ -98,19 +88,19 @@ public class DTLSConnector extends ConnectorBase {
/** Storing flights according to peer-addresses. */
private Map<String, DTLSFlight> flights = new ConcurrentHashMap<String, DTLSFlight>();

/** Storage for the pre-shared keys */
private final PskStore pskStore;
/** root authorities certificates */
private final Certificate[] rootCerts;

/**
* Create a DTLS connector.
*
* @param address the address to binf
* @param pskStore the storage for pre-shared keys
* @param address the address to bind
* @param rootCertificates list of trusted self-signed root certificates
*/
public DTLSConnector(InetSocketAddress address, PskStore pskStore) {
public DTLSConnector(InetSocketAddress address, Certificate[] rootCertificates) {
super(address);
this.address = address;
this.pskStore = pskStore;
this.rootCerts = rootCertificates;
}

/**
Expand All @@ -128,30 +118,38 @@ public void close() {
* @param peerAddress the remote endpoint of the session to close
*/
public void close(InetSocketAddress peerAddress) {
DTLSSession session = dtlsSessions.get(addressToKey(peerAddress));
String addrKey = addressToKey(peerAddress);
try {
DTLSSession session = dtlsSessions.get(addrKey);

if (session != null) {
DTLSMessage closeNotify = new AlertMessage(AlertLevel.WARNING, AlertDescription.CLOSE_NOTIFY);
if (session != null) {
DTLSMessage closeNotify = new AlertMessage(AlertLevel.WARNING, AlertDescription.CLOSE_NOTIFY);

DTLSFlight flight = new DTLSFlight();
flight.addMessage(new Record(ContentType.ALERT, session.getWriteEpoch(), session.getSequenceNumber(),
closeNotify, session));
flight.setRetransmissionNeeded(false);
DTLSFlight flight = new DTLSFlight();
flight.addMessage(new Record(ContentType.ALERT, session.getWriteEpoch(), session.getSequenceNumber(),
closeNotify, session));
flight.setRetransmissionNeeded(false);

cancelPreviousFlight(peerAddress);
cancelPreviousFlight(peerAddress);

flight.setPeerAddress(peerAddress);
flight.setSession(session);
flight.setPeerAddress(peerAddress);
flight.setSession(session);

if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Sending CLOSE_NOTIFY to " + peerAddress.toString());
}
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Sending CLOSE_NOTIFY to " + peerAddress.toString());
}

sendFlight(flight);
} else {
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.warning("Session to close not found: " + peerAddress.toString());
sendFlight(flight);
} else {
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.warning("Session to close not found: " + peerAddress.toString());
}
}
} finally {
// clear sessions
dtlsSessions.remove(addrKey);
handshakers.remove(addrKey);
flights.remove(addrKey);
}
}

Expand All @@ -174,7 +172,7 @@ public synchronized void stop() {
// TODO: We should not return null
@Override
protected RawData receiveNext() throws Exception {
byte[] buffer = new byte[maxPayloadSize];
byte[] buffer = new byte[config.getMaxPayloadSize()];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);

Expand Down Expand Up @@ -293,8 +291,13 @@ protected RawData receiveNext() throws Exception {
LOGGER.info("Created new session as client with peer: " + peerAddress.toString());
}
}
handshaker = new ClientHandshaker(peerAddress, null, session, pskStore);
;
handshaker = new ClientHandshaker(peerAddress, null, session, rootCerts,
config.clientConfig);
handshaker.setMaxFragmentLength(config.getMaxFragmentLength());

handshakers.put(addressToKey(peerAddress), handshaker);

if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest("Stored re-handshaker: " + handshaker.toString() + " for "
+ peerAddress.toString());
Expand Down Expand Up @@ -323,9 +326,12 @@ protected RawData receiveNext() throws Exception {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.info("Created new session as server with peer: " + peerAddress.toString());
}
handshaker = new ServerHandshaker(peerAddress, session, pskStore);
handshaker = new ServerHandshaker(peerAddress, session, rootCerts, config.serverConfig);
handshaker.setMaxFragmentLength(config.getMaxFragmentLength());
} else {
handshaker = new ResumingServerHandshaker(peerAddress, session, pskStore);
handshaker = new ResumingServerHandshaker(peerAddress, session, rootCerts,
config.serverConfig);
handshaker.setMaxFragmentLength(config.getMaxFragmentLength());
}
handshakers.put(addressToKey(peerAddress), handshaker);
if (LOGGER.isLoggable(Level.FINEST)) {
Expand Down Expand Up @@ -386,7 +392,9 @@ protected RawData receiveNext() throws Exception {
AlertMessage alert;
if (e instanceof HandshakeException) {
alert = ((HandshakeException) e).getAlert();
LOGGER.severe("Handshake Exception (" + peerAddress.toString() + "): " + e.getMessage());
LOGGER.severe("Handshake Exception (" + peerAddress.toString() + "): " + e.getMessage()
+ " we close the session");
close(session.getPeer());
} else {
alert = new AlertMessage(AlertLevel.FATAL, AlertDescription.HANDSHAKE_FAILURE);
LOGGER.log(Level.SEVERE, "Unknown Exception (" + peerAddress + ").", e);
Expand Down Expand Up @@ -430,7 +438,8 @@ protected void sendNext(RawData message) throws Exception {
// start fresh handshake
session = new DTLSSession(peerAddress, true);
dtlsSessions.put(addressToKey(peerAddress), session);
handshaker = new ClientHandshaker(peerAddress, message, session, pskStore);
handshaker = new ClientHandshaker(peerAddress, message, session, rootCerts, config.clientConfig);
handshaker.setMaxFragmentLength(config.getMaxFragmentLength());

} else {

Expand All @@ -442,8 +451,10 @@ protected void sendNext(RawData message) throws Exception {

} else {
// try resuming session
handshaker = new ResumingClientHandshaker(peerAddress, message, session, pskStore);
handshaker = new ResumingClientHandshaker(peerAddress, message, session, rootCerts, config.clientConfig);
handshaker.setMaxFragmentLength(config.getMaxFragmentLength());
}

}

DTLSFlight flight = new DTLSFlight();
Expand All @@ -470,6 +481,19 @@ protected void sendNext(RawData message) throws Exception {
sendFlight(flight);
}

/**
* Returns the {@link DTLSSession} related to the given peer address.
*
* @param address the peer address
* @return the {@link DTLSSession} or <code>null</code> if no session found.
*/
public DTLSSession getSessionByAddress(InetSocketAddress address) {
if (address == null) {
return null;
}
return dtlsSessions.get(addressToKey(address));
}

/**
* Searches through all stored sessions and returns that session which matches the session identifier or
* <code>null</code> if no such session available. This method is used when the server receives a
Expand Down Expand Up @@ -512,19 +536,6 @@ private DTLSSession getSessionByIdentifier(byte[] sessionID) {
return null;
}

/**
* Returns the {@link DTLSSession} related to the given peer address.
*
* @param address the peer address
* @return the {@link DTLSSession} or <code>null</code> if no session found.
*/
public DTLSSession getSessionByAddress(InetSocketAddress address) {
if (address == null) {
return null;
}
return dtlsSessions.get(addressToKey(address));
}

private void sendFlight(DTLSFlight flight) {
byte[] payload = new byte[] {};

Expand All @@ -539,7 +550,7 @@ private void sendFlight(DTLSFlight flight) {
}

byte[] recordBytes = record.toByteArray();
if (payload.length + recordBytes.length > maxPayloadSize) {
if (payload.length + recordBytes.length > config.getMaxPayloadSize()) {
// can't add the next record, send current payload as datagram
DatagramPacket datagram = new DatagramPacket(payload, payload.length, flight.getPeerAddress()
.getAddress(), flight.getPeerAddress().getPort());
Expand Down Expand Up @@ -568,7 +579,7 @@ private void sendFlight(DTLSFlight flight) {
private void handleTimeout(DTLSFlight flight) {

// set DTLS retransmission maximum
final int max = max_retransmit;
final int max = config.getMaxRetransmit();

// check if limit of retransmissions reached
if (flight.getTries() < max) {
Expand Down Expand Up @@ -599,7 +610,7 @@ private void scheduleRetransmission(DTLSFlight flight) {
// calculate timeout using exponential back-off
if (flight.getTimeout() == 0) {
// use initial timeout
flight.setTimeout(retransmission_timeout);
flight.setTimeout(config.getRetransmissionTimeout());
} else {
// double timeout
flight.incrementTimeout();
Expand Down Expand Up @@ -654,4 +665,7 @@ private String addressToKey(InetSocketAddress address) {
return address.toString().split("/")[1];
}

public DTLSConnectorConfig getConfig() {
return config;
}
}
Loading

0 comments on commit 3a7bdee

Please sign in to comment.