Skip to content

Commit

Permalink
X509 and DTLS (#60)
Browse files Browse the repository at this point in the history
* Make X509 work

Get X509 to also work

* Add more badges

Fix some pointers

* Fix merge errors

* Correct merge again

Need to have a PSK set of algorithms
  • Loading branch information
jimsch authored Sep 23, 2019
1 parent d5afdfc commit 9caa545
Show file tree
Hide file tree
Showing 15 changed files with 162 additions and 94 deletions.
2 changes: 1 addition & 1 deletion CoAP.Example/CoAP.Client/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net45" />
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net45" requireReinstallation="true" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net45" />
</packages>
</packages>
11 changes: 8 additions & 3 deletions CoAP.NET/CoAP.Std10.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>


<Project Sdk="Microsoft.NET.Sdk">
Expand All @@ -7,8 +7,8 @@
<TargetFrameworks>netcoreapp2.0;net462;netstandard2.0</TargetFrameworks>
<PackageId>Com.AugustCellars.CoAP</PackageId>
<Id>Com.AugustCellars.CoAP</Id>
<PackageVersion>1.3.0.0</PackageVersion>
<Version>1.3.0.0</Version>
<PackageVersion>1.4.0.0</PackageVersion>
<Version>1.4.0.0</Version>
<Authors>Jim Schaad</Authors>
<Description>An implementation of the CBOR Object Signing and Encryption standards.</Description>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
Expand All @@ -19,6 +19,10 @@
This project is built on the CoAP.NET project of smeshlink which in turn is based on Californium. As this project did not seem to be maintained any more and I wanted a version in order to test the newer items that are coming out of the IETF CORE working group, I have captured it and started exanding it.
This project is NOT intended to be used for commercial purposes. It is intented only for research and verification work.

1.4
- Start using CoAPException rather than Exception for items being thrown by our code
- Test and fix code dealing with using DTLS with X509 certificates
- Recognize the "+udp" schema names as being permitted by the client endpoint classes
1.3
- Remove NetStandard 1.3 in favor of 2.0 and add NetCore 2.0
- Put in multcast support
Expand Down Expand Up @@ -112,6 +116,7 @@ This project is NOT intended to be used for commercial purposes. It is intented
<Compile Include="CoapClient.cs" />
<Compile Include="CoapConfig.cs" />
<Compile Include="CoapConstants.cs" />
<Compile Include="CoAPException.cs" />
<Compile Include="CoapObserveRelation.cs" />
<Compile Include="Code.cs" />
<Compile Include="Codec\DatagramReader.cs" />
Expand Down
24 changes: 24 additions & 0 deletions CoAP.NET/CoAPException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Com.AugustCellars.CoAP
{
public class CoAPException : Exception
{
public CoAPException()
{
}

public CoAPException(string message)
: base(message)
{
}

public CoAPException(string message, Exception inner)
: base(message, inner)
{
}

}
}
77 changes: 57 additions & 20 deletions CoAP.NET/CoapConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
* Please see README for more information.
*/

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace Com.AugustCellars.CoAP
{
Expand All @@ -21,94 +22,130 @@ public static class CoapConstants
/// <summary>
/// RFC 7252 CoAP version.
/// </summary>
public const Int32 Version = 0x01;
public const int Version = 0x01;

/// <summary>
/// The CoAP URI scheme.
/// </summary>
public const String UriScheme = "coap";
public const string UriScheme = "coap";

/// <summary>
/// The CoAPS URI scheme.
/// </summary>
public const String SecureUriScheme = "coaps";
public const string SecureUriScheme = "coaps";

/// <summary>
/// The default CoAP port for normal CoAP communication (not secure).
/// </summary>
public const Int32 DefaultPort = 5683;
public const int DefaultPort = 5683;

/// <summary>
/// The default CoAP port for secure CoAP communication (coaps).
/// </summary>
public const Int32 DefaultSecurePort = 5684;
public const int DefaultSecurePort = 5684;

/// <summary>
/// The initial time (ms) for a CoAP message
/// </summary>
public const Int32 AckTimeout = 2000;
public const int AckTimeout = 2000;

/// <summary>
/// The initial timeout is set
/// to a random number between RESPONSE_TIMEOUT and (RESPONSE_TIMEOUT *
/// RESPONSE_RANDOM_FACTOR)
/// </summary>
public const Double AckRandomFactor = 1.5D;
public const double AckRandomFactor = 1.5D;

/// <summary>
/// The max time that a message would be retransmitted
/// </summary>
public const Int32 MaxRetransmit = 4;
public const int MaxRetransmit = 4;

/// <summary>
/// Default block size used for block-wise transfers
/// </summary>
public const Int32 DefaultBlockSize = 512;
public const int DefaultBlockSize = 512;
// public const Int32 MessageCacheSize = 32;
// public const Int32 ReceiveBufferSize = 4096;
// public const Int32 DefaultOverallTimeout = 100000;

/// <summary>
/// Default URI for wellknown resource
/// </summary>
public const String DefaultWellKnownURI = "/.well-known/core";
public const string DefaultWellKnownURI = "/.well-known/core";

// public const Int32 TokenLength = 8;

/// <summary>
/// Max Age value to use if not on message
/// </summary>
public const Int32 DefaultMaxAge = 60;
public const int DefaultMaxAge = 60;

/// <summary>
/// The number of notifications until a CON notification will be used.
/// </summary>
public const Int32 ObservingRefreshInterval = 10;
public const int ObservingRefreshInterval = 10;

/// <summary>
/// EmptyToken value to use if no token provided.
/// </summary>
public static readonly Byte[] EmptyToken = new Byte[0];
public static readonly byte[] EmptyToken = new byte[0];

/// <summary>
/// The lowest value of a request code.
/// </summary>
public const Int32 RequestCodeLowerBound = 1;
public const int RequestCodeLowerBound = 1;

/// <summary>
/// The highest value of a request code.
/// </summary>
public const Int32 RequestCodeUpperBound = 31;
public const int RequestCodeUpperBound = 31;

/// <summary>
/// The lowest value of a response code.
/// </summary>
public const Int32 ResponseCodeLowerBound = 64;
public const int ResponseCodeLowerBound = 64;

/// <summary>
/// The highest value of a response code.
/// </summary>
public const Int32 ResponseCodeUpperBound = 191;
public const int ResponseCodeUpperBound = 191;

/// <summary>
/// The lowest value of a signal code.
/// </summary>
public const Int32 SignalCodeLowerBound = 224;
public const int SignalCodeLowerBound = 224;

/// <summary>
/// The highest value of a signal code.
/// </summary>
public const Int32 SignalCodeUpperBound = 255;
public const int SignalCodeUpperBound = 255;
}

public class UriInformation
{
public string Name { get; }
public int DefaultPort { get; }
public enum TransportType { IP = 1 }

private TransportType Transport { get; }

public UriInformation(string name, int defaultPort, TransportType transportType)
{
Name = name;
DefaultPort = defaultPort;
Transport = transportType;
}

public static ReadOnlyDictionary<string, UriInformation> UriDefaults { get; } = new ReadOnlyDictionary<string, UriInformation>(
new Dictionary<string, UriInformation>() {
{"coap", new UriInformation("coap", 5683, TransportType.IP)},
{"coaps", new UriInformation("coaps", 5684, TransportType.IP)},
{"coap+udp", new UriInformation("coap+udp", 5683, TransportType.IP)},
{"coaps+udp", new UriInformation("coaps+udp", 5684, TransportType.IP)},
{"coap+tcp", new UriInformation("coap+tcp", 5683, TransportType.IP)},
{"coaps+tcp", new UriInformation("coaps+tcp", 5684, TransportType.IP)}
}
);
}
}
47 changes: 24 additions & 23 deletions CoAP.NET/DTLS/DTLSClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,28 @@
namespace Com.AugustCellars.CoAP.DTLS
{

class DtlsClient : DefaultTlsClient
public class DtlsClient : DefaultTlsClient
{
private readonly TlsPskIdentity _mPskIdentity;
private TlsSession _mSession;
public EventHandler<TlsEvent> TlsEventHandler;
private readonly TlsKeyPair _tlsKeyPair;

internal DtlsClient(TlsSession session, TlsPskIdentity pskIdentity)
public DtlsClient(TlsSession session, TlsPskIdentity pskIdentity)
{
_mSession = session;
_mPskIdentity = pskIdentity;
}

internal DtlsClient(TlsSession session, TlsKeyPair userKey)
public DtlsClient(TlsSession session, TlsKeyPair userKey)
{
_mSession = session;
_tlsKeyPair = userKey ?? throw new ArgumentNullException(nameof(userKey));
}

#if SUPPORT_TLS_CWT
public KeySet CwtTrustKeySet { get; set; }
internal DtlsClient(TlsSession session, TlsKeyPair tlsKey, KeySet cwtTrustKeys)
public DtlsClient(TlsSession session, TlsKeyPair tlsKey, KeySet cwtTrustKeys)
{
_mSession = session;
_tlsKeyPair = tlsKey ?? throw new ArgumentNullException(nameof(tlsKey));
Expand All @@ -62,11 +62,11 @@ public override int[] GetCipherSuites()

if (_tlsKeyPair != null) {
if (_tlsKeyPair.X509Certificate != null) {
i = new int[] {
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
};
}
i = new int[] {
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
};
}
#if SUPPORT_RPK
else if (_tlsKeyPair.PublicKey != null) {
i = new int[] {
Expand All @@ -77,23 +77,24 @@ public override int[] GetCipherSuites()
#endif
#if SUPPORT_TLS_CWT
else if (_tlsKeyPair.CertType == CertificateType.CwtPublicKey) {
i = new int[] {
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
};
}
i = new int[] {
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8
};
}
#endif
else {
// We should never get here
i = new int[0];
}
}
else {
i = new int[] {
CipherSuite.TLS_PSK_WITH_AES_128_CCM_8,
};
// We should never get here
i = new int[] {
CipherSuite.TLS_PSK_WITH_AES_128_CCM_8
};
}

TlsEvent e = new TlsEvent(TlsEvent.EventCode.GetCipherSuites) {
IntValues = i
};
Expand Down Expand Up @@ -204,7 +205,7 @@ public override TlsAuthentication GetAuthentication()
return auth;
}

throw new Exception("ICE");
throw new CoAPException("ICE");
}

private void MyTlsEventHandler(object sender, TlsEvent tlsEvent)
Expand Down Expand Up @@ -538,15 +539,15 @@ public virtual TlsCredentials GetClientCredentials(CertificateRequest certificat

SubjectPublicKeyInfo spi = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(param);

return new DefaultTlsSignerCredentials(_mContext, new RawPublicKey(spi), privKey, new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.ecdsa));
}

return new DefaultTlsSignerCredentials(_mContext, new RawPublicKey(spi), privKey, new SignatureAndHashAlgorithm(HashAlgorithm.sha256, SignatureAlgorithm.ecdsa));
}

}
#endif
#if SUPPORT_TLS_CWT

else if (TlsKey.CertType == CertificateType.CwtPublicKey) {
OneKey k = TlsKey.PublicCwt.Cnf.Key;
OneKey k = TlsKey.PublicCwt.Cnf.Key;
if (k.HasKeyType((int) GeneralValuesInt.KeyType_EC2) &&
k.HasAlgorithm(AlgorithmValues.ECDSA_256)) {

Expand Down
2 changes: 1 addition & 1 deletion CoAP.NET/DTLS/DTLSClientEndPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private DTLSClientEndPoint(DTLSClientChannel channel, ICoapConfig config) : base
// Stack.Remove("Reliability");
MessageEncoder = UdpCoapMesageEncoder;
MessageDecoder = UdpCoapMessageDecoder;
EndpointSchema = "coaps";
EndpointSchema = new []{"coaps", "coaps+udp"};
channel.TlsEventHandler += OnTlsEvent;
}

Expand Down
2 changes: 1 addition & 1 deletion CoAP.NET/DTLS/DTLSEndPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public DTLSEndPoint(DTLSChannel channel, ICoapConfig config) : base(channel, con
Stack.Remove(Stack.Get("Reliability"));
MessageEncoder = UdpCoapMesageEncoder;
MessageDecoder = UdpCoapMessageDecoder;
EndpointSchema = "coaps";
EndpointSchema = new []{"coaps", "coaps+udp"};
channel.TlsEventHandler += OnTlsEvent;
}

Expand Down
4 changes: 3 additions & 1 deletion CoAP.NET/DTLS/DtlsServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class DtlsServer : DefaultTlsServer

public KeySet CwtTrustKeySet { get; set; }

internal DtlsServer(TlsKeyPairSet serverKeys, KeySet userKeys)
public DtlsServer(TlsKeyPairSet serverKeys, KeySet userKeys)
{
_serverKeys = serverKeys;
_userKeys = userKeys;
Expand Down Expand Up @@ -390,6 +390,8 @@ public override void NotifyClientCertificate(Certificate clientCertificate)

AuthenticationCertificate = (Certificate) clientCertificate;

AuthenticationCertificate = (Certificate) clientCertificate;

}
#endif

Expand Down
Loading

0 comments on commit 9caa545

Please sign in to comment.