示例#1
0
        private string CreateApiKey()
        {
            var securityKey = GetSecurityKeyFromFrontend();
            var tempKey     = GetKey("Client_identity", securityKey);

            using (var client = new DTLSClientEndPoint(tempKey))
            {
                client.Start();

                Request r = Request.NewPost();
                r.URI = new Uri($"coaps://{hub}/15011/9063");
                r.SetPayload($"{{ \"9090\" : \"{ApplicationName}\" }}"); // escape hell; this translates to {"9090":"application"}

                r.Respond += (sender, e) => { Console.WriteLine(e.Response); };

                r.Send(client);
                var response = r.WaitForResponse(2 * 1000);

                if (response == null)
                {
                    throw new TimeoutException($"No reply while getting api key for {ApplicationName}");
                }
                Dictionary <string, string> values = GetJsonResponse(response);
                string apiKey;
                if (!values.TryGetValue("9091", out apiKey))
                {
                    throw new InvalidDataException($"Expected response with key 9091, got { string.Join(",", values.Keys.ToArray())}");
                }
                return(apiKey);
            }
        }
示例#2
0
        public TradfriAuth GenerateAppSecret(string GatewaySecret, string applicationName)
        {
            Response resp = new Response(StatusCode.Valid);

            OneKey authKey = new OneKey();

            authKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
            authKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(GatewaySecret)));
            authKey.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("Client_identity")));
            DTLSClientEndPoint ep = new DTLSClientEndPoint(authKey);

            ep.Start();

            Request r = new Request(Method.POST);

            r.SetUri($"coaps://{_gatewayIp}" + $"/{(int)TradfriConstRoot.Gateway}/{(int)TradfriConstAttr.Auth}/");
            r.EndPoint   = ep;
            r.AckTimeout = 5000;
            r.SetPayload($@"{{""{(int)TradfriConstAttr.Identity}"":""{applicationName}""}}");

            r.Send();
            resp = r.WaitForResponse();

            if ((int)resp.StatusCode != 201)
            {
                RequestException <Response> .ConvertToException(MapToHttpStatusCode(resp.StatusCode), resp.StatusCode.ToString(), resp.UriQuery, "", resp.ResponseText, resp);
            }

            return(Convert <TradfriAuth>(resp.PayloadString));
        }
示例#3
0
        public void Start()
        {
            var key = GetStoredKey();

            _client = new DTLSClientEndPoint(key);
            _client.Start();
        }
示例#4
0
        public static TradfriAuth GeneratePsk(string gatwayIp, string appName, string secret)
        {
            try
            {
                var authKey = new OneKey();
                authKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
                authKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(secret)));
                authKey.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("Client_identity")));
                var ep = new DTLSClientEndPoint(authKey);
                ep.Start();

                var request = new Request(Method.POST);
                request.SetUri($"coaps://{gatwayIp}" + $"/{(int)TradfriConstRoot.Gateway}/{(int)TradfriConstAttribute.Auth}/");
                request.EndPoint   = ep;
                request.AckTimeout = 5000;
                request.SetPayload($@"{{""{(int)TradfriConstAttribute.Identity}"":""{appName}""}}");

                request.Send();
                var resp = request.WaitForResponse(5000);
                if (resp == null)
                {
                    return(null);
                }

                return(JsonConvert.DeserializeObject <TradfriAuth>(resp.PayloadString));
            }
            catch (Exception)
            {
                throw;
            }
        }
        public TradFriAuth GeneratePSK(string GatewaySecret, string applicationName)
        {
            Response resp = new Response(StatusCode.Valid);

            try
            {
                OneKey authKey = new OneKey();
                authKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
                authKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(GatewaySecret)));
                authKey.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("Client_identity")));
                DTLSClientEndPoint ep = new DTLSClientEndPoint(authKey);
                ep.Start();

                Request r = new Request(Method.POST);
                r.SetUri($"coaps://{GatewayIp}" + $"/{(int)TradFriConstRoot.Gateway}/{(int)TradFriConstAttr.Auth}/");
                r.EndPoint   = ep;
                r.AckTimeout = 5000;
                r.SetPayload($@"{{""{(int)TradFriConstAttr.Identity}"":""{applicationName}""}}");

                r.Send();
                resp = r.WaitForResponse(5000);

                return(JsonConvert.DeserializeObject <TradFriAuth>(resp.PayloadString));
            }
            catch (Exception exception)
            {
                Console.WriteLine(exception);

                var content = JsonConvert.DeserializeObject <dynamic>(resp.PayloadString);
                return(new TradFriAuth());
            }
        }
示例#6
0
        public IGateway Connect(string psk)
        {
            _logger.LogInformation($"Connecting to {_ipAddress} as \"{_clientIdentity}\" with PSK \"{psk}\"");

            var authKey = new OneKey();

            authKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
            authKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(psk)));
            authKey.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes(_clientIdentity)));

            var clientEndPoint = new DTLSClientEndPoint(authKey);

            clientEndPoint.Start();

            return(new Gateway(clientEndPoint, new Uri($"coaps://{_ipAddress}"), _logger));
        }
示例#7
0
        public void Connect()
        {
            OneKey userKey = new OneKey();

            userKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
            userKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(PreSharedKey)));

            DTLSClientEndPoint ep = new DTLSClientEndPoint(userKey);
            CoapClient         cc = new CoapClient(new Uri($"coaps://{GatewayIp}"))
            {
                EndPoint = ep
            };

            ep.Start();
            Client = cc;
        }
        public void ConnectPSK(string GatewaySecret)
        {
            OneKey authKey = new OneKey();

            authKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
            authKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(GatewaySecret)));

            DTLSClientEndPoint ep = new DTLSClientEndPoint(authKey);

            (Implementation as CoapImplementation)._coapClient = new CoapClient(new Uri($"coaps://{_gatewayIp}"))
            {
                EndPoint = ep
            };

            ep.Start();
        }
示例#9
0
        public string GeneratePsk(string gatewaySecret)
        {
            try
            {
                _logger.LogInformation($"Connecting to {_ipAddress} as \"{_clientIdentity}\" to generate new PSK");

                var authKey = new OneKey();
                authKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
                authKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(gatewaySecret)));
                authKey.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("Client_identity")));
                using (var clientEndPoint = new DTLSClientEndPoint(authKey))
                {
                    clientEndPoint.Start();

                    var authRequest = new AuthRequest {
                        Identity = _clientIdentity
                    };

                    var request = new Request(Method.POST)
                    {
                        EndPoint   = clientEndPoint,
                        AckTimeout = 5000
                    };

                    request.SetUri($"coaps://{_ipAddress}/{(int)RequestRoot.Gateway}/{(int)TradfriAttribute.Auth}/");
                    string json = Json.Serialize(authRequest);
                    request.SetPayload(json);
                    request.Send();

                    Response response = request.WaitForResponse(5000);
                    if (response == null)
                    {
                        throw new TradfriException("No response from gateway");
                    }

                    AuthResponse authResponse = Json.Deserialize <AuthResponse>(response.PayloadString);

                    _logger.LogInformation($"PSK generated: \"{authResponse.Psk}\"");

                    return(authResponse.Psk);
                }
            }
            catch (Exception exception)
            {
                throw new TradfriException("Failed during authentication.", exception);
            }
        }
示例#10
0
        public void ConnectAppKey(string appKey, string applicationName)
        {
            OneKey authKey = new OneKey();

            authKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
            authKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(appKey)));
            authKey.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes(applicationName)));

            DTLSClientEndPoint ep = new DTLSClientEndPoint(authKey);
            CoapClient         cc = new CoapClient(new Uri($"coaps://{_gatewayIp}"))
            {
                EndPoint = ep
            };

            ep.Start();

            _coapClient = cc;
        }
示例#11
0
        public void Connect()
        {
            OneKey authKey = new OneKey();

            authKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
            authKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(Psk)));
            authKey.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes(_name)));

            DTLSClientEndPoint ep = new DTLSClientEndPoint(authKey);
            CoapClient         cc = new CoapClient(new Uri($"coaps://{_gatewayIp}"))
            {
                EndPoint = ep
            };

            ep.Start();

            GatewayController gc = new GatewayController(cc);

            GatewayInfo = gc.GetGatewayInfo();
            _client     = cc;
        }
示例#12
0
        /// <summary>
        /// Initializes the connection with the LAN controller
        /// </summary>
        /// <param name="endPoint">IP endpoint of the IKEA Tradfri LAN Controller</param>
        /// <param name="securityKey">Private security key found on the bottom of the LAN Controller</param>
        public static void InitializeConnection(IPEndPoint endPoint, string securityKey)
        {
            if (endPoint == null)
            {
                throw new ArgumentNullException(nameof(endPoint));
            }

            if (string.IsNullOrWhiteSpace(securityKey))
            {
                throw new ArgumentNullException(nameof(securityKey));
            }

            try
            {
                _controllerAddress     = endPoint;
                _connectionSecurityKey = securityKey;

                OneKey userKey = new OneKey();
                userKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
                userKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(_connectionSecurityKey)));

                CoAPEndPoint coapEndPoint = new DTLSClientEndPoint(userKey);
                _coapClient = new CoapClient(new Uri($"coaps://{_controllerAddress.Address}:{_controllerAddress.Port}/"))
                {
                    EndPoint = coapEndPoint
                };
                coapEndPoint.Start();

                // there has to be a GET operation to successfully open the connection

                _coapClient.UriPath = CommandConstants.UniqueDevices + "/";
                _coapClient.Get();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
示例#13
0
        public void Process(Request request, Response response)
        {
            //  Is this processable?
            if (response.StatusCode != StatusCode.Unauthorized ||
                response.ContentFormat != 65008)
            {
                return;
            }

            try {
                //  Init from the response data
                Oauth.AsInfo info = new Oauth.AsInfo(response.Payload);

                //  Missage this as needed.
                string aSServer = info.ASServer;

                //  Need to build one from scratch

                if (!authServers.ContainsKey(info.ASServer))
                {
                    Console.WriteLine($"No security association is setup for {info.ASServer}");
                    return;
                }

                AuthServerInfo asi = authServers[info.ASServer];

                if (asi.ClientLink == null)
                {
                    asi.ClientLink = new CoapClient(new Uri(info.ASServer));
                    if (asi.UseDTLS)
                    {
                        asi.ClientLink.EndPoint = new DTLSClientEndPoint(asi.TlsKey);
                        asi.ClientLink.EndPoint.Start();
                    }
                }

                // M00BUG - need to make sure that this will pickup a port number if given.
                string audience = $"{request.URI.Scheme}://{request.URI.Authority}";

                Oauth.Request myRequest = new Oauth.Request("client_credentials")
                {
                    Audience = audience,
                    Scope    = CBORObject.FromObject(request.UriPath)
                };

                myRequest.Profile = Profile;

                byte[] payload = myRequest.EncodeToBytes();

                asi.ClientLink.Timeout = 2 * 60 * 1000;
                Response asResponse = asi.ClientLink.Post(payload, MediaType.ApplicationCbor);


                if (asResponse == null)
                {
                    asi.ClientLink.EndPoint.Stop();
                    asi.ClientLink = null;
                    Console.WriteLine($"Timed out requesting token from {info.ASServer}");
                    return;
                }

                if (asResponse.StatusCode != StatusCode.Created)
                {
                    //  We had an error condition appear
                    if (asResponse.Payload != null)
                    {
                        CBORObject obj       = CBORObject.DecodeFromBytes(asResponse.Payload);
                        int        error     = obj["error"].AsInt32();
                        string     errorText = "";
                        if (obj.ContainsKey("error_description"))
                        {
                            errorText = obj["error_description"].AsString();
                        }
                        Console.WriteLine(
                            $"Recieved an error {asResponse.StatusCode} with error no = {error} and description '{errorText}'");
                    }
                    else
                    {
                        Console.WriteLine($"Received and error {asResponse.StatusCode} from the AS but no text");
                    }

                    return;
                }

                Oauth.Response myResponse = new Oauth.Response(asResponse.Payload);


                // default profile for client -
#if false
                if (Profile != null && myResponse.Profile != Profile)
                {
                    Console.WriteLine("AS Server returned an unexpected profile {0}", myResponse.Profile);
                    return;
                }
#endif
                myResponse.Profile = Oauth.ProfileIds.Coap_Dtls;

                //  Post token to resource server

                CoapClient client = new CoapClient();
                client.Uri     = new Uri($"coap://{request.URI.Authority}/authz-info");
                client.Timeout = 10000; // 1 second
                Response tknResponse = client.Post(myResponse.Token, MediaType.ApplicationCbor);
                if (tknResponse == null)
                {
                    Console.WriteLine("Post of token failed w/ no response");
                    return;
                }

                if (tknResponse.StatusCode != StatusCode.Created)
                {
                    Console.WriteLine($"Post of token failed with error {tknResponse.StatusCode}");
                    return;
                }

                Confirmation cnf = myResponse.Confirmation;


                Request newRequest = new Request(request.Method);
                newRequest.Payload = request.Payload;
                newRequest.SetOptions(request.GetOptions());

                DTLSClientEndPoint endPoint = null;

                switch (myResponse.Profile)
                {
                case Oauth.ProfileIds.Coap_Dtls: {
                    OneKey key = cnf.Key;
                    endPoint = new DTLSClientEndPoint(cnf.Key);
                    endPoint.Start();

                    newRequest.EndPoint = endPoint;
                    newRequest.URI      = new Uri($"coaps://{request.URI.Authority}/{request.URI.AbsolutePath}");
                }
                break;

                case Oauth.ProfileIds.Coap_Oscore: {
                    OneKey oneKey = cnf.Key;
                    byte[] salt   = null;
                    if (oneKey.ContainsName("slt"))
                    {
                        salt = oneKey[CBORObject.FromObject("slt")].GetByteString();
                    }
                    CBORObject alg = null;
                    if (oneKey.ContainsName(CoseKeyKeys.Algorithm))
                    {
                        alg = oneKey[CoseKeyKeys.Algorithm];
                    }
                    CBORObject kdf = null;
                    if (oneKey.ContainsName(CBORObject.FromObject("kdf")))
                    {
                        kdf = oneKey[CBORObject.FromObject("kdf")];
                    }

                    SecurityContext oscoapContext = SecurityContext.DeriveContext(
                        oneKey[CoseKeyParameterKeys.Octet_k].GetByteString(),
                        oneKey[CBORObject.FromObject("sid")].GetByteString(),
                        oneKey[CBORObject.FromObject("rid")].GetByteString(),
                        salt, alg, kdf);
                    newRequest.OscoapContext = oscoapContext;
                }
                break;

                default:
                    Console.WriteLine("Cannot rewrite as we don't recognize the profile");
                    return;
                }

                newRequest.Respond += delegate(Object sender, ResponseEventArgs e)
                {
                    Response responseN = e.Response;
                    if (responseN == null)
                    {
                        Console.WriteLine("Request timeout");
                    }
                    else
                    {
                        Console.WriteLine(Utils.ToString(responseN));
                        Console.WriteLine("Time (ms): " + responseN.RTT);
                    }

                    if (endPoint != null)
                    {
                        endPoint.Stop();
                    }
                };

                newRequest.Send();
            }
            catch (Exception e) {
                Console.WriteLine("Error processing AceAuthz - " + e.ToString());
            }
        }
示例#14
0
        public static void Main(String[] args)
        {
            String             method     = null;
            Uri                uri        = null;
            String             payload    = null;
            Boolean            loop       = false;
            Boolean            byEvent    = false;
            OneKey             authKey    = null;
            SecurityContext    oscoap     = null;
            SecurityContextSet contextSet = null;

            if (args.Length == 0)
            {
                PrintUsage();
            }

            Int32 index = 0;

            foreach (String arg in args)
            {
                if (arg[0] == '-')
                {
                    if (arg.Equals("-l"))
                    {
                        loop = true;
                    }
                    else if (arg.Equals("-e"))
                    {
                        byEvent = true;
                    }
                    else if (arg.StartsWith("-psk="))
                    {
                        if (authKey == null)
                        {
                            authKey = new OneKey();
                            authKey.Add(COSE.CoseKeyKeys.KeyType, COSE.GeneralValues.KeyType_Octet);
                        }
                        authKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(arg.Substring(5))));
                    }
                    else if (arg.StartsWith("-psk-id="))
                    {
                        if (authKey == null)
                        {
                            authKey = new OneKey();
                            authKey.Add(COSE.CoseKeyKeys.KeyType, COSE.GeneralValues.KeyType_Octet);
                        }
                        authKey.Add(COSE.CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes(arg.Substring(8))));
                    }
                    else if (arg.StartsWith("-oscoap="))
                    {
                        if (contextSet == null)
                        {
                            Console.WriteLine("Must have -oscoap-data before -oscoap");
                            Environment.Exit(1);
                        }

                        byte[] id = Encoding.UTF8.GetBytes(arg.Substring(8));

                        oscoap = contextSet.FindByGroupId(id).First();
                    }
                    else if (arg.StartsWith("-oscoap-data="))
                    {
                        contextSet = LoadContextSet(arg.Substring(13));
                    }
                    else
                    {
                        Console.WriteLine("Unknown option: " + arg);
                    }
                }
                else
                {
                    switch (index)
                    {
                    case 0:
                        method = arg.ToUpper();
                        break;

                    case 1:
                        try
                        {
                            uri = new Uri(arg);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Failed parsing URI: " + ex.Message);
                            Environment.Exit(1);
                        }
                        break;

                    case 2:
                        payload = arg;
                        break;

                    default:
                        Console.WriteLine("Unexpected argument: " + arg);
                        break;
                    }
                    index++;
                }
            }

            if (method == null || uri == null)
            {
                PrintUsage();
            }

            Request request = NewRequest(method);

            if (request == null)
            {
                Console.WriteLine("Unknown method: " + method);
                Environment.Exit(1);
            }

            if ("OBSERVE".Equals(method))
            {
                request.MarkObserve();
                loop = true;
            }
            else if ("DISCOVER".Equals(method) &&
                     (String.IsNullOrEmpty(uri.AbsolutePath) || uri.AbsolutePath.Equals("/")))
            {
                uri = new Uri(uri, "/.well-known/core");
            }

            CoAPEndPoint ep = null;

            if (uri.Scheme == "coaps")
            {
                if (authKey == null)
                {
                    Console.WriteLine("Must use the -psk option to provide an authentication key");
                    return;
                }
                ep = new DTLSClientEndPoint(authKey);
                ep.Start();
                request.EndPoint = ep;
            }

            request.URI = uri;
            if (payload != null)
            {
                request.SetPayload(payload, MediaType.TextPlain);
            }
            if (oscoap != null)
            {
                request.OscoapContext = oscoap;
            }

            // uncomment the next line if you want to specify a draft to use
            // request.EndPoint = CoAP.Net.EndPointManager.Draft13;

            Console.WriteLine(Utils.ToString(request));

            try
            {
                if (byEvent)
                {
                    request.Respond += delegate(Object sender, ResponseEventArgs e)
                    {
                        Response response = e.Response;
                        if (response == null)
                        {
                            Console.WriteLine("Request timeout");
                        }
                        else
                        {
                            Console.WriteLine(Utils.ToString(response));
                            Console.WriteLine("Time (ms): " + response.RTT);
                        }
                        if (!loop)
                        {
                            if (ep != null)
                            {
                                ep.Stop();
                            }
                            Environment.Exit(0);
                        }
                    };
                    request.Send();
                    while (true)
                    {
                        Console.ReadKey();
                    }
                }
                else
                {
                    // uncomment the next line if you need retransmission disabled.
                    // request.AckTimeout = -1;

                    request.Send();

                    do
                    {
                        Console.WriteLine("Receiving response...");

                        Response response = null;
                        response = request.WaitForResponse();

                        if (response == null)
                        {
                            Console.WriteLine("Request timeout");
                            break;
                        }
                        else
                        {
                            Console.WriteLine(Utils.ToString(response));
                            Console.WriteLine("Time elapsed (ms): " + response.RTT);

                            if (response.ContentType == MediaType.ApplicationLinkFormat)
                            {
                                IEnumerable <WebLink> links = LinkFormat.Parse(response.PayloadString);
                                if (links == null)
                                {
                                    Console.WriteLine("Failed parsing link format");
                                    Environment.Exit(1);
                                }
                                else
                                {
                                    Console.WriteLine("Discovered resources:");
                                    foreach (var link in links)
                                    {
                                        Console.WriteLine(link);
                                    }
                                }
                            }
                        }
                    } while (loop);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Failed executing request: " + ex.Message);
                Console.WriteLine(ex);
                if (ep != null)
                {
                    ep.Stop();
                }
                Environment.Exit(1);
            }
        }
示例#15
0
        public void Process(Request request, Response response)
        {
            //  Is this processable?
            if (response.StatusCode != StatusCode.Unauthorized /* ||
                                                                * !(response.ContentFormat == 65008 || response.ContentFormat == MediaType.ApplicationCbor)*/)
            {
                return;
            }

            try {
                //  Init from the response data
                Oauth.AsInfo info = new Oauth.AsInfo(response.Payload);

                //  Massage this as needed.
                string aSServer = info.ASServer;

                //  Need to build one from scratch

                if (!authServers.ContainsKey(info.ASServer))
                {
                    Console.WriteLine($"No security association is setup for {info.ASServer}");
                    return;
                }

                AuthServerInfo asi = authServers[info.ASServer];

                if (asi.ClientLink == null)
                {
                    asi.ClientLink = new CoapClient(new Uri(info.ASServer));
                    if (asi.UseDTLS)
                    {
                        asi.ClientLink.EndPoint = new DTLSClientEndPoint(asi.TlsKey);
                        asi.ClientLink.EndPoint.Start();
                    }
                    else
                    {
                        if (asi.ClientLink.Uri.Scheme == "coaps")
                        {
                            asi.ClientLink.Uri = new Uri($"coap://{asi.ClientLink.Uri.Authority}/{asi.ClientLink.UriPath}");
                        }
                        asi.ClientLink.OscoreContext = asi.OscoreKey;
                    }
                }

                // M00BUG - need to make sure that this will pickup a port number if given.
                string audience = $"{request.URI.Scheme}://{request.URI.Authority}";
                if (UseAudience != null)
                {
                    audience = UseAudience;
                }

                Oauth.Request myRequest = new Oauth.Request("client_credentials")
                {
                    Audience = audience,
                    Scope    = (UseScopeValue == null) ? CBORObject.FromObject(request.UriPath) : UseScopeValue
                };

                if (ClientKey != null)
                {
                    myRequest.Cnf = new Confirmation();
                    switch (ClientKeyType)
                    {
                    case 1: // kid
                        myRequest.Cnf.Kid = ClientKey.PrivateKey[CoseKeyKeys.KeyIdentifier].GetByteString();
                        break;

                    case 2: // key
                        myRequest.Cnf.Key = ClientKey.PrivateKey;
                        break;
                    }
                }

                Response asResponse;
                if (asi.UseJSON)
                {
                    string jsonPayload = myRequest.EncodeToString();
                    asi.ClientLink.Timeout = 2 * 60 * 1000;
                    asResponse             = asi.ClientLink.Post(jsonPayload, MediaType.ApplicationJson);
                }
                else
                {
                    byte[] payload = myRequest.EncodeToBytes();
                    asi.ClientLink.Timeout = 2 * 60 * 1000;
                    asResponse             = asi.ClientLink.Post(payload, MediaType.ApplicationCbor);
                }


                if (asResponse == null)
                {
                    asi.ClientLink.EndPoint.Stop();
                    asi.ClientLink = null;
                    Console.WriteLine($"Timed out requesting token from {info.ASServer}");
                    return;
                }

                if (asResponse.StatusCode != StatusCode.Created)
                {
                    //  We had an error condition appear
                    if (asResponse.Payload != null)
                    {
                        CBORObject obj       = CBORObject.DecodeFromBytes(asResponse.Payload);
                        int        error     = obj[/*"error"*/ CBORObject.FromObject(15)].AsInt32();
                        string     errorText = "";
                        if (obj.ContainsKey(/*"error_description")*/ CBORObject.FromObject(16)))
                        {
                            errorText = obj[CBORObject.FromObject(16)].AsString();
                        }
                        Console.WriteLine(
                            $"Received an error {asResponse.StatusCode} with error no = {error} and description '{errorText}'");
                    }
                    else
                    {
                        Console.WriteLine($"Received and error {asResponse.StatusCode} from the AS but no text");
                    }

                    return;
                }

                Oauth.Response myResponse = Oauth.Response.FromCBOR(asResponse.Payload);


                // default profile for client -
#if false
                if (Profile != null && myResponse.Profile != Profile)
                {
                    Console.WriteLine("AS Server returned an unexpected profile {0}", myResponse.Profile);
                    return;
                }
#endif
                if (!myResponse.ContainsKey(Oauth.Oauth_Parameter.Profile))
                {
                    myResponse.Profile = Oauth.ProfileIds.Coap_Dtls;
                }

                //  Post token to resource server

                byte[][] OscoreSalts = null;

                if (!SendTokenAsPsk)
                {
                    CoapClient client = new CoapClient();
                    client.Uri     = new Uri($"coap://{request.URI.Authority}/authz-info");
                    client.Timeout = 10000; // 1 second

                    Response tknResponse = null;
                    if (myResponse.Profile == Oauth.ProfileIds.Coap_Oscore)
                    {
                        byte[]     mySalt = new byte[] { 32, 33, 34, 35, 36, 37, 38 };
                        CBORObject post   = CBORObject.NewMap();
                        post.Add((CBORObject)Oauth.Oauth_Parameter.Access_Token, myResponse.Token);
                        post.Add((CBORObject)Oauth.Oauth_Parameter.CNonce, mySalt);
                        tknResponse = client.Post(post.EncodeToBytes(), MediaType.ApplicationAceCbor);
                        OscoreSalts = new byte[][] { mySalt, null };
                    }
                    else
                    {
                        tknResponse = client.Post(myResponse.Token, MediaType.ApplicationOctetStream);
                    }

                    if (tknResponse == null)
                    {
                        Console.WriteLine("Post of token failed w/ no response");
                        return;
                    }

                    if (tknResponse.StatusCode != StatusCode.Created)
                    {
                        Console.WriteLine($"Post of token failed with error {tknResponse.StatusCode}");
                        return;
                    }

                    if (tknResponse.ContentType == MediaType.ApplicationAceCbor)
                    {
                        CBORObject post = CBORObject.DecodeFromBytes(tknResponse.Payload);
                        if (post.ContainsKey((CBORObject)Oauth.Oauth_Parameter.Client_id))
                        {
                            //  Retrieve
                        }

                        if (post.ContainsKey((CBORObject)Oauth.Oauth_Parameter.CNonce))
                        {
                            if (OscoreSalts == null)
                            {
                                throw new Exception("Internal Error - salts");
                            }
                            OscoreSalts[1] = post[(CBORObject)Oauth.Oauth_Parameter.CNonce].GetByteString();
                        }
                    }
                }

                Confirmation cnf = myResponse.Confirmation;
                if (cnf == null)
                {
                    if (ClientKey == null)
                    {
                        Console.WriteLine("Returned a token but I don't know what key I should be using");
                        return;
                    }
                    cnf = new Confirmation(ClientKey.PrivateKey);
                }

                if (cnf.Kid != null)
                {
                    Console.WriteLine("Missing code - how do we map a kid to a real key?");
                    return;
                }

                Request newRequest = new Request(request.Method);
                newRequest.Payload = request.Payload;
                newRequest.SetOptions(request.GetOptions());

                DTLSClientEndPoint endPoint = null;

                switch (myResponse.Profile)
                {
                case Oauth.ProfileIds.Coap_Dtls: {
                    OneKey key = cnf.Key;
                    LastKeyFound = cnf.Key;
                    if (SendTokenAsPsk)
                    {
                        cnf.Key.AsCBOR().Set(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(myResponse.Token));
                    }

                    endPoint = new DTLSClientEndPoint(cnf.Key);
                    endPoint.Start();

                    if (myResponse.RsConfirmation != null)
                    {
                        ResourceInfo rsInfo = new ResourceInfo(myResponse.RsConfirmation.Key);
                        endPoint.TlsEventHandler += rsInfo.CheckRPK;
                    }

                    newRequest.EndPoint = endPoint;
                    newRequest.URI      = new Uri($"coaps://{request.URI.Authority}/{request.URI.AbsolutePath}");
                }
                break;

                case Oauth.ProfileIds.Coap_Oscore: {
                    CBORObject oscoreContext = cnf.AsCBOR[CBORObject.FromObject(Confirmation.ConfirmationIds.COSE_OSCORE)];

                    byte[] salt = new byte[0];
                    if (oscoreContext.ContainsKey(CBORObject.FromObject(6)))
                    {
                        salt = oscoreContext[CBORObject.FromObject(CBORObject.FromObject(6))].GetByteString();
                    }
                    CBORObject alg = null;
                    if (oscoreContext.ContainsKey(CBORObject.FromObject(5)))
                    {
                        alg = oscoreContext[CBORObject.FromObject(5)];
                    }
                    CBORObject kdf = null;
                    if (oscoreContext.ContainsKey(CBORObject.FromObject(4)))
                    {
                        kdf = oscoreContext[CBORObject.FromObject(4)];
                    }
                    byte[] keyContext = null;
                    if (oscoreContext.ContainsKey(CBORObject.FromObject(7)))
                    {
                        keyContext = oscoreContext[CBORObject.FromObject(7)].GetByteString();
                    }

                    if (OscoreSalts == null)
                    {
                        throw new Exception("Internal Error");
                    }

                    byte[] newSalt = new byte[salt.Length + OscoreSalts[0].Length + OscoreSalts[1].Length];
                    Array.Copy(salt, newSalt, salt.Length);
                    Array.Copy(OscoreSalts[0], 0, newSalt, salt.Length, OscoreSalts[0].Length);
                    Array.Copy(OscoreSalts[1], 0, newSalt, salt.Length + OscoreSalts[0].Length, OscoreSalts[1].Length);

                    SecurityContext oscoapContext = SecurityContext.DeriveContext(
                        oscoreContext[CBORObject.FromObject(1)].GetByteString(), keyContext,
                        oscoreContext[CBORObject.FromObject(2)].GetByteString(),
                        oscoreContext[CBORObject.FromObject(3)].GetByteString(),
                        newSalt, alg, kdf);

                    newRequest.OscoreContext = oscoapContext;

                    newRequest.URI = new Uri($"coap://{request.URI.Authority}/{request.URI.AbsolutePath}");
                }
                break;

                default:
                    Console.WriteLine("Cannot rewrite as we don't recognize the profile");
                    return;
                }

                newRequest.Respond += delegate(object sender, ResponseEventArgs e)
                {
                    Response responseN = e.Response;
                    if (responseN == null)
                    {
                        Console.WriteLine("Request timeout");
                    }
                    else
                    {
                        Console.WriteLine(Utils.ToString(responseN));
                        Console.WriteLine("Time (ms): " + responseN.RTT);
                    }

                    if (endPoint != null)
                    {
                        endPoint.Stop();
                    }
                };

                newRequest.Send();
            }
            catch (Exception e) {
                Console.WriteLine("Error processing AceAuthz - " + e.ToString());
            }
        }
示例#16
0
        static void Main(string[] args)
        {
            Com.AugustCellars.CoAP.Log.LogManager.Level = LogLevel.None;
            ;
            String Server = "192.168.53.55:5684";

            OneKey userKey = new OneKey();

            userKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
            //userKey.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes("sesame")));
            // userKey.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("password")));

            CoapClient client = new CoapClient(new Uri($"coaps://{Server}/.well-known/core"));



            CoAPEndPoint ep = new DTLSClientEndPoint(userKey);

            client.EndPoint = ep;
            ep.Start();

            //

            Response r1 = client.Get();

            Console.WriteLine("Links = " + r1.PayloadString);

            //
            //           string str = "<//15001/65536>;ct=0;obs,<//15001/65537>;ct=0;obs,<//15004/136834>;ct=0;obs,<//15005/136834/217609>;ct=0;obs,<//15005/136834/218326>;ct=0;obs,<//15005/136834/224384>;ct=0;obs,<//15005/136834>;ct=0;obs,<//15001>;ct=0;obs,<//15001/reset>;ct=0,<//status>;ct=0;obs,<//15005>;ct=0;obs,<//15004>;ct=0;obs,<//15004/add>;ct=0,<//15004/remove>;ct=0,<//15006>;ct=0;obs,<//15011/15012>;ct=0;obs,<//15011/9034>;ct=0,<//15011/9030>;ct=0,<//15011/9031>;ct=0,<//15011/9063>;ct=0,<//15011/9033>;ct=0,<//15010>;ct=0;obs";
            //           IEnumerable<WebLink> links = LinkFormat.Parse(str);
            //           foreach(var item in links) Console.WriteLine(item);
            //

            LogManager.Level = LogLevel.None;


            IEnumerable <WebLink> items = client.Discover();

            foreach (var node in items)
            {
                Console.WriteLine($"Resource = {node}");

                client.UriPath = node.Uri;

                if (false && node.Attributes.Observable)
                {
                    CoapClient c2 = new CoapClient()
                    {
                        EndPoint = client.EndPoint,
                        Uri      = client.Uri,
                        UriPath  = node.Uri
                    };
                    Console.WriteLine("Observe it");
                    CoapObserveRelation relation1 = c2.Observe(r => { EventIn(node.Uri, r); });
                }
                else
                {
                    Response response = client.Get();

                    Console.WriteLine("   Payload: " + response.PayloadString);
                    Console.WriteLine();
                }
            }

            client.Uri     = new Uri($"coaps://{Server}");
            client.UriPath = "/15004/166412";
            client.Get();
            Response rep = client.Put("{ \"5850\":1}");

            Thread.Sleep(3000);

            //rep = client.Get();
            Console.WriteLine(rep.PayloadString);

            client.UriPath = "/15001/65537";
            ;

            for (int i = 0; i < 10; i++)
            {
                Thread.Sleep(3000);
                client.Put("{ \"5851\":127}");

                Thread.Sleep(3000);
                client.Put("{ \"3311\":[{ \"5851\":0}]}");

                Thread.Sleep(3000);
                client.Put("{ \"3311\":[{ \"5851\":255}]}");
            }


            ep.Stop();
        }