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); }
/// <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"); }
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()); } }
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); }