public void incorrectIV() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV128), Attributes.UNPROTECTED); msg.SetContent(strContent); msg.Encrypt(rgbKey128); }
public void EncryptNoTag() { Encrypt0Message msg = new Encrypt0Message(false, true); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV96), Attributes.PROTECTED); msg.SetContent(rgbContent); msg.Encrypt(rgbKey128); CBORObject cn = msg.EncodeToCBORObject(); Assert.AreEqual(cn.IsTagged, (false)); }
public void EncryptIncorrectIV() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV128), Attributes.UNPROTECTED); msg.SetContent(rgbContent); CoseException e = Assert.ThrowsException <CoseException>(() => msg.Encrypt(rgbKey128)); Assert.AreEqual(e.Message, ("IV size is incorrect.")); }
public void encryptNoEmitContent() { Encrypt0Message msg = new Encrypt0Message(true, false); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV96), Attributes.UNPROTECTED); msg.SetContent(strContent); msg.Encrypt(rgbKey128); CBORObject cn = msg.EncodeToCBORObject(); Assert.IsTrue(cn[2].IsNull); }
public void testDecodeFromBytes_byteArr_MessageTag() { Encrypt0Message msg = new Encrypt0Message(true, false); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV96), Attributes.PROTECTED); msg.SetContent(rgbContent); msg.Encrypt(rgbKey128); byte[] rgbMsg = msg.EncodeToBytes(); msg = (Encrypt0Message)Message.DecodeFromBytes(rgbMsg); Assert.AreEqual(false, (msg.HasContent())); }
public byte[] CreateMessage3() { CBORObject msg = CBORObject.NewArray(); if (_fSymmetricSecret) { msg.Add(6); } else { msg.Add(3); } msg.Add(_SessionId[1]); byte[] aad_3 = ConcatenateAndHash(new byte[2][] { _LastMessageAuthenticator, msg.EncodeToBytes() }, _MessageDigest); byte[] signBody = new byte[0]; if (!_fSymmetricSecret) { Sign1Message sign1 = new Sign1Message(false, false); sign1.SetContent(aad_3); sign1.AddAttribute(HeaderKeys.Algorithm, _algSign, Attributes.DO_NOT_SEND); sign1.AddAttribute(HeaderKeys.KeyId, _SigningKey[CoseKeyKeys.KeyIdentifier], Attributes.UNPROTECTED); sign1.Sign(_SigningKey); CBORObject obj = CBORObject.NewArray(); obj.Add(sign1.EncodeToBytes()); signBody = obj.EncodeToBytes(); } byte[][] encKeys = _DeriveKeys(_Keys, _SecretSalt, aad_3, _algAEAD); Encrypt0Message enc = new Encrypt0Message(false); enc.SetContent(signBody); enc.SetExternalData(aad_3); enc.AddAttribute(HeaderKeys.Algorithm, _algAEAD, Attributes.DO_NOT_SEND); enc.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(encKeys[1]), Attributes.DO_NOT_SEND); enc.Encrypt(encKeys[0]); msg.Add(enc.EncodeToBytes()); byte[] msgOut = msg.EncodeToBytes(); _LastMessageAuthenticator = ConcatenateAndHash(new byte[2][] { _LastMessageAuthenticator, msgOut }, _MessageDigest); return(msgOut); }
public void roundTrip() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV96), Attributes.UNPROTECTED); msg.SetContent(strContent); msg.Encrypt(rgbKey128); byte[] rgbMsg = msg.EncodeToBytes(); msg = (Encrypt0Message)Message.DecodeFromBytes(rgbMsg); msg.Decrypt(rgbKey128); Assert.AreEqual <string>(msg.GetContentAsString(), strContent); }
public void testDecodeUnknown() { Encrypt0Message msg = new Encrypt0Message(false, true); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV96), Attributes.PROTECTED); msg.SetContent(rgbContent); msg.Encrypt(rgbKey128); byte[] rgbMsg = msg.EncodeToBytes(); CoseException e = Assert.ThrowsException <CoseException>(() => msg = (Encrypt0Message)Message.DecodeFromBytes(rgbMsg, Tags.Unknown)); Assert.AreEqual(e.Message, ("Message was not tagged and no default tagging option given")); }
public void TestRoundTrip4() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV96), Attributes.PROTECTED); msg.SetContent(rgbContent); msg.Encrypt(rgbKey128); CBORObject rgbMsg = msg.EncodeToCBORObject(); msg = (Encrypt0Message)Message.DecodeFromCBOR(rgbMsg); byte[] contentNew = msg.Decrypt(rgbKey128); CollectionAssert.AreEqual(rgbContent, (contentNew)); }
public void noContent() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.Encrypt(rgbKey128); }
public void nullKeyForDecrypt() { Encrypt0Message msg = new Encrypt0Message(true, true); // thrown.expect(CoseException.class); // thrown.expectMessage("No Encrypted Content Specified"); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV96), Attributes.UNPROTECTED); msg.SetContent(strContent); msg.Encrypt(rgbKey128); byte[] rgb = msg.EncodeToBytes(); msg = (Encrypt0Message)Message.DecodeFromBytes(rgb); msg.Decrypt(null); }
public void unsupportedAlgorithm() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.HMAC_SHA_256, Attributes.PROTECTED); msg.SetContent(strContent); msg.Encrypt(rgbKey128); }
public void nullKey() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.SetContent(strContent); msg.Encrypt(null); }
public void incorrectKeySize() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.SetContent(strContent); msg.Encrypt(rgbKey256); }
public void roundTripDetached() { Encrypt0Message msg = new Encrypt0Message(true, false); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV96), Attributes.UNPROTECTED); msg.SetContent(strContent); msg.Encrypt(rgbKey128); byte[] content = msg.GetEncryptedContent(); byte[] rgb = msg.EncodeToBytes(); msg = (Encrypt0Message)Message.DecodeFromBytes(rgb); msg.SetEncryptedContent(content); msg.Decrypt(rgbKey128); }
public void unknownAlgorithm() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, CBORObject.FromObject("Unknown"), Attributes.PROTECTED); msg.SetContent(strContent); msg.Encrypt(rgbKey128); }
public void NoContentForDecrypt() { Encrypt0Message msg = new Encrypt0Message(true, false); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(rgbIV96), Attributes.UNPROTECTED); msg.SetContent(rgbContent); msg.Encrypt(rgbKey128); byte[] rgb = msg.EncodeToBytes(); msg = (Encrypt0Message)Message.DecodeFromBytes(rgb); CoseException e = Assert.ThrowsException <CoseException>(() => msg.Decrypt(rgbKey128)); Assert.AreEqual(e.Message, ("No Encrypted Content Specified.")); }
public void EncryptNullKey() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.SetContent(rgbContent); Assert.ThrowsException <CoseException>(() => msg.Encrypt(null)); }
public void EncryptNoContent() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); CoseException e = Assert.ThrowsException <CoseException>(() => msg.Encrypt(rgbKey128)); Assert.AreEqual(e.Message, ("No Content Specified")); }
public void EncryptIncorrectKeySize() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.AES_GCM_128, Attributes.PROTECTED); msg.SetContent(rgbContent); CoseException e = Assert.ThrowsException <CoseException>(() => msg.Encrypt(rgbKey256)); Assert.AreEqual(e.Message, ("Incorrect Key Size")); }
public void EncryptUnsupportedAlgorithm() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, AlgorithmValues.HMAC_SHA_256, Attributes.PROTECTED); msg.SetContent(rgbContent); CoseException e = Assert.ThrowsException <CoseException>(() => msg.Encrypt(rgbKey128)); Assert.AreEqual(e.Message, ("Unknown Algorithm Specified")); }
public void EncryptUnknownAlgorithm() { Encrypt0Message msg = new Encrypt0Message(); msg.AddAttribute(HeaderKeys.Algorithm, CBORObject.FromObject("Unknown"), Attributes.PROTECTED); msg.SetContent(rgbContent); CoseException e = Assert.ThrowsException <CoseException>(() => msg.Encrypt(rgbKey128)); Assert.AreEqual(e.Message, ("Unknown Algorithm Specified")); }
public override void SendResponse(INextLayer nextLayer, Exchange exchange, Response response) { if (exchange.OscoapContext != null) { SecurityContext ctx = exchange.OscoapContext; Codec.IMessageEncoder me = Spec.NewMessageEncoder(); Response encryptedResponse = new Response((StatusCode)response.Code); if (response.Payload != null) { encryptedResponse.Payload = response.Payload; } MoveResponseHeaders(response, encryptedResponse); if (_Log.IsInfoEnabled) { _Log.Info("SendResponse: New inner response message"); _Log.Info(encryptedResponse.ToString()); } // Build AAD CBORObject aad = CBORObject.NewArray(); aad.Add(1); aad.Add(CBORObject.NewArray()); aad[1].Add(ctx.Sender.Algorithm); aad.Add(exchange.OscoapSenderId); aad.Add(exchange.OscoapSequenceNumber); aad.Add(CBORObject.FromObject(new byte[0])); // Options if (ctx.GroupId != null) { aad.Add(ctx.GroupId); } if (_Log.IsInfoEnabled) { _Log.Info("SendResponse: AAD = " + BitConverter.ToString(aad.EncodeToBytes())); } Encrypt0Message enc = new Encrypt0Message(false); byte[] msg = me.Encode(encryptedResponse); int tokenSize = msg[0] & 0xf; byte[] msg2 = new byte[msg.Length - (3 + tokenSize)]; Array.Copy(msg, 4 + tokenSize, msg2, 1, msg2.Length - 1); msg2[0] = msg[1]; enc.SetContent(msg2); enc.SetExternalData(aad.EncodeToBytes()); if (response.HasOption(OptionType.Observe) || ctx.GroupId != null) { enc.AddAttribute(HeaderKeys.PartialIV, CBORObject.FromObject(ctx.Sender.PartialIV), Attributes.UNPROTECTED); enc.AddAttribute(HeaderKeys.IV, ctx.Sender.GetIV(ctx.Sender.PartialIV), Attributes.DO_NOT_SEND); ctx.Sender.IncrementSequenceNumber(); if (ctx.GroupId != null) { enc.AddAttribute(HeaderKeys.KeyId, CBORObject.FromObject(ctx.Sender.Id), Attributes.UNPROTECTED); } } else { CBORObject iv = ctx.Recipient.GetIV(exchange.OscoapSequenceNumber); enc.AddAttribute(HeaderKeys.IV, iv, Attributes.DO_NOT_SEND); } _Log.Info(m => m($"SendResponse: IV = {BitConverter.ToString(enc.FindAttribute(HeaderKeys.IV, Attributes.DO_NOT_SEND).GetByteString())}")); _Log.Info(m => m($"SendResponse: Key = {BitConverter.ToString(ctx.Sender.Key)}")); enc.AddAttribute(HeaderKeys.Algorithm, ctx.Sender.Algorithm, Attributes.DO_NOT_SEND); enc.Encrypt(ctx.Sender.Key); byte[] finalBody = DoCompression(enc); OscoapOption o = new OscoapOption(OptionType.Oscoap); o.Set(finalBody); response.AddOption(o); response.StatusCode = StatusCode.Content; response.Payload = enc.GetEncryptedContent(); // Need to be able to retrieve this again undersome cirumstances. if (encryptedResponse.HasOption(OptionType.Block2)) { Request request = exchange.CurrentRequest; Exchange.KeyUri keyUri = new Exchange.KeyUri(request.URI, null, response.Destination); // Observe notification only send the first block, hence do not store them as ongoing if (exchange.OSCOAP_ResponseBlockStatus != null && !encryptedResponse.HasOption(OptionType.Observe)) { // Remember ongoing blockwise GET requests BlockHolder blockInfo = new BlockHolder(exchange); if (Util.Utils.Put(_ongoingExchanges, keyUri, blockInfo) == null) { if (_Log.IsInfoEnabled) { _Log.Info("Ongoing Block2 started late, storing " + keyUri + " for " + request); } } else { if (_Log.IsInfoEnabled) { _Log.Info("Ongoing Block2 continued, storing " + keyUri + " for " + request); } } } else { if (_Log.IsInfoEnabled) { _Log.Info("Ongoing Block2 completed, cleaning up " + keyUri + " for " + request); } BlockHolder exc; _ongoingExchanges.TryRemove(keyUri, out exc); } } } base.SendResponse(nextLayer, exchange, response); }
/// <inheritdoc /> public override void ReceiveRequest(INextLayer nextLayer, Exchange exchange, Request request) { if (!request.HasOption(OptionType.Oscoap)) { base.ReceiveRequest(nextLayer, exchange, request); return; } Response response; try { Option op = request.GetFirstOption(OptionType.Oscoap); request.RemoveOptions(OptionType.Oscoap); _Log.Info(m => m("Incoming Request: {0}", Util.Utils.ToString(request))); Encrypt0Message msg = Uncompress(op.RawValue); if (msg == null) { // Only bother to reply to CON messages if (request.Type == MessageType.CON) { response = new Response(StatusCode.BadOption) { PayloadString = "Unable to decompress" }; exchange.SendResponse(response); } return; } msg.SetEncryptedContent(request.Payload); List <SecurityContext> contexts = new List <SecurityContext>(); SecurityContext ctx = null; CBORObject kid; // We may know the context because it is a follow up on a conversation - // In which case we can just use the same one. // M00BUG - Multicast problem of recipient ID? CBORObject gid = null; if (exchange.OscoapContext != null) { contexts.Add(exchange.OscoapContext); if (exchange.OscoapContext.GroupId != null) { gid = CBORObject.FromObject(exchange.OscoapContext.GroupId); } kid = CBORObject.FromObject(exchange.OscoapSenderId); } else { gid = msg.FindAttribute(CBORObject.FromObject("gid")); kid = msg.FindAttribute(HeaderKeys.KeyId); if (kid == null) { exchange.SendResponse(new Response(StatusCode.BadRequest)); return; } if (gid != null) { contexts = SecurityContextSet.AllContexts.FindByGroupId(gid.GetByteString()); } else { contexts = SecurityContextSet.AllContexts.FindByKid(kid.GetByteString()); } if (contexts.Count == 0) { response = new Response(StatusCode.Unauthorized) { PayloadString = "No Context Found - 1" }; exchange.SendResponse(response); return; // Ignore messages that have no known security context. } } byte[] partialIV = msg.FindAttribute(HeaderKeys.PartialIV).GetByteString(); // Build AAD CBORObject aad = CBORObject.NewArray(); aad.Add(CBORObject.FromObject(1)); // M00BUG aad.Add(CBORObject.NewArray()); // Array place holder aad[1].Add(CBORObject.FromObject(0)); // Place holder for algorithm aad.Add(CBORObject.FromObject(kid)); aad.Add(CBORObject.FromObject(partialIV)); aad.Add(CBORObject.FromObject(new byte[0])); // encoded I options if (gid != null) { aad.Add(gid); } byte[] payload = null; byte[] seqNoArray = new byte[8]; Array.Copy(partialIV, 0, seqNoArray, 8 - partialIV.Length, partialIV.Length); if (BitConverter.IsLittleEndian) { Array.Reverse(seqNoArray); } Int64 seqNo = BitConverter.ToInt64(seqNoArray, 0); String responseString = "General decrypt failure"; foreach (SecurityContext context in contexts) { SecurityContext.EntityContext recip = context.Recipient; if (recip == null) { if (kid == null) { continue; } recip = context.Recipients[kid.GetByteString()]; if (recip == null) { continue; } } if (_replayWindow && recip.ReplayWindow.HitTest(seqNo)) { _Log.Info(m => m("Hit test on {0} failed", seqNo)); responseString = "Hit test - duplicate"; continue; } aad[1][0] = recip.Algorithm; if (_Log.IsInfoEnabled) { _Log.Info("AAD = " + BitConverter.ToString(aad.EncodeToBytes())); _Log.Info("IV = " + BitConverter.ToString(recip.GetIV(partialIV).GetByteString())); _Log.Info("Key = " + BitConverter.ToString(recip.Key)); } msg.SetExternalData(aad.EncodeToBytes()); msg.AddAttribute(HeaderKeys.Algorithm, recip.Algorithm, Attributes.DO_NOT_SEND); msg.AddAttribute(HeaderKeys.IV, recip.GetIV(partialIV), Attributes.DO_NOT_SEND); try { ctx = context; payload = msg.Decrypt(recip.Key); recip.ReplayWindow.SetHit(seqNo); } catch (Exception e) { if (_Log.IsInfoEnabled) { _Log.Info("--- ", e); } ctx = null; } if (ctx != null) { break; } } if (ctx == null) { if (request.Type == MessageType.CON) { response = new Response(StatusCode.BadRequest) { PayloadString = responseString }; exchange.SendResponse(response); } return; } exchange.OscoapContext = ctx; // So we know it on the way back. request.OscoapContext = ctx; exchange.OscoapSequenceNumber = partialIV; exchange.OscoapSenderId = kid.GetByteString(); byte[] newRequestData = new byte[payload.Length + _FixedHeader.Length - 1]; Array.Copy(_FixedHeader, newRequestData, _FixedHeader.Length); Array.Copy(payload, 1, newRequestData, _FixedHeader.Length, payload.Length - 1); newRequestData[1] = payload[0]; Codec.IMessageDecoder me = Spec.NewMessageDecoder(newRequestData); Request newRequest = me.DecodeRequest(); // Update headers is a pain RestoreOptions(request, newRequest); request.Method = newRequest.Method; if (_Log.IsInfoEnabled) { // log.Info(String.Format("Secure message post = " + Util.Utils.ToString(request))); } // We may want a new exchange at this point if it relates to a new message for blockwise. if (request.HasOption(OptionType.Block2)) { Exchange.KeyUri keyUri = new Exchange.KeyUri(request.URI, null, request.Source); BlockHolder block; _ongoingExchanges.TryGetValue(keyUri, out block); if (block != null) { block.RestoreTo(exchange); } } request.Payload = newRequest.Payload; } catch (Exception e) { _Log.Error("OSCOAP Layer: reject message because ", e); exchange.OscoapContext = null; if (request.Type == MessageType.CON) { response = new Response(StatusCode.Unauthorized) { Payload = Encoding.UTF8.GetBytes("Error is " + e.Message) }; exchange.SendResponse(response); } // Ignore messages that we cannot decrypt. return; } base.ReceiveRequest(nextLayer, exchange, request); }
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); }
public byte[] CreateMessage2() { CBORObject msg = CBORObject.NewArray(); CBORObject obj; if (_fSymmetricSecret) { msg.Add(5); // Msg Type } else { msg.Add(2); } msg.Add(_SessionId[1]); // S_U msg.Add(_SessionId[0]); // S_V msg.Add(_Nonce[0]); // N_V msg.Add(_Keys[0].PublicKey().AsCBOR()); // E_V msg.Add(_algKeyAgree); // HKDF_V msg.Add(_algAEAD); // AEAD_V if (!_fSymmetricSecret) { msg.Add(_algSign); // SIG_V obj = CBORObject.NewArray(); obj.Add(AlgorithmValuesInt.ECDSA_256); obj.Add(AlgorithmValues.EdDSA); msg.Add(obj); // SIGs_V } if (_algKeyAgree.Equals(COSE.AlgorithmValues.ECDH_SS_HKDF_256)) { _MessageDigest = new Sha256Digest(); } byte[] data2 = msg.EncodeToBytes(); byte[] aad_2 = ConcatenateAndHash(new byte[2][] { _Messages[0], data2 }, _MessageDigest); // M00TODO - hash message[0] before passing it in. byte[][] useKeys = _DeriveKeys(_Keys, _SecretSalt, aad_2, _algAEAD); byte[] aeadKey = useKeys[0]; byte[] signResult = new byte[0]; if (!_fSymmetricSecret) { Sign1Message sign1 = new Sign1Message(false, false); sign1.SetContent(aad_2); sign1.AddAttribute(HeaderKeys.KeyId, _SigningKey[CoseKeyKeys.KeyIdentifier], Attributes.UNPROTECTED); sign1.AddAttribute(HeaderKeys.Algorithm, _algSign, Attributes.DO_NOT_SEND); sign1.Sign(_SigningKey); signResult = sign1.EncodeToBytes(); } Encrypt0Message enc0 = new Encrypt0Message(true); enc0.AddAttribute(HeaderKeys.Algorithm, _algAEAD, Attributes.DO_NOT_SEND); enc0.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(useKeys[1]), Attributes.DO_NOT_SEND); enc0.SetExternalData(aad_2); CBORObject encContent = CBORObject.NewArray(); encContent.Add(signResult); enc0.SetContent(encContent.EncodeToBytes()); enc0.Encrypt(aeadKey); msg.Add(enc0.EncodeToCBORObject()); // COSE_ENC_2 _Messages[1] = msg.EncodeToBytes(); _LastMessageAuthenticator = ConcatenateAndHash(new byte[][] { _Messages[0], _Messages[1] }, _MessageDigest); return(_Messages[1]); }
public override void ReceiveResponse(INextLayer nextLayer, Exchange exchange, Response response) { if (response.HasOption(OptionType.Oscoap)) { Option op = response.GetFirstOption(OptionType.Oscoap); if (exchange.OscoapContext == null) { return; } SecurityContext ctx = exchange.OscoapContext; bool fServerIv = true; Encrypt0Message msg = Uncompress(op.RawValue); if (msg == null) { return; } msg.SetEncryptedContent(response.Payload); SecurityContext.EntityContext recip = ctx.Recipient; if (recip == null) { if (ctx.GroupId == null) { // This is not currently a valid state to be in return; } CBORObject kid = msg.FindAttribute(HeaderKeys.KeyId); if (kid == null) { // this is not currently a valid state to be in return; } recip = ctx.Recipients[kid.GetByteString()]; if (recip == null) { // M00TODO - deal with asking the user for a recipient structure at this point. return; } } if (msg.FindAttribute(HeaderKeys.PartialIV) == null) { msg.AddAttribute(HeaderKeys.PartialIV, CBORObject.FromObject(ctx.Sender.PartialIV), Attributes.DO_NOT_SEND); fServerIv = false; } byte[] partialIV = msg.FindAttribute(HeaderKeys.PartialIV).GetByteString(); byte[] seqNoArray = new byte[8]; Array.Copy(partialIV, 0, seqNoArray, 8 - partialIV.Length, partialIV.Length); if (BitConverter.IsLittleEndian) { Array.Reverse(seqNoArray); } Int64 seqNo = BitConverter.ToInt64(seqNoArray, 0); if (fServerIv) { if (_replayWindow && recip.ReplayWindow.HitTest(seqNo)) { return; } } msg.AddAttribute(HeaderKeys.Algorithm, recip.Algorithm, Attributes.DO_NOT_SEND); CBORObject fullIV; if (fServerIv) { fullIV = recip.GetIV(partialIV); } else { fullIV = ctx.Sender.GetIV(partialIV); } msg.AddAttribute(HeaderKeys.IV, fullIV, Attributes.DO_NOT_SEND); // build aad CBORObject aad = CBORObject.NewArray(); aad.Add(1); aad.Add(CBORObject.NewArray()); aad[1].Add(recip.Algorithm); aad.Add(ctx.Sender.Id); aad.Add(ctx.Sender.PartialIV); aad.Add(CBORObject.FromObject(new byte[0])); // OPTIONS if (ctx.GroupId != null) { aad.Add(ctx.GroupId); } msg.SetExternalData(aad.EncodeToBytes()); _Log.Info(m => m($"fServerIv = {fServerIv}")); _Log.Info(m => m("ReceiveResponse: AAD = " + BitConverter.ToString(aad.EncodeToBytes()))); _Log.Info(m => m($"ReceiveResponse: IV = {BitConverter.ToString(fullIV.GetByteString())}")); _Log.Info(m => m($"ReceiveResponse: Key = {BitConverter.ToString(recip.Key)}")); byte[] payload = msg.Decrypt(recip.Key); recip.ReplayWindow.SetHit(seqNo); byte[] rgb = new byte[payload.Length + _FixedHeader.Length - 1]; Array.Copy(_FixedHeader, rgb, _FixedHeader.Length); Array.Copy(payload, 1, rgb, _FixedHeader.Length, payload.Length - 1); rgb[1] = payload[0]; Codec.IMessageDecoder me = Spec.NewMessageDecoder(rgb); Response decryptedReq = me.DecodeResponse(); response.Payload = decryptedReq.Payload; response.StatusCode = decryptedReq.StatusCode; RestoreOptions(response, decryptedReq); } base.ReceiveResponse(nextLayer, exchange, response); }
/// <summary> /// /// </summary> /// <param name="msgData"></param> /// <param name="keySetPublic"></param> public void ParseMessage2(byte[] msgData, KeySet keySetPublic) { int msgIndex; CBORObject algVerify = null; CBORObject msg = CBORObject.DecodeFromBytes(msgData); if (msg.Type != CBORType.Array) { throw new Exception("Invalid message"); } _Messages[1] = msgData; if (_fSymmetricSecret) { if (msg[0].AsInt16() != 5) { throw new Exception("Invalid Message"); } } else { if (msg[0].AsInt16() != 2) { throw new Exception("Invalid Message"); } } _SessionId[1] = msg[2].GetByteString(); // S_V _Nonce[1] = msg[3].GetByteString(); // N_V _Keys[1] = new OneKey(msg[4]); // E_V _algKeyAgree = msg[5]; // HKDF_V _algAEAD = msg[6]; // AAEAD_V if (_fSymmetricSecret) { msgIndex = 7; } else { algVerify = msg[7]; // SIG_V _algSign = _SelectAlgorithm(msg[8], new CBORObject[] { _SigningKey[CoseKeyKeys.Algorithm] }); // SIG_U msgIndex = 9; } // What is the hash algorithm to use? switch ((AlgorithmValuesInt)_algKeyAgree.AsInt32()) { case AlgorithmValuesInt.ECDH_SS_HKDF_256: _MessageDigest = new Sha256Digest(); break; case AlgorithmValuesInt.ECDH_SS_HKDF_512: _MessageDigest = new Sha512Digest(); break; } Encrypt0Message enc0 = (Encrypt0Message)Com.AugustCellars.COSE.Message.DecodeFromBytes(msg[msgIndex].EncodeToBytes(), Tags.Encrypt0); msg.Remove(msg[msgIndex]); byte[] data_2 = msg.EncodeToBytes(); byte[] aad_2 = ConcatenateAndHash(new byte[2][] { _Messages[0], data_2 }, _MessageDigest); byte[][] useKeys = _DeriveKeys(_Keys, _SecretSalt, aad_2, _algAEAD); byte[] encKey = useKeys[0]; enc0.AddAttribute(HeaderKeys.Algorithm, _algAEAD, Attributes.DO_NOT_SEND); enc0.AddAttribute(HeaderKeys.IV, CBORObject.FromObject(useKeys[1]), Attributes.DO_NOT_SEND); enc0.SetExternalData(aad_2); byte[] body = enc0.Decrypt(encKey); if (!_fSymmetricSecret) { CBORObject encBody = CBORObject.DecodeFromBytes(body); Sign1Message sign1 = (Sign1Message)Com.AugustCellars.COSE.Message.DecodeFromBytes(encBody[0].GetByteString(), Tags.Sign1); sign1.AddAttribute(HeaderKeys.Algorithm, algVerify, Attributes.DO_NOT_SEND); CBORObject kid = sign1.FindAttribute(HeaderKeys.KeyId); sign1.SetExternalData(aad_2); foreach (OneKey sigKey in keySetPublic) { sign1.Validate(sigKey); //FIND KEY); } } else { // body is the EXT_2 value } _LastMessageAuthenticator = ConcatenateAndHash(new byte[2][] { _LastMessageAuthenticator, msgData }, _MessageDigest); }
/// <inheritdoc /> public override void SendRequest(INextLayer nextLayer, Exchange exchange, Request request) { if ((request.OscoapContext != null) || (exchange.OscoapContext != null)) { SecurityContext ctx = exchange.OscoapContext; if (request.OscoapContext != null) { ctx = request.OscoapContext; exchange.OscoapContext = ctx; } Codec.IMessageEncoder me = Spec.NewMessageEncoder(); Request encryptedRequest = new Request(request.Method); if (request.Payload != null) { encryptedRequest.Payload = request.Payload; } MoveRequestHeaders(request, encryptedRequest); _Log.Info(m => m("New inner response message\n{0}", encryptedRequest.ToString())); ctx.Sender.IncrementSequenceNumber(); Encrypt0Message enc = new Encrypt0Message(false); byte[] msg = me.Encode(encryptedRequest); int tokenSize = msg[0] & 0xf; byte[] msg2 = new byte[msg.Length - (3 + tokenSize)]; Array.Copy(msg, 4 + tokenSize, msg2, 1, msg2.Length - 1); msg2[0] = msg[1]; enc.SetContent(msg2); // Build AAD CBORObject aad = CBORObject.NewArray(); aad.Add(CBORObject.FromObject(1)); // version aad.Add(CBORObject.NewArray()); aad[1].Add(CBORObject.FromObject(ctx.Sender.Algorithm)); aad.Add(CBORObject.FromObject(ctx.Sender.Id)); aad.Add(CBORObject.FromObject(ctx.Sender.PartialIV)); aad.Add(CBORObject.FromObject(new byte[0])); if (ctx.GroupId != null) { aad.Add(CBORObject.FromObject(ctx.GroupId)); } #if DEBUG switch (SecurityContext.FutzError) { case 1: aad[0] = CBORObject.FromObject(2); break; // Change version # case 2: aad[1] = CBORObject.FromObject(request.Code + 1); break; // Change request code case 3: aad[2] = CBORObject.FromObject(ctx.Sender.Algorithm.AsInt32() + 1); break; // Change algorithm number } #endif _Log.Info(m => m("SendRequest: AAD = {0}", BitConverter.ToString(aad.EncodeToBytes()))); enc.SetExternalData(aad.EncodeToBytes()); #if DEBUG { byte[] fooX = ctx.Sender.PartialIV; if (SecurityContext.FutzError == 8) { fooX[fooX.Length - 1] += 1; } enc.AddAttribute(HeaderKeys.IV, ctx.Sender.GetIV(fooX), Attributes.DO_NOT_SEND); } #else enc.AddAttribute(HeaderKeys.IV, ctx.Sender.GetIV(ctx.Sender.PartialIV), Attributes.DO_NOT_SEND); #endif enc.AddAttribute(HeaderKeys.PartialIV, CBORObject.FromObject(ctx.Sender.PartialIV), /* Attributes.PROTECTED */ Attributes.DO_NOT_SEND); enc.AddAttribute(HeaderKeys.Algorithm, ctx.Sender.Algorithm, Attributes.DO_NOT_SEND); enc.AddAttribute(HeaderKeys.KeyId, CBORObject.FromObject(ctx.Sender.Id), /*Attributes.PROTECTED*/ Attributes.DO_NOT_SEND); if (ctx.GroupId != null) { enc.AddAttribute(CBORObject.FromObject("gid"), CBORObject.FromObject(ctx.GroupId), Attributes.DO_NOT_SEND); } if (_Log.IsInfoEnabled) { _Log.Info("SendRequest: AAD = " + BitConverter.ToString(aad.EncodeToBytes())); _Log.Info("SendRequest: IV = " + BitConverter.ToString(ctx.Sender.GetIV(ctx.Sender.PartialIV).GetByteString())); _Log.Info("SendRequest: Key = " + BitConverter.ToString(ctx.Sender.Key)); } enc.Encrypt(ctx.Sender.Key); if (ctx.Sender.SigningKey != null) { CounterSignature sig = new CounterSignature(ctx.Sender.SigningKey); sig.AddAttribute(HeaderKeys.Algorithm, ctx.Sender.SigningKey[CoseKeyKeys.Algorithm], Attributes.DO_NOT_SEND); sig.SetObject(enc); CBORObject aad2 = ctx.Sender.SigningKey[CoseKeyKeys.Algorithm]; sig.SetExternalData(aad2.EncodeToBytes()); CBORObject signatureBytes = sig.EncodeToCBORObject(); enc.AddAttribute(HeaderKeys.CounterSignature, signatureBytes, Attributes.DO_NOT_SEND); } byte[] optionValue = DoCompression(enc); OscoapOption o = new OscoapOption(); o.Set(optionValue); request.AddOption(o); request.Payload = enc.GetEncryptedContent(); if (request.HasOption(OptionType.Observe)) { request.Method = Method.FETCH; } else { request.Method = Method.POST; } } base.SendRequest(nextLayer, exchange, request); }
/// <inheritdoc /> public override void SendRequest(INextLayer nextLayer, Exchange exchange, Request request) { if ((request.OscoreContext != null) || (exchange.OscoreContext != null)) { SecurityContext ctx = exchange.OscoreContext; if (request.OscoreContext != null) { ctx = request.OscoreContext; exchange.OscoreContext = ctx; } Codec.IMessageEncoder me = Spec.NewMessageEncoder(); Request encryptedRequest = new Request(request.Method); if (request.Payload != null) { encryptedRequest.Payload = request.Payload; } MoveRequestHeaders(request, encryptedRequest); _Log.Info(m => m("New inner response message\n{0}", encryptedRequest.ToString())); ctx.Sender.IncrementSequenceNumber(); Encrypt0Message enc = new Encrypt0Message(false); byte[] msg = me.Encode(encryptedRequest); int tokenSize = msg[0] & 0xf; byte[] msg2 = new byte[msg.Length - (3 + tokenSize)]; Array.Copy(msg, 4 + tokenSize, msg2, 1, msg2.Length - 1); msg2[0] = msg[1]; enc.SetContent(msg2); // Build AAD CBORObject aad = CBORObject.NewArray(); aad.Add(CBORObject.FromObject(1)); // version aad.Add(CBORObject.NewArray()); // Algorithms aad[1].Add(CBORObject.FromObject(ctx.Sender.Algorithm)); if (ctx.Sender.SigningAlgorithm != null) { aad[1].Add(ctx.Sender.SigningAlgorithm); if (ctx.CountersignParams != null) { aad[1].Add(ctx.CountersignParams); } if (ctx.CountersignKeyParams != null) { aad[1].Add(ctx.CountersignKeyParams); } } aad.Add(CBORObject.FromObject(ctx.Sender.Id)); aad.Add(CBORObject.FromObject(ctx.Sender.PartialIV)); aad.Add(CBORObject.FromObject(new byte[0])); // I options go here _Log.Info(m => m("SendRequest: AAD = {0}", BitConverter.ToString(aad.EncodeToBytes()))); enc.SetExternalData(aad.EncodeToBytes()); enc.AddAttribute(HeaderKeys.IV, ctx.Sender.GetIV(ctx.Sender.PartialIV), Attributes.DO_NOT_SEND); enc.AddAttribute(HeaderKeys.PartialIV, CBORObject.FromObject(ctx.Sender.PartialIV), /* Attributes.PROTECTED */ Attributes.DO_NOT_SEND); enc.AddAttribute(HeaderKeys.Algorithm, ctx.Sender.Algorithm, Attributes.DO_NOT_SEND); enc.AddAttribute(HeaderKeys.KeyId, CBORObject.FromObject(ctx.Sender.Id), /*Attributes.PROTECTED*/ Attributes.DO_NOT_SEND); if (ctx.GroupId != null) { enc.AddAttribute(HeaderKeys.KidContext, CBORObject.FromObject(ctx.GroupId), Attributes.DO_NOT_SEND); } _Log.Info(m => m("SendRequest: AAD = {0}\nSendRequest: IV = {1}\nSendRequest: Key = {2}", BitConverter.ToString(aad.EncodeToBytes()), ctx.Sender.GetIV(ctx.Sender.PartialIV).GetByteString(), BitConverter.ToString(ctx.Sender.Key))); byte[] optionValue = BuildOscoreOption(enc); CounterSignature1 cs1 = null; if (ctx.Sender.SigningKey != null) { cs1 = new CounterSignature1(ctx.Sender.SigningKey); cs1.AddAttribute(HeaderKeys.Algorithm, ctx.Sender.SigningAlgorithm, Attributes.DO_NOT_SEND); aad.Add(optionValue); _Log.Info(m => m("SendRequest: AAD for Signature = {0}", BitConverter.ToString(aad.EncodeToBytes()))); cs1.SetExternalData(aad.EncodeToBytes()); cs1.SetObject(enc); enc.CounterSigner1 = cs1; } enc.Encrypt(ctx.Sender.Key); OscoapOption o = new OscoapOption(); o.Set(optionValue); request.AddOption(o); request.Payload = enc.GetEncryptedContent(); if (cs1 != null) { int cbOrig = request.Payload.Length; byte[] rgbOrig = request.Payload; byte[] signatureBytes = cs1.EncodeToCBORObject().GetByteString(); Array.Resize(ref rgbOrig, cbOrig + signatureBytes.Length); Array.Copy(signatureBytes, 0, rgbOrig, cbOrig, signatureBytes.Length); request.Payload = rgbOrig; } request.Method = request.HasOption(OptionType.Observe) ? Method.FETCH : Method.POST; request.Code = (int)request.Method; } base.SendRequest(nextLayer, exchange, request); }