public static void OneTimeSetup(TestContext ctx) { PskOne = new OneKey(); PskOne.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet); PskOne.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("KeyOne"))); PskOne.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes("abcDEFghiJKL"))); PskTwo = new OneKey(); PskTwo.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet); PskTwo.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("KeyTwo"))); PskTwo.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes("12345678091234"))); UserKeys = new KeySet(); UserKeys.AddKey(PskOne); UserKeys.AddKey(PskTwo); }
private static SecurityContextSet LoadContextSet(string fileName) { if (fileName == null) { fileName = "ServerKeys.cbor"; } KeySet keys = new KeySet(); SecurityContextSet newSet = new SecurityContextSet(); 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(), null, key[CBORObject.FromObject("RecipID")].GetByteString(), key[CBORObject.FromObject("SenderID")].GetByteString(), null, key[CoseKeyKeys.Algorithm]); newSet.Add(ctx); break; } else if (usage == "oscoap-group") { SecurityContext ctx = SecurityContext.DeriveGroupContext( key[CoseKeyParameterKeys.Octet_k].GetByteString(), key[CBORObject.FromObject(2)].GetByteString(), key[CBORObject.FromObject("SenderID")].GetByteString(), null, null, null, null, null, key[CoseKeyKeys.Algorithm]); foreach (CBORObject recipient in key[CBORObject.FromObject("recipients")].Values) { ctx.AddRecipient(recipient[CBORObject.FromObject("RecipID")].GetByteString(), new OneKey(recipient[CBORObject.FromObject("sign")])); } newSet.Add(ctx); } } if ((usages.Length != 1) || (usages[0] != "oscoap")) { keys.AddKey(key); } } reader.Close(); } // return(newSet); }
static void AddCwtRoot(string[] cmds) { if (cmds.Length != 2) { Console.WriteLine("wrong number of parameters"); return; } CBORObject cbor = CBORDiagnostics.Parse(cmds[1]); CwtRootKeys.AddKey(new OneKey(cbor)); }
private void CreateServer() { CoAPEndPoint endpoint = new CoAPEndPoint(0); KeySet ks = new KeySet(); ks.AddKey(psk); ks.AddKey(_clientSignKey.PublicKey()); _resource = new EdhocResource(ks, serverSignKey); _server = new CoapServer(); _server.Add(_resource); _server.Add(new Hello("hello")); _server.AddEndPoint(endpoint); _server.Start(); _serverPort = ((System.Net.IPEndPoint)endpoint.LocalEndPoint).Port; }
static void GenerateKeys(string fileName) { if (fileName == null) { fileName = "ServerKeys.cbor"; } KeySet keys = new KeySet(); OneKey key; for (int i = 0; i < 4; i++) { key = new OneKey(); key.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet); if (i == 3) { key.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("Key#2"))); } else { key.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("Key#" + i.ToString()))); } if (i == 3) { key.Add(CoseKeyKeys.Algorithm, AlgorithmValues.AES_CCM_64_128_128); } else { key.Add(CoseKeyKeys.Algorithm, AlgorithmValues.AES_CCM_64_64_128); } key.Add(CBORObject.FromObject("KDF"), AlgorithmValues.dir_kdf); key.Add(CBORObject.FromObject("SenderID"), CBORObject.FromObject(Encoding.UTF8.GetBytes("client"))); key.Add(CBORObject.FromObject("RecipID"), CBORObject.FromObject(Encoding.UTF8.GetBytes("server"))); byte[] keyValue = new byte[35]; for (int j = 0; j < keyValue.Length; j++) { keyValue[j] = (byte)(((i + 1) * (j + 1))); } key.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(keyValue)); keys.AddKey(key); } FileStream fs = new FileStream(fileName, FileMode.Create); using (BinaryWriter writer = new BinaryWriter(fs)) { writer.Write(keys.EncodeToBytes()); writer.Close(); } Environment.Exit(0); }
public static void Main(String[] args) { KeySet keys = new KeySet(); OneKey key = new OneKey(); key.Add(CoseKeyKeys.KeyType, COSE.GeneralValues.KeyType_Octet); key.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("password"))); key.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes("sesame"))); keys.AddKey(key); CoapServer server = new CoapServer(); // server.AddEndPoint(new TcpEndPoint(5683)); server.AddEndPoint(new DTLSEndPoint(null, keys, 5684)); server.Add(new HelloWorldResource("hello")); server.Add(new FibonacciResource("fibonacci")); server.Add(new StorageResource("storage")); server.Add(new ImageResource("image")); server.Add(new MirrorResource("mirror")); server.Add(new LargeResource("large")); server.Add(new CarelessResource("careless")); server.Add(new SeparateResource("separate")); server.Add(new TimeResource("time")); try { server.Start(); Console.Write("CoAP server [{0}] is listening on", server.Config.Version); foreach (var item in server.EndPoints) { Console.Write(" "); Console.Write(item.LocalEndPoint); } Console.WriteLine(); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine("Press any key to exit."); Console.ReadKey(); server.Stop(); }
public void TestSharedSecret() { Request req; Uri uriHello = new Uri("coap://localhost:" + _serverPort + "/hello"); Uri uri = new Uri("coap://localhost:" + _serverPort + "/" + "edhoc"); CoapClient clientHello = new CoapClient(uriHello); CoapClient client = new CoapClient(uri); // Try and get hello -- should fail because no security setup. CoAP.Response resp = clientHello.Get(); Assert.AreEqual(CoAP.StatusCode.Unauthorized, resp.StatusCode); // Create and send message #1 for PSK EDHOC.EdhocInitiator init = new EdhocInitiator(psk); byte[] msg = init.CreateMessage1(); req = new Request(Method.POST); req.Payload = msg; resp = client.Send(req); Assert.AreEqual(CoAP.StatusCode.Changed, resp.StatusCode); // Process response message KeySet ks = new KeySet(); ks.AddKey(serverSignKey); init.ParseMessage2(resp.Payload, ks); // Post new message msg = init.CreateMessage3(); req = new Request(Method.POST); req.Payload = msg; resp = client.Send(req); Assert.AreEqual(StatusCode.Changed, resp.StatusCode); // Setup my security context. OSCOAP.SecurityContext ctx = init.CreateSecurityContext(); req = new Request(Method.GET); req.URI = uriHello; req.OscoapContext = ctx; resp = clientHello.Send(req); Assert.AreEqual(StatusCode.Content, resp.StatusCode); }
static public EdhocResponder ParseMessage3(byte[] msgData, KeySet serverKeys) { CBORObject algVerify = null; CBORObject msg = CBORObject.DecodeFromBytes(msgData); if (msg.Type != CBORType.Array) { throw new Exception("Invalid message"); } EdhocResponder edhoc = MessageList[new ListKey(msg[1].GetByteString())]; edhoc._Messages[2] = msgData; if (edhoc._fSymmetricSecret) { if (msg[0].AsInt16() != 6) { throw new Exception("Invalid Message"); } } else { if (msg[0].AsInt16() != 3) { throw new Exception("Invalid Message"); } } Encrypt0Message enc0 = (Encrypt0Message)Com.AugustCellars.COSE.Message.DecodeFromBytes(msg[2].GetByteString(), Tags.Encrypt0); msg.Remove(msg[2]); byte[] data_3 = msg.EncodeToBytes(); byte[] aad_3 = ConcatenateAndHash(new byte[][] { edhoc._LastMessageAuthenticator, data_3 }, edhoc._MessageDigest); byte[][] useKeys = _DeriveKeys(edhoc._Keys, edhoc._SecretSalt, aad_3, edhoc._algAEAD); byte[] encKey = useKeys[0]; enc0.AddAttribute(HeaderKeys.Algorithm, edhoc._algAEAD, Attributes.DO_NOT_SEND); enc0.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(useKeys[1]), Attributes.DO_NOT_SEND); enc0.SetExternalData(aad_3); byte[] body = enc0.Decrypt(encKey); if (!edhoc._fSymmetricSecret) { CBORObject encBody = CBORObject.DecodeFromBytes(body); Sign1Message sign1 = (Sign1Message)Com.AugustCellars.COSE.Message.DecodeFromBytes(encBody[0].GetByteString(), Tags.Sign1); sign1.AddAttribute(HeaderKeys.Algorithm, edhoc._algSign, Attributes.DO_NOT_SEND); CBORObject kidObject = sign1.FindAttribute(HeaderKeys.KeyId); byte[] kid = null; if (kidObject != null) { kid = kidObject.GetByteString(); } sign1.SetExternalData(aad_3); KeySet keys = new KeySet(); foreach (OneKey sigKey in serverKeys) { if (sigKey.HasKid(kid)) { keys.AddKey(sigKey); } } List <OneKey> ks = new List <OneKey>(); List <OneKey> ks2 = ks.Where(f => f.HasKid(kid)).ToList(); OneKey signingKey = null; foreach (OneKey sigKey in keys) { try { sign1.Validate(sigKey); signingKey = sigKey; } catch (Exception) { // nop; } } if (signingKey == null) { throw new Exception("Unable to complete - no signing key found"); } } else { // body is the EXT_3 value } edhoc._LastMessageAuthenticator = ConcatenateAndHash(new byte[][] { edhoc._LastMessageAuthenticator, msgData }, edhoc._MessageDigest); return(edhoc); }
static void RunCommand(string[] commands) { if (commands.Length == 0) { return; } switch (commands[0].ToUpper()) { default: _dispatchTable.Execute(commands); break; case "SCRIPT": TextReader x = new StreamReader(commands[1]); RunScript(x); x.Dispose(); break; case "COMMENT": break; case "EXIT": Environment.Exit(0); break; case "PAUSE": Console.ReadLine(); break; case "TIMEOUT": break; case "LOG-LEVEL": if (commands.Length != 2) { Console.WriteLine("Incorrect number of args"); return; } switch (commands[1].ToUpper()) { case "INFO": LogManager.Level = LogLevel.Info; break; case "NONE": LogManager.Level = LogLevel.None; break; case "FATAL": LogManager.Level = LogLevel.Fatal; break; default: Console.WriteLine("Unknown level"); break; } break; case "LOG-TO": break; case "OPTION": OptionType typ = GetOptionType(commands[1]); switch (typ) { case OptionType.ContentFormat: case OptionType.Accept: if (commands.Length == 2) { _Options.Add(Option.Create(typ)); } else { for (int i = 2; i < commands.Length; i++) { int val = MediaType.ApplicationLinkFormat; if (int.TryParse(commands[i], out val)) { _Options.Add(Option.Create(typ, val)); } else { Console.WriteLine($"Bad option value '{commands[i]}'"); } } } break; case OptionType.Unknown: Console.WriteLine("Unrecognized type string"); return; default: if (commands.Length == 2) { _Options.Add(Option.Create(typ)); } else { for (int i = 2; i < commands.Length; i++) { _Options.Add(Option.Create(typ, commands[i])); } } break; } break; case "CLEAR-OPTION": if (commands.Length == 1) { _Options.Clear(); return; } typ = GetOptionType(commands[1]); List <Option> del = new List <Option>(); foreach (Option op in _Options) { if (op.Type == typ) { del.Add(op); } } foreach (Option op in del) { _Options.Remove(op); } break; case "BODY": if (commands.Length == 1) { break; } byte[] b = File.ReadAllBytes(commands[1]); Body = b; break; #if false case "EDHOC": RunEdhoc(commands); break; #endif case "ADD-OSCOAP": if (commands.Length != 3) { Console.WriteLine("Incorrect number of arguments: " + commands.Length); return; } CBORObject cbor = CBORDiagnostics.Parse(commands[2]); SecurityContext ctx = SecurityContext.DeriveContext( cbor[CoseKeyParameterKeys.Octet_k].GetByteString(), cbor[CBORObject.FromObject("RecipID")].GetByteString(), cbor[CBORObject.FromObject("SenderID")].GetByteString(), null, cbor[CoseKeyKeys.Algorithm]); _OscopKeys.Add(commands[1], ctx); break; #if DEV_VERSION case "ADD-OSCOAP-GROUP": if (commands.Length != 3) { Console.WriteLine("Incorrect number of arguments: " + commands.Length); return; } cbor = CBORDiagnostics.Parse(commands[2]); ctx = SecurityContext.DeriveGroupContext(cbor[CoseKeyParameterKeys.Octet_k].GetByteString(), cbor[CoseKeyKeys.KeyIdentifier].GetByteString(), cbor[CBORObject.FromObject("sender")][CBORObject.FromObject("ID")].GetByteString(), null, null, cbor[CoseKeyKeys.Algorithm]); ctx.Sender.SigningKey = new OneKey(cbor["sender"]["sign"]); foreach (CBORObject recipient in cbor[CBORObject.FromObject("recipients")].Values) { ctx.AddRecipient(recipient[CBORObject.FromObject("ID")].GetByteString(), new OneKey(recipient["sign"])); } _OscopKeys.Add(commands[1], ctx); break; #endif case "USE-OSCOAP": if (commands.Length != 2) { Console.WriteLine("Incorrect number of arguments: " + commands.Length); return; } if (commands[1] == "NONE") { _CurrentOscoap = null; return; } if (!_OscopKeys.ContainsKey(commands[1])) { Console.WriteLine($"OSCOAP Key {commands[1]} is not defined"); return; } _CurrentOscoap = _OscopKeys[commands[1]]; break; case "OSCOAP-TEST": OscoapTests.RunTest(Int32.Parse(commands[1])); break; case "OSCOAP-PIV": _CurrentOscoap.Sender.SequenceNumber = Int32.Parse(commands[1]); break; case "EDHOC-ADD-SERVER-KEY": if (commands.Length != 2) { Console.WriteLine("Incorrect number of arguments: " + commands.Length); return; } cbor = CBORDiagnostics.Parse(commands[2]); _EdhocServerKeys.AddKey(new OneKey(cbor)); break; case "EDHOC-ADD-USER-KEY": if (commands.Length != 3) { Console.WriteLine("Incorrect number of arguments: " + commands.Length); return; } cbor = CBORDiagnostics.Parse(commands[2]); _EdhocValidateKeys.Add(commands[1], new OneKey(cbor)); break; } }
void ProcessFile(FileInfo testCase) { if (testCase.Extension != ".json") { return; } if (testCase.Name[0] == '.') { return; } Debug.Print($"Working on file {testCase}"); Console.WriteLine("Working on file '" + testCase + "'"); string inputText = testCase.OpenText().ReadToEnd(); CBORObject test = CBORObject.FromJSONString(inputText); KeySet decodeKeys = new KeySet(); KeySet signKeys = new KeySet(); CBORObject input = test["input"]; CWT cwt = new CWT(); if (input.ContainsKey("encrypted")) { OneKey key = LoadKey(input["encrypted"]["key"]); cwt.EncryptionKey = key; decodeKeys.AddKey(key); } if (input.ContainsKey("mac0")) { OneKey key = LoadKey(input["mac0"]["key"]); cwt.MacKey = key; decodeKeys.AddKey(key); } if (input.ContainsKey("sign0")) { OneKey key = LoadKey(input["sign0"]["key"]); cwt.SigningKey = key; signKeys.AddKey(key.PublicKey()); } CWT cwt2 = CWT.Decode(FromHex(test["output"]["cbor"].AsString()), decodeKeys, signKeys); CBORObject token = input["token"]; foreach (CBORObject key in token.Keys) { CBORObject value = token[key]; CBORObject key2 = key; if (key.AsString().EndsWith("_hex")) { value = CBORObject.FromObject(FromHex(value.AsString())); key2 = CBORObject.FromObject(key.AsString().Substring(0, key.AsString().Length - 4)); } cwt.SetClaim(key2, value); Assert.True(cwt2.HasClaim(key2), $"Missing Claim {key2}"); Assert.AreEqual(value, cwt.GetClaim(key2)); } byte[] foo = cwt.EncodeToBytes(); cwt2 = CWT.Decode(foo, decodeKeys, signKeys); foreach (CBORObject key in token.Keys) { CBORObject value = token[key]; CBORObject key2 = key; if (key.AsString().EndsWith("_hex")) { value = CBORObject.FromObject(FromHex(value.AsString())); key2 = CBORObject.FromObject(key.AsString().Substring(0, key.AsString().Length - 4)); } Assert.True(cwt2.HasClaim(key2)); Assert.AreEqual(value, cwt.GetClaim(key2)); } }
static CoapServer SetupServer(ICoapConfig config, EndPoint endPoint, int port, KeySet dtlsSignKeys, KeySet dtlsValidateKeys) { // // CoapServer server = new CoapServer(config, endPoint, port); DTLSEndPoint ep2 = new DTLSEndPoint(dtlsSignKeys, dtlsValidateKeys, port + 1); server.AddEndPoint(ep2); IResource root = new HelloWorldResource("hello", true); server.Add(root); IResource x = new OscoapTest("coap"); root.Add(x); x = new OscoapTest("1"); root.Add(x); root.Add(new OscoapTest("2")); root.Add(new OscoapTest("3")); root.Add(new OscoapTest("6")); root.Add(new OscoapTest("7")); server.Add(new OscoapTest("test")); server.Add(new TimeResource("observe")); server.Add(new LargeResource("LargeResource")); #if DEV_VERSION AceTest.Setup(server, "RS1"); #if false server.Add(new Com.AugustCellars.CoAP.EDHOC.EdhocResource(edhocKeys, edhocSign)); #endif // Setup the ACE resources string UseAsServer = "coaps://localhost:5689/token"; // UseAsServer = "coaps://31.133.142.90/token"; // UseAsServer = "coaps://31.133.134.176/token"; KeySet myDecryptKeySet = new KeySet(); OneKey key = new OneKey(); key.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet); key.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(new byte[] { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 })); key.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes("SERVER_KID"))); key.Add(CoseKeyKeys.Algorithm, AlgorithmValues.AES_CCM_64_128_128); myDecryptKeySet.AddKey(key); key = new OneKey(); key.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet); key.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(new byte[] { (byte)'a', (byte)'b', (byte)'c', 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 })); key.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(new byte[] { 0x70, 0x63, 0x6F, 0x61, 0x70, 0x3A, 0x2F, 0x2F, 0x6C, 0x6F, 0x63, 0x61, 0x6C, 0x68, 0x6F, 0x73, 0x74 })); key.Add(CoseKeyKeys.Algorithm, CBORObject.FromObject(5)); myDecryptKeySet.AddKey(key); AuthZ authZ = new AuthZ(myDecryptKeySet, null); server.Add(authZ); AceOAuthTest r = new AceOAuthTest("ace-echo", true, true, UseAsServer); r.AuthTokenProcessor = authZ; server.Add(r); OscoapContexts = SecurityContextSet.AllContexts; #endif // ep2.Add(new AceOAuthTest("ace/echo", true, true, null)); #if INCLUDE_RD ResourceDirectoryResource.CreateResources(server); #endif #if DEV_VERSION // server = new CoapServer(config); CoAPEndPoint tcp = new TcpEndPoint(port); tcp.Start(); server.AddEndPoint(tcp); // server.Add(new HelloWorldResource("hello", false)); // server.Add(new LargeResource("LargeResource")); server.Add(new LargeResource("ExtraLargeResource", 20 * 1024)); server.Add(new StorageResource("StorageHere")); server.Start(); // server = new CoapServer(config); tcp = new TLSEndPoint(dtlsSignKeys, dtlsValidateKeys, port + 1); tcp.Start(); server.AddEndPoint(tcp); AceTest.Setup(server, "RS2"); //server.Add(new HelloWorldResource("hello", false)); #endif server.Start(); return(server); }
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); }
public static void Init() { Set = new KeySet(); Set.AddKey(left = new Key("left", KeyCode.LeftArrow)); Set.AddKey(right = new Key("right", KeyCode.RightArrow)); Set.AddKey(down = new Key("down", KeyCode.DownArrow)); Set.AddKey(up = new Key("up", KeyCode.UpArrow)); Set.AddKey(jump = new Key("jump", KeyCode.Space)); Set.AddKey(attack = new Key("attack", KeyCode.A)); Set.AddKey(skill = new Key("skill", KeyCode.S)); Set.AddKey(dash = new Key("dash", KeyCode.D)); Set.AddKey(weaponSwap = new Key("weaponSwap", KeyCode.Q)); Set.AddKey(weaponSkill_1 = new Key("weaponSkill_1", KeyCode.W)); Set.AddKey(weaponSkill_2 = new Key("weaponSkill_2", KeyCode.E)); }