Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support client bootstrapping to receive OSCORE security information #950

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*
* Contributors:
* Sierra Wireless - initial API and implementation
* Rikard Höglund (RISE) - additions to support OSCORE
*******************************************************************************/
package org.eclipse.leshan.server.bootstrap.demo;

Expand All @@ -22,9 +23,14 @@
import java.util.Iterator;
import java.util.Map;

import org.eclipse.californium.oscore.HashMapCtxDB;
import org.eclipse.californium.oscore.OSCoreCtx;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.core.util.SecurityUtil;
import org.eclipse.leshan.server.OscoreHandler;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig.OscoreObject;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig.ServerSecurity;
import org.eclipse.leshan.server.bootstrap.BootstrapConfigStore;
import org.eclipse.leshan.server.bootstrap.EditableBootstrapConfigStore;
Expand Down Expand Up @@ -88,6 +94,32 @@ public Iterator<SecurityInfo> getAllByEndpoint(String endpoint) {

BootstrapConfig bsConfig = bootstrapConfigStore.get(endpoint, null, null);

// TODO this should be done via OSCORE store ?
// Extract OSCORE security info
if (bsConfig != null && bsConfig.oscore != null && !bsConfig.oscore.isEmpty()) {
LOG.trace("Looking for OSCORE security info for endpoint {}", endpoint);

// First find the context for this endpoint
for (ServerSecurity bsEntryValue : bsConfig.security.values()) {
// Only find contexts for BS-Client connections
Integer bsOscoreSecurityMode = bsEntryValue.oscoreSecurityMode;
if (!bsEntryValue.bootstrapServer || bsOscoreSecurityMode == null) {
continue;
}

OscoreObject value = bsConfig.oscore.get(bsOscoreSecurityMode);

HashMapCtxDB db = OscoreHandler.getContextDB();
byte[] rid = Hex.decodeHex(value.oscoreRecipientId.toCharArray());
OSCoreCtx ctx = db.getContext(rid);

// Create the security info (will re-add the context to the db)
SecurityInfo securityInfo = SecurityInfo.newOSCoreInfo(endpoint, ctx);

return Arrays.asList(securityInfo).iterator();
}
}

if (bsConfig == null || bsConfig.security == null)
return null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* Sierra Wireless - initial API and implementation
* Achim Kraus (Bosch Software Innovations GmbH) - add parameter for
* configuration filename
* Rikard Höglund (RISE) - additions to support OSCORE
*******************************************************************************/

package org.eclipse.leshan.server.bootstrap.demo;
Expand All @@ -37,6 +38,7 @@
import org.eclipse.californium.core.network.config.NetworkConfig;
import org.eclipse.californium.core.network.config.NetworkConfig.Keys;
import org.eclipse.californium.elements.util.SslContextUtil;
import org.eclipse.californium.oscore.OSCoreCoapStackFactory;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHolder;
Expand All @@ -46,6 +48,7 @@
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.model.StaticModel;
import org.eclipse.leshan.core.util.SecurityUtil;
import org.eclipse.leshan.server.OscoreHandler;
import org.eclipse.leshan.server.bootstrap.BootstrapConfigurationStoreAdapter;
import org.eclipse.leshan.server.bootstrap.demo.servlet.BootstrapServlet;
import org.eclipse.leshan.server.bootstrap.demo.servlet.ServerServlet;
Expand Down Expand Up @@ -124,12 +127,14 @@ public static void main(String[] args) {

final StringBuilder trustStoreChapter = new StringBuilder();
trustStoreChapter.append("\n .");
trustStoreChapter.append("\n URI format: file://<path-to-trust-store-file>#<hex-strore-password>#<alias-pattern>");
trustStoreChapter
.append("\n URI format: file://<path-to-trust-store-file>#<hex-strore-password>#<alias-pattern>");
trustStoreChapter.append("\n .");
trustStoreChapter.append("\n Where:");
trustStoreChapter.append("\n - path-to-trust-store-file is path to pkcs12 trust store file");
trustStoreChapter.append("\n - hex-store-password is HEX formatted password for store");
trustStoreChapter.append("\n - alias-pattern can be used to filter trusted certificates and can also be empty to get all");
trustStoreChapter.append(
"\n - alias-pattern can be used to filter trusted certificates and can also be empty to get all");
trustStoreChapter.append("\n .");
trustStoreChapter.append("\n Default: All certificates are trusted which is only OK for a demo.");

Expand Down Expand Up @@ -283,7 +288,8 @@ public static void main(String[] args) {

// check input exists
if (!input.exists()) {
System.err.println("Failed to load trust store - file or directory does not exist : " + input.toString());
System.err.println(
"Failed to load trust store - file or directory does not exist : " + input.toString());
formatter.printHelp(USAGE, options);
return;
}
Expand Down Expand Up @@ -322,6 +328,11 @@ public static void createAndStartServer(String webAddress, int webPort, String l
String secureLocalAddress, Integer secureLocalPort, String modelsFolderPath, String configFilename,
boolean supportDeprecatedCiphers, PublicKey publicKey, PrivateKey privateKey, X509Certificate certificate,
List<Certificate> trustStore) throws Exception {

// Enable OSCORE stack (fine to do even when using DTLS or only CoAP)
// TODO OSCORE : this should be done in DefaultEndpointFactory ?
OSCoreCoapStackFactory.useAsDefault(OscoreHandler.getContextDB());

// Create Models
List<ObjectModel> models = ObjectLoader.loadDefault();
if (modelsFolderPath != null) {
Expand Down
1 change: 1 addition & 0 deletions leshan-bsserver-demo/src/main/resources/webapp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<script src="tag/psk-input.tag" type="riot/tag"></script>
<script src="tag/rpk-input.tag" type="riot/tag"></script>
<script src="tag/x509-input.tag" type="riot/tag"></script>
<script src="tag/oscore-input.tag" type="riot/tag"></script>
<script src="tag/bootstrap-modal.tag" type="riot/tag"></script>

<script src="js/bsconfigstore.js"></script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ var configFromRestToUI = function(config){
var security = config.security[i];
if (security.bootstrapServer){
newConfig.bs.push({security:security});

// add oscore object (if any) to bs
var oscoreObjectInstanceId = security.oscoreSecurityMode;
var oscore = config.oscore[oscoreObjectInstanceId];
if(oscore){
newConfig.bs.push({oscore:oscore});
}
}else{
newConfig.dm = [];
// search for DM information;
Expand All @@ -19,6 +26,13 @@ var configFromRestToUI = function(config){
if (!newConfig.dm){
newConfig.dm.push({security:security});
}

// add oscore object (if any) to dm
var oscoreObjectInstanceId = security.oscoreSecurityMode;
var oscore = config.oscore[oscoreObjectInstanceId];
if(oscore){
newConfig.dm.push({oscore:oscore});
}
}
}
return newConfig;
Expand All @@ -33,18 +47,27 @@ var configsFromRestToUI = function(configs){

//convert config from UI to rest API format:
var configFromUIToRest = function(config){
var newConfig = {servers:{}, security:{}};
var newConfig = {servers:{}, security:{}, oscore:{}};
var writingOscore = false;
for (var i = 0; i < config.bs.length; i++) {
var bs = config.bs[i];
newConfig.security[i] = bs.security;
newConfig.oscore[i] = bs.oscore;
writingOscore |= (bs.oscore != null);
}
for (var j = 0; j < config.dm.length; j++) {
var dm = config.dm[j];
newConfig.security[i+j] = dm.security;
delete dm.security;
newConfig.oscore[i+j] = dm.oscore;
writingOscore |= (dm.oscore != null);
delete dm.oscore;
newConfig.servers[j] = dm;
}
newConfig.toDelete = ["/0", "/1"]
if(writingOscore) {
newConfig.toDelete.push("/21");
}
return newConfig;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<securityconfig-input ref="lwserver" onchange={update} show={activetab.lwserver}
securi={ "coaps://" + location.hostname + ":5684" }
unsecuri= { "coap://" + location.hostname + ":5683" }
secmode = { {no_sec:true, psk:true, rpk:true, x509:true} }
secmode = { {no_sec:true, psk:true, rpk:true, x509:true, oscore:true} }
></securityconfig-input>
</div>
<div>
Expand All @@ -36,7 +36,7 @@
serverpubkey= {serversecurity.rpk.hexDer}
servercertificate= {serversecurity.certificate.hexDer}
disable = { {uri:true, serverpubkey:true, servercertificate:true}}
secmode = { {no_sec:true, psk:true,rpk:true, x509:true}}
secmode = { {no_sec:true, psk:true,rpk:true, x509:true, oscore:true}}
></securityconfig-input>
</div>

Expand Down Expand Up @@ -93,6 +93,36 @@
function submit(){
var lwserver = tag.refs.lwserver.get_value()
var bsserver = tag.refs.bsserver.get_value()

if(bsserver.secmode === "OSCORE") {
var bsserverOscore = bsserver.oscore;
var bsOscore =
{
oscoreMasterSecret : bsserverOscore.masterSecret,
oscoreSenderId : bsserverOscore.senderId,
oscoreRecipientId : bsserverOscore.recipientId,
oscoreAeadAlgorithm : bsserverOscore.aeadAlgorithm,
oscoreHmacAlgorithm : bsserverOscore.hkdfAlgorithm,
oscoreMasterSalt : bsserverOscore.masterSalt,
}
var bsOscoreSecurityMode = 0; // link to bs oscore object
bsserver.secmode = "NO_SEC"; // act as no_sec from here
}

if(lwserver.secmode === "OSCORE") {
var lwserverOscore = lwserver.oscore;
var dmOscore =
{
oscoreMasterSecret : lwserverOscore.masterSecret,
oscoreSenderId : lwserverOscore.senderId,
oscoreRecipientId : lwserverOscore.recipientId,
oscoreAeadAlgorithm : lwserverOscore.aeadAlgorithm,
oscoreHmacAlgorithm : lwserverOscore.hkdfAlgorithm,
oscoreMasterSalt : lwserverOscore.masterSalt,
}
var dmOscoreSecurityMode = 1; // link to dm oscore object
lwserver.secmode = "NO_SEC"; // act as no_sec from here
}

// add config to the store
bsConfigStore.add(endpoint.value, {
Expand All @@ -114,8 +144,10 @@
smsBindingKeyParam : [ ],
smsBindingKeySecret : [ ],
smsSecurityMode : "NO_SEC",
uri : lwserver.uri
}
uri : lwserver.uri,
oscoreSecurityMode : dmOscoreSecurityMode
},
oscore : dmOscore
}],
bs:[{
security : {
Expand All @@ -131,7 +163,9 @@
smsBindingKeySecret : [ ],
smsSecurityMode : "NO_SEC",
uri : bsserver.uri,
}
oscoreSecurityMode : bsOscoreSecurityMode
},
oscore : bsOscore
}]
});
$('#bootstrap-modal').modal('hide');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
<tr each={ config, endpoint in configs }>
<td>{ endpoint }</td>
<td>
<div each={ config.bs }>
<div each={ config.bs } if={ security }>
<p>
<strong>{ security.uri }</strong><br/>
security mode : {security.securityMode}<br/>
Expand All @@ -66,7 +66,7 @@
</div>
</td>
<td>
<div each={ config.dm }>
<div each={ config.dm } if={ security }>
<p>
<strong>{security.uri}</strong><br/>
security mode : {security.securityMode}<br/>
Expand Down
Loading