Пример #1
0
 static bool IsSigner(OneKey key)
 {
     if (key[usageKey].AsString().Contains("EDHOC"))
     {
         if (key[CoseKeyKeys.KeyType].Equals(GeneralValues.KeyType_EC) &&
             key.ContainsName(CoseKeyParameterKeys.EC_D))
         {
             return(true);
         }
         if (key[CoseKeyKeys.KeyType].Equals(GeneralValues.KeyType_OKP) &&
             key.ContainsName(CoseKeyParameterKeys.OKP_D))
         {
             return(true);
         }
     }
     return(false);
 }
Пример #2
0
        /// <summary>
        /// Create an EDHOC context for a suplicant to generate messages from.
        /// </summary>
        /// <param name="contextKey">Either shared secret or signing to key to used to do identity proofing for</param>
        public EdhocInitiator(OneKey contextKey)
        {
            switch ((GeneralValuesInt)contextKey[CoseKeyKeys.KeyType].AsInt32())
            {
            case GeneralValuesInt.KeyType_Octet:
                _fSymmetricSecret = true;
                _SharedSecret     = contextKey;
                break;

            case GeneralValuesInt.KeyType_EC2:
            case GeneralValuesInt.KeyType_OKP:
                _fSymmetricSecret = false;
                if (!contextKey.ContainsName(CoseKeyParameterKeys.EC_D))
                {
                    throw new Exception("Need to supply a private key with the signing key");
                }
                _SigningKey = contextKey;
                break;

            case GeneralValuesInt.KeyType_RSA:
            default:
                throw new Exception("Unknown key type for secret");
            }

            //  Save the items in the "Our" side of the arrays.

            _kid[0] = contextKey[CoseKeyKeys.KeyIdentifier];
#if true
            _SessionId[0] = new byte[2];
            _random.NextBytes(_SessionId[0]);
            _Nonce[0] = new byte[8];
            _random.NextBytes(_Nonce[0]);
#else
            _SessionId[0] = Encoding.UTF8.GetBytes("kid client");
            _Nonce[0]     = Encoding.UTF8.GetBytes("Nonce Client");
#endif
            _Keys[0] = OneKey.GenerateKey(null, GeneralValues.KeyType_OKP, "X25519");
        }
Пример #3
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());
            }
        }
Пример #4
0
        static KeySet LoadKeys(string fileName)
        {
            if (fileName == null)
            {
                fileName = "ServerKeys.cbor";
            }
            KeySet keys = new KeySet();

            FileStream fs = new FileStream(fileName, FileMode.Open);

            using (BinaryReader reader = new BinaryReader(fs)) {
                byte[]     data = reader.ReadBytes((int)fs.Length);
                CBORObject obj  = CBORObject.DecodeFromBytes(data);

                for (int i = 0; i < obj.Count; i++)
                {
                    OneKey   key    = new OneKey(obj[i]);
                    string[] usages = key[_UsageKey].AsString().Split(' ');

                    foreach (String usage in usages)
                    {
                        if (usage == "oscoap")
                        {
                            SecurityContext ctx = SecurityContext.DeriveContext(
                                key[CoseKeyParameterKeys.Octet_k].GetByteString(),
                                key[CBORObject.FromObject("RecipID")].GetByteString(),
                                key[CBORObject.FromObject("SenderID")].GetByteString(), null,
                                key[CoseKeyKeys.Algorithm]);
                            SecurityContextSet.AllContexts.Add(ctx);
                            break;
                        }
#if DEV_VERSION
                        else if (usage == "oscoap-group")
                        {
                            SecurityContext ctx = SecurityContext.DeriveGroupContext(
                                key[CoseKeyParameterKeys.Octet_k].GetByteString(),
                                key[CoseKeyKeys.KeyIdentifier].GetByteString(),
                                key[CBORObject.FromObject("sender")][CBORObject.FromObject("ID")].GetByteString(), null,
                                null, key[CoseKeyKeys.Algorithm]);
                            ctx.Sender.SigningKey = new OneKey(obj[i]["sign"]);
                            foreach (CBORObject recipient in key[CBORObject.FromObject("recipients")].Values)
                            {
                                ctx.AddRecipient(recipient[CBORObject.FromObject("ID")].GetByteString(),
                                                 new OneKey(recipient["sign"]));
                            }

                            SecurityContextSet.AllContexts.Add(ctx);
                        }
#endif
                        else if (usage == "dtls")
                        {
                            if (key.HasPrivateKey())
                            {
                                DtlsSignKeys.AddKey(key);
                            }
                            else
                            {
                                DtlsValidateKeys.AddKey(key);
                            }
                        }

                        else if (usage == "edhoc")
                        {
                            if (key[CoseKeyKeys.KeyType].Equals(GeneralValues.KeyType_EC) ||
                                key[CoseKeyKeys.KeyType].Equals(GeneralValues.KeyType_OKP))
                            {
                                if (key.ContainsName(CoseKeyParameterKeys.EC_D))
                                {
                                    edhocSign = key;
                                }
                                else
                                {
                                    edhocKeys.AddKey(key);
                                }
                            }
                            else
                            {
                                edhocKeys.AddKey(key);
                            }
                        }
                    }

                    if ((usages.Length != 1) || (usages[0] != "oscoap"))
                    {
                        keys.AddKey(key);
                    }
                }

                reader.Close();
            }

            return(keys);
        }