Example #1
0
        public new CBORObject EncodeToCBORObject()
        {
            CBORObject cborBodyAttributes = null;

            byte[] rgbBody = null;

            if (m_msgToSign != null)
            {
                if (m_msgToSign.GetType() == typeof(EncryptMessage))
                {
                    EncryptMessage msg = (EncryptMessage)m_msgToSign;
                    msg.Encrypt();
                    rgbBody = msg.GetEncryptedContent();
                }
                else if (m_msgToSign.GetType() == typeof(Encrypt0Message))
                {
                    Encrypt0Message msg = (Encrypt0Message)m_msgToSign;
                    rgbBody = msg.GetEncryptedContent();
                    if (rgbBody == null)
                    {
                        throw new CoseException("Need to encrypt message before countersignatures can be processed.");
                    }
                }
                cborBodyAttributes = m_msgToSign.ProtectedMap;
            }
            else if (m_signerToSign != null)
            {
                CBORObject obj = m_signerToSign.EncodeToCBORObject();
                cborBodyAttributes = m_signerToSign.ProtectedMap;
            }
            else
            {
                throw new CoseException("Internal state error - NYI");
            }


            CBORObject signed = base.EncodeToCBORObject(cborBodyAttributes.EncodeToBytes(), rgbBody);

            return(signed[2]);
        }
Example #2
0
        /// <summary>
        /// Given a CBOR tree, decode and return the correct COSE message object.
        /// Message type can be provided explicitly or inferred from the CBOR tag element.
        /// If the explicit and inferred elements provide different answers, then it fails.
        /// </summary>
        /// <param name="messageObject"></param>
        /// <param name="defaultTag"></param>
        /// <returns></returns>
        public static Message DecodeFromCBOR(CBORObject messageObject, Tags defaultTag = Tags.Unknown)
        {
            if (messageObject.Type != CBORType.Array)
            {
                throw new CoseException("Message is not a COSE security message.");
            }

            if (messageObject.IsTagged)
            {
                if (messageObject.GetAllTags().Count() != 1)
                {
                    throw new CoseException("Malformed message - too many tags");
                }

                if (defaultTag == Tags.Unknown)
                {
                    defaultTag = (Tags)messageObject.MostOuterTag.ToInt32Checked();
                }
                else if (defaultTag != (Tags)messageObject.MostOuterTag.ToInt32Checked())
                {
                    throw new CoseException("Passed in tag does not match actual tag");
                }
            }

            Message returnObject;

            switch (defaultTag)
            {
            case Tags.Unknown:
                throw new CoseException("Message was not tagged and no default tagging option given");

            case Tags.Signed:
                SignMessage sig = new SignMessage();
                sig.InternalDecodeFromCBORObject(messageObject);
                returnObject = sig;
                break;

            case Tags.Sign1:
                Sign1Message sig0 = new Sign1Message();
                sig0.InternalDecodeFromCBORObject(messageObject);
                returnObject = sig0;
                break;

            case Tags.MAC:
                MACMessage mac = new MACMessage();
                mac.InternalDecodeFromCBORObject(messageObject);
                returnObject = mac;
                break;

            case Tags.MAC0:
                MAC0Message mac0 = new MAC0Message();
                mac0.InternalDecodeFromCBORObject(messageObject);
                returnObject = mac0;
                break;

            case Tags.Encrypt: // It is an encrytion message
                EncryptMessage enc = new EncryptMessage();

                enc.InternalDecodeFromCBORObject(messageObject);
                returnObject = enc;
                break;

            case Tags.Encrypt0:
                Encrypt0Message enc0 = new Encrypt0Message();
                enc0.InternalDecodeFromCBORObject(messageObject);
                returnObject = enc0;
                break;

            default:
                throw new CoseException("Message is not recognized as a COSE security message.");
            }

            //  Check for counter signatures

            CBORObject csig = returnObject.FindAttribute(HeaderKeys.CounterSignature, UNPROTECTED);

            if (csig != null)
            {
                if (csig.Type != CBORType.Array || csig.Count == 0)
                {
                    throw new CoseException("Invalid counter signature attribute");
                }

                if (csig[0].Type == CBORType.Array)
                {
                    foreach (CBORObject cbor in csig.Values)
                    {
                        if (cbor.Type != CBORType.Array)
                        {
                            throw new CoseException("Invalid Counter signature attribute");
                        }

                        CounterSignature cs = new CounterSignature(cbor);
                        cs.SetObject(returnObject);
                        returnObject.CounterSignerList.Add(cs);
                    }
                }
                else
                {
                    CounterSignature cs = new CounterSignature(csig);
                    cs.SetObject(returnObject);
                    returnObject.CounterSignerList.Add(cs);
                }
            }

            csig = returnObject.FindAttribute(HeaderKeys.CounterSignature0, UNPROTECTED);
            if (csig != null)
            {
                if (csig.Type != CBORType.ByteString)
                {
                    throw new CoseException("Invalid CounterSignature0 attribute");
                }
                CounterSignature1 cs = new CounterSignature1(csig.GetByteString());
                cs.SetObject(returnObject);
                returnObject.CounterSigner1 = cs;
            }

            return(returnObject);
        }