コード例 #1
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);
        }