/**
         * Constructor that accepts the binary representation of a signed COSE_Sign1 object.
         *
         * @param data
         *          the binary representation of the COSE_Sign1 object
         * @throws CBORException
         *           for invalid data
         */
        public CoseSign1_Object(byte[] data)
        {
            CBORObject message = CBORObject.DecodeFromBytes(data);

            if (message.Type != CBORType.Array)
            {
                throw new CBORException("Supplied message is not a valid COSE security object");
            }

            // If the message is tagged, it must have the message tag for a COSE_Sign1 message.
            //
            if (message.IsTagged)
            {
                if (message.GetAllTags().Length != 1)
                {
                    throw new CBORException("Invalid object - too many tags");
                }
                if (MessageTag != message.MostInnerTag.ToInt32Unchecked())
                {
                    throw new CBORException(String.Format(
                                                "Invalid COSE_Sign1 structure - Expected {0} tag - but was {1}",
                                                MessageTag, message.MostInnerTag.ToInt32Unchecked()));
                }
            }

            if (message.Count != 4)
            {
                throw new CBORException(String.Format(
                                            "Invalid COSE_Sign1 structure - Expected an array of 4 items - but array has {0} items", message.Count));
            }
            if (message[0].Type == CBORType.ByteString)
            {
                ProtectedAttributesEncoding = message[0].GetByteString();

                if (message[0].GetByteString().Length == 0)
                {
                    ProtectedAttributes = CBORObject.NewMap();
                }
                else
                {
                    ProtectedAttributes = CBORObject.DecodeFromBytes(ProtectedAttributesEncoding);
                    if (this.ProtectedAttributes.Count == 0)
                    {
                        this.ProtectedAttributesEncoding = new byte[0];
                    }
                }
            }
            else
            {
                throw new CBORException(String.Format("Invalid COSE_Sign1 structure - " +
                                                      "Expected item at position 1/4 to be a bstr which is the encoding of the protected attributes, but was {0}",
                                                      message[0].Type));
            }

            if (message[1].Type == CBORType.Map)
            {
                UnprotectedAttributes = message[1];
            }
            else
            {
                throw new CBORException(String.Format(
                                            "Invalid COSE_Sign1 structure - Expected item at position 2/4 to be a Map for unprotected attributes, but was {0}",
                                            message[1].Type));
            }

            if (message[2].Type == CBORType.ByteString)
            {
                Content = message[2].GetByteString();
            }
            else if (!message[2].IsNull)
            {
                throw new CBORException(String.Format(
                                            "Invalid COSE_Sign1 structure - Expected item at position 3/4 to be a bstr holding the payload, but was {0}",
                                            message[2].Type));
            }

            if (message[3].Type == CBORType.ByteString)
            {
                Signature = message[3].GetByteString();
            }
            else
            {
                throw new CBORException(String.Format(
                                            "Invalid COSE_Sign1 structure - Expected item at position 4/4 to be a bstr holding the signature, but was {0}",
                                            message[3].Type));
            }
        }
示例#2
0
       private static CBORObject FromObjectAndInnerTags(
 object objectValue,
 CBORObject objectWithTags)
       {
           CBORObject newObject = CBORObject.FromObject(objectValue);
             if (!objectWithTags.IsTagged) {
           return newObject;
             }
             objectWithTags = objectWithTags.UntagOne();
             if (!objectWithTags.IsTagged) {
           return newObject;
             }
             EInteger[] tags = objectWithTags.GetAllTags();
             for (int i = tags.Length - 1; i >= 0; --i) {
           newObject = CBORObject.FromObjectAndTag(newObject, tags[i]);
             }
             return newObject;
       }
示例#3
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);
        }