Beispiel #1
0
        public override CBORObject Encode()
        {
            CBORObject obj;

            obj = CBORObject.NewArray();

            if ((ProtectedMap != null) && (ProtectedMap.Count > 0))
            {
                obj.Add(ProtectedMap.EncodeToBytes());
            }
            else
            {
                obj.Add(new byte[0]);
            }

            ProtectedBytes = obj[0].GetByteString();

            ProcessCounterSignatures();

            if ((UnprotectedMap == null) || (UnprotectedMap.Count == 0))
            {
                obj.Add(CBORObject.NewMap());
            }
            else
            {
                obj.Add(UnprotectedMap);  // Add unprotected attributes
            }
            obj.Add(rgbContent);

            PerformSignature();

            obj.Add(_rgbSignature);
            return(obj);
        }
Beispiel #2
0
        private byte[] BuildContentBytes()
#endif
        {
            CBORObject obj = CBORObject.NewArray();

            obj.Add(_strContext);
            if (ProtectedBytes == null)
            {
                if (ProtectedMap.Count > 0)
                {
                    ProtectedBytes = ProtectedMap.EncodeToBytes();
                }
                else
                {
                    ProtectedBytes = new byte[0];
                }
            }
            obj.Add(ProtectedBytes);
            if (ExternalData != null)
            {
                obj.Add(CBORObject.FromObject(ExternalData));
            }
            else
            {
                obj.Add(CBORObject.FromObject(new byte[0]));
            }
            obj.Add(rgbContent);

            return(obj.EncodeToBytes());
        }
Beispiel #3
0
        public void PerformSignature()
        {
            CBORObject cborProtected = CBORObject.FromObject(new byte[0]);

            if ((ProtectedMap != null) && (ProtectedMap.Count > 0))
            {
                byte[] rgb = ProtectedMap.EncodeToBytes();
                cborProtected = CBORObject.FromObject(rgb);
            }

            if (_rgbSignature == null)
            {
                CBORObject signObj = CBORObject.NewArray();
                signObj.Add(_context);
                signObj.Add(cborProtected);
                signObj.Add(ExternalData); // External AAD
                signObj.Add(rgbContent);

                _rgbSignature = _Sign(toBeSigned());

#if FOR_EXAMPLES
                m_toBeSigned = signObj.EncodeToBytes();
#endif
            }
        }
Beispiel #4
0
        public CBORObject EncodeToCBORObject(byte[] bodyAttributes, byte[] body)
        {
            CBORObject obj = CBORObject.NewArray();

            CBORObject cborProtected = CBORObject.FromObject(new byte[0]);

            if ((ProtectedMap != null) && (ProtectedMap.Count > 0))
            {
                byte[] rgb = ProtectedMap.EncodeToBytes();
                cborProtected = CBORObject.FromObject(rgb);
            }

            ProtectedBytes = cborProtected.GetByteString();
            obj.Add(cborProtected);

            if (rgbSignature == null)
            {
                rgbSignature = Sign(toBeSigned(body, bodyAttributes));
            }

            ProcessCounterSignatures();

            if ((UnprotectedMap == null))
            {
                obj.Add(CBORObject.NewMap());
            }
            else
            {
                obj.Add(UnprotectedMap); // Add unprotected attributes
            }

            obj.Add(rgbSignature);
            return(obj);
        }
Beispiel #5
0
        protected byte[] toBeSigned(byte[] rgbContent, byte[] bodyAttributes)
        {
            CBORObject cborProtected = CBORObject.FromObject(new byte[0]);

            if ((ProtectedMap != null) && (ProtectedMap.Count > 0))
            {
                byte[] rgb = ProtectedMap.EncodeToBytes();
                cborProtected = CBORObject.FromObject(rgb);
            }

            if (rgbContent == null)
            {
                rgbContent = new byte[0];
            }

            CBORObject signObj = CBORObject.NewArray();

            signObj.Add(context);
            signObj.Add(bodyAttributes);
            signObj.Add(cborProtected);
            signObj.Add(ExternalData);
            signObj.Add(rgbContent);

#if FOR_EXAMPLES
            m_toBeSigned = signObj.EncodeToBytes();
#endif
            return(signObj.EncodeToBytes());
        }
Beispiel #6
0
        /// <summary>
        /// Encode the COSE Encrypt0 item to a CBOR tree.
        /// <see cref="Encrypt"/> must be done prior to calling this function.
        /// </summary>
        /// <returns></returns>
        public override CBORObject Encode()
        {
            CBORObject cbor;

            if (RgbEncrypted == null)
            {
                throw new CoseException("Must call Encrypt first");
            }

            ProcessCounterSignatures();

            cbor = CBORObject.NewArray();

            if (ProtectedMap.Count > 0)
            {
                cbor.Add(ProtectedMap.EncodeToBytes());
            }
            else
            {
                cbor.Add(CBORObject.FromObject(new byte[0]));
            }

            cbor.Add(UnprotectedMap); // Add unprotected attributes

            if (m_emitContent)
            {
                cbor.Add(RgbEncrypted);                     // Add ciphertext
            }
            else
            {
                cbor.Add(CBORObject.Null);
            }

            return(cbor);
        }
Beispiel #7
0
        public override CBORObject Encode()
        {
            CBORObject obj;

            if (RgbTag == null)
            {
                MAC();
            }

            obj = CBORObject.NewArray();

            if (ProtectedMap.Count > 0)
            {
                obj.Add(ProtectedMap.EncodeToBytes());
            }
            else
            {
                obj.Add(new byte[0]);
            }

            if (UnprotectedMap.Count > 0)
            {
                obj.Add(UnprotectedMap);                           // Add unprotected attributes
            }
            else
            {
                obj.Add(CBORObject.NewMap());
            }

            obj.Add(rgbContent);      // Add ciphertext
            obj.Add(RgbTag);

            if ((!m_forceArray) && (_recipientList.Count == 1))
            {
                CBORObject recipient = _recipientList[0].Encode();

                for (int i = 0; i < recipient.Count; i++)
                {
                    obj.Add(recipient[i]);
                }
            }
            else if (_recipientList.Count > 0)
            {
                CBORObject recipients = CBORObject.NewArray();

                foreach (Recipient key in _recipientList)
                {
                    recipients.Add(key.Encode());
                }
                obj.Add(recipients);
            }
            else
            {
                obj.Add(null);      // No recipients - set to null
            }

            return(obj);
        }
Beispiel #8
0
        public byte[] getAADBytes()
        {
            CBORObject obj = CBORObject.NewArray();

            obj.Add(_context);
            if (ProtectedMap.Count == 0)
            {
                ProtectedBytes = new byte[0];
            }
            else
            {
                ProtectedBytes = ProtectedMap.EncodeToBytes();
            }

            obj.Add(ProtectedBytes);

            obj.Add(CBORObject.FromObject(ExternalData));

            // Console.WriteLine("COSE AAD = " + BitConverter.ToString(obj.EncodeToBytes()));

            return(obj.EncodeToBytes());
        }
Beispiel #9
0
        private byte[] toBeSigned()
        {
            CBORObject cborProtected = CBORObject.FromObject(new byte[0]);

            if ((ProtectedMap != null) && (ProtectedMap.Count > 0))
            {
                byte[] rgb = ProtectedMap.EncodeToBytes();
                cborProtected = CBORObject.FromObject(rgb);
            }

            CBORObject signObj = CBORObject.NewArray();

            signObj.Add(_context);
            signObj.Add(cborProtected);
            signObj.Add(ExternalData); // External AAD
            signObj.Add(rgbContent);

#if FOR_EXAMPLES
            m_toBeSigned = signObj.EncodeToBytes();
#endif

            return(signObj.EncodeToBytes());
        }
Beispiel #10
0
        public CBORObject EncodeToJSON(byte[] body)
        {
            CBORObject obj = CBORObject.NewMap();

            if (protectedB64 != null)
            {
                obj.Add("protected", protectedB64);
            }
            else if (ProtectedMap.Count > 0)
            {
                protectedB64 = Message.base64urlencode(Encoding.UTF8.GetBytes(JSON.ToJsonString(ProtectedMap)));
                obj.Add("protected", protectedB64);
            }

            if (UnprotectedMap.Count > 0)
            {
                obj.Add("header", UnprotectedMap);                           // Add unprotected attributes
            }
            String str = "";

            if (ProtectedMap.ContainsKey("b64") && ProtectedMap["b64"].AsBoolean() == false)
            {
                str += protectedB64 + "." + Encoding.UTF8.GetString(body);
            }
            else
            {
                str += protectedB64 + "." + Message.base64urlencode(body);
            }

#if DEBUG
            ToBeSigned = str;
#endif

            obj.Add("signature", Message.base64urlencode(Sign(Encoding.UTF8.GetBytes(str))));

            return(obj);
        }
Beispiel #11
0
        public override CBORObject Encode()
        {
            CBORObject obj;

            if (RgbTag == null)
            {
                throw new CoseException("Must call Compute before encoding");
            }
            ProcessCounterSignatures();

            obj = CBORObject.NewArray();

            if (ProtectedMap.Count > 0)
            {
                obj.Add(ProtectedMap.EncodeToBytes());
            }
            else
            {
                obj.Add(new byte[0]);
            }



            if (UnprotectedMap.Count > 0)
            {
                obj.Add(UnprotectedMap);                           // Add unprotected attributes
            }
            else
            {
                obj.Add(CBORObject.NewMap());
            }

            obj.Add(rgbContent);      // Add ciphertext
            obj.Add(RgbTag);

            return(obj);
        }
Beispiel #12
0
        private void AES_CCM(byte[] k)
        {
            CcmBlockCipher cipher = new CcmBlockCipher(new AesEngine());
            KeyParameter   contentKey;
            int            cbitTag = 64;

            //  The requirements from JWA
            //  IV is 96 bits
            //  Authentication tag is 128 bits
            //  key sizes are 128, 192 and 256 bits

            _iv = new byte[96 / 8];
            s_PRNG.NextBytes(_iv);

            contentKey = new KeyParameter(k);

            //  Build the object to be hashed

            byte[] a = new byte[0];
            if (ProtectedMap != null)
            {
                a = Encoding.UTF8.GetBytes(ProtectedMap.ToString());
            }

            AeadParameters parameters = new AeadParameters(contentKey, 128, _iv, a);

            cipher.Init(true, parameters);

            byte[] c   = new byte[cipher.GetOutputSize(payload.Length)];
            int    len = cipher.ProcessBytes(payload, 0, payload.Length, c, 0);

            cipher.DoFinal(c, len);

            Array.Resize(ref c, c.Length - (128 / 8) + (cbitTag / 8));
            _RgbEncrypted = c;
        }
Beispiel #13
0
        public override CBORObject Encode()
        {
            CBORObject obj;

            byte[] rgbProtected;

            obj = CBORObject.NewArray();

            if ((ProtectedMap != null) && (ProtectedMap.Count > 0))
            {
                rgbProtected = ProtectedMap.EncodeToBytes();
                obj.Add(rgbProtected);
            }
            else
            {
                rgbProtected = new byte[0];
                obj.Add(rgbProtected);
            }

            if (CounterSignerList.Count() != 0)
            {
                if (CounterSignerList.Count() == 1)
                {
                    AddAttribute(HeaderKeys.CounterSignature, CounterSignerList[0].EncodeToCBORObject(rgbProtected, rgbContent), UNPROTECTED);
                }
                else
                {
                    foreach (CounterSignature sig in CounterSignerList)
                    {
                        sig.EncodeToCBORObject(rgbProtected, rgbContent);
                    }
                }
            }

            if ((UnprotectedMap == null) || (UnprotectedMap.Count == 0))
            {
                obj.Add(CBORObject.NewMap());
            }
            else
            {
                obj.Add(UnprotectedMap);  // Add unprotected attributes
            }
            obj.Add(rgbContent);

            if ((signerList.Count == 1) && !m_forceArray)
            {
                CBORObject recipient = signerList[0].EncodeToCBORObject(obj[0].EncodeToBytes(), rgbContent);

                for (int i = 0; i < recipient.Count; i++)
                {
                    obj.Add(recipient[i]);
                }
            }
            else if (signerList.Count > 0)
            {
                CBORObject signers = CBORObject.NewArray();

                foreach (Signer key in signerList)
                {
                    signers.Add(key.EncodeToCBORObject(rgbProtected, rgbContent));
                }
                obj.Add(signers);
            }
            else
            {
                obj.Add(null);      // No recipients - set to null
            }
            return(obj);
        }
Beispiel #14
0
        /// <summary>
        /// Encrypt the message based on attributes and recipients.
        /// </summary>
        public virtual void Encrypt()
        {
            string alg = null;

            //  Get the algorithm we are using - the default is AES GCM

            try {
                alg = FindAttribute("enc").AsString();
            }
            catch {
                foreach (Recipient r in RecipientList)
                {
                    CBORObject alg2 = r.FindAttribute("enc");
                    if (alg2 != null)
                    {
                        if (alg2.Type != CBORType.TextString || (alg != null && alg != alg2.AsString()))
                        {
                            throw new JoseException("Multiple content encryption algorithms have been specified.");
                        }
                        alg = alg2.AsString();
                    }
                }

                if (alg == null)
                {
                    throw new JoseException("Content encryption algorithm has not been specified.");
                }
            }

            byte[] contentKey = null;

            //  Determine if we are doing a direct encryption
            int recipientTypes = 0;

            if (RecipientList.Count == 0)
            {
                throw new JoseException("Must have at least one recipient for the message");
            }

            foreach (Recipient key in RecipientList)
            {
                switch (key.RecipientType)
                {
                case RecipientType.Direct:
                case RecipientType.KeyAgreeDirect:
                    if ((recipientTypes & 1) != 0)
                    {
                        throw new JoseException("It is not legal to have two direct recipients in a message");
                    }
                    recipientTypes |= 1;
                    contentKey      = key.GetKey(alg, this);
                    break;

                default:
                    recipientTypes |= 2;
                    break;
                }
            }

            if (recipientTypes == 3)
            {
                throw new JoseException("It is not legal to mix direct and indirect recipients in a message");
            }

            if (contentKey == null)
            {
                switch (alg)
                {
                case "A128GCM":
                case "AES-128-CCM-64":
                    contentKey = new byte[128 / 8];
                    break;

                case "A192GCM":
                case "AES192GCM":
                    contentKey = new byte[192 / 8];
                    break;

                case "A256GCM":
                case "AES256GCM":
                    contentKey = new byte[256 / 8];
                    break;

                case "A128CBC-HS256":
                    contentKey = new byte[2 * 128 / 8];
                    break;

                case "A192CBC-HS256":
                    contentKey = new byte[2 * 192 / 8];
                    break;

                case "A256CBC-HS256":
                    contentKey = new byte[2 * 256 / 8];
                    break;

                default:
                    throw new JoseException($"Unrecognized content encryption algorithm '{alg}'");
                }

                s_PRNG.NextBytes(contentKey);
            }

            foreach (Recipient key in RecipientList)
            {
                key.SetContent(contentKey);
                key.Encrypt(this);
            }

            //  Encode the protected attributes if there are any

            if (ProtectedMap.Count > 0)
            {
                _strProtected = base64urlencode(Encoding.UTF8.GetBytes(ProtectedMap.ToString()));
            }

            byte[] saveContent = payload;
            if (ProtectedMap.ContainsKey("zip"))
            {
                MemoryStream  stm2   = new MemoryStream();
                DeflateStream zipStm = new DeflateStream(stm2, CompressionMode.Compress);

                zipStm.Write(payload, 0, payload.Length);
                zipStm.Close();

                payload = stm2.GetBuffer();
            }

            switch (alg)
            {
            case "A128GCM":
            case "A192GCM":
            case "A256GCM":
                AES_GCM_Encrypt(contentKey);
                break;

            case "AES-128-CCM-64":
                AES_CCM(contentKey);
                break;

            case "A128CBC-HS256":
            case "A192CBC-HS256":
            case "A256CBC-HS256":
                AES_CBC_MAC_Encrypt(alg, contentKey);
                break;

            default:
                throw new JoseException("Internal Error:  We should never get here.");
            }

            payload = saveContent;
        }
Beispiel #15
0
        /// <inheritdoc />
        protected override string InternalEncodeCompressed()
        {
            CBORObject obj3;
            CBORObject objRecip = null;
            string     str      = "";

            if (RecipientList.Count() != 1)
            {
                throw new JoseException("Compact encoding cannot have more than one recipient");
            }


            if (_Aad != null)
            {
                throw new JoseException("Compact encoding cannot have additional authenticated data");
            }

            if (RecipientList[0].UnprotectedMap.Count != 0)
            {
                if (_RgbEncrypted == null)
                {
                    foreach (CBORObject o in RecipientList[0].UnprotectedMap.Keys)
                    {
                        ProtectedMap.Add(o, RecipientList[0].UnprotectedMap[o]);
                    }
                    RecipientList[0].UnprotectedMap.Clear();
                }
            }

            ForceArray(true);
            obj3 = EncodeToJSON();

            if (obj3.ContainsKey("recipients"))
            {
                objRecip = obj3["recipients"][0];
            }

            if (obj3.ContainsKey("aad"))
            {
                throw new JoseException("Compact encoding cannot have additional authenticated data");
            }

            if (objRecip != null && objRecip.ContainsKey("header"))
            {
                throw new JoseException("Compact encoding cannot have recipient header data");
            }

            if (obj3.ContainsKey("protected"))
            {
                str += obj3["protected"].AsString();
            }
            str += ".";
            if (obj3.ContainsKey("unprotected"))
            {
                throw new JoseException("Compact encoding cannot have unprotected attributes");
            }

            if (objRecip != null && objRecip.ContainsKey("encrypted_key"))
            {
                str += objRecip["encrypted_key"].AsString();
            }
            str += ".";
            if (obj3.ContainsKey("iv"))
            {
                str += obj3["iv"].AsString();
            }
            str += ".";
            if (obj3.ContainsKey("ciphertext"))
            {
                str += obj3["ciphertext"].AsString();
            }
            str += ".";
            if (obj3.ContainsKey("tag"))
            {
                str += obj3["tag"].AsString();
            }

            return(str);
        }
Beispiel #16
0
        /// <inheritdoc />
        protected override CBORObject InternalEncodeToJSON(bool fCompact)
        {
            CBORObject obj = CBORObject.NewMap();

            if (_RgbEncrypted == null)
            {
                Encrypt();
            }

            if (ProtectedMap.Count > 0)
            {
                obj.Add("protected", base64urlencode(Encoding.UTF8.GetBytes(ProtectedMap.ToString())));
            }

            if (UnprotectedMap.Count > 0)
            {
                obj.Add("unprotected", UnprotectedMap);                           // Add unprotected attributes
            }
            if (_iv != null)
            {
                obj.Add("iv", base64urlencode(_iv));                     // Add iv
            }
            if (_Aad != null)
            {
                obj.Add("aad", Encoding.UTF8.GetString(_Aad));
            }

            if (_RgbEncrypted != null)
            {
                obj.Add("ciphertext", base64urlencode(_RgbEncrypted));                             // Add ciphertext
            }
            obj.Add("tag", base64urlencode(_Tag));

            if (RecipientList.Count > 0)
            {
                CBORObject recipients = CBORObject.NewArray();

                foreach (Recipient key in RecipientList)
                {
                    CBORObject j = key.EncodeToJSON();
                    if ((j != null) && (j.Count != 0))
                    {
                        recipients.Add(j);
                    }
                }

                if (fCompact)
                {
                    if (recipients.Count != 1)
                    {
                        throw new JoseException("Compact encoding must be for one recipient");
                    }
                    if (recipients[0].ContainsKey("encrypted_key"))
                    {
                        obj.Add("encrypted_key", recipients[0]["encrypted_key"]);
                    }

                    if (recipients[0].ContainsKey("header"))
                    {
                        obj.Add("header", recipients[0]["header"]);
                    }
                }
                else
                {
                    if (recipients.Count > 0)
                    {
                        obj.Add("recipients", recipients);
                    }
                }
            }
            else
            {
                throw new JoseException("Must have one or more recipients");
            }
            return(obj);
        }
Beispiel #17
0
        public bool Verify(SignMessage msg)
        {
            string alg = FindAttribute("alg").AsString();

            JWK key = keyToSign;

            IDigest digest;
            IDigest digest2;

            switch (alg)
            {
            case "RS256":
            case "ES256":
            case "PS256":
            case "HS256":
                digest  = new Sha256Digest();
                digest2 = new Sha256Digest();
                break;

            case "RS384":
            case "ES384":
            case "PS384":
            case "HS384":
                digest  = new Sha384Digest();
                digest2 = new Sha384Digest();
                break;

            case "RS512":
            case "ES512":
            case "PS512":
            case "HS512":
                digest  = new Sha512Digest();
                digest2 = new Sha512Digest();
                break;

            case "EdDSA":
                digest  = null;
                digest2 = null;
                break;

            default:
                throw new JoseException("Unknown signature algorithm");
            }

            //

            byte[] toBeSigned;
            string str  = "";
            string body = Encoding.UTF8.GetString(msg.payloadB64);

            if (ProtectedMap.ContainsKey("b64") && ProtectedMap["b64"].AsBoolean() == false)
            {
                str += protectedB64 + "." + body;
            }
            else
            {
                str += protectedB64 + "." + body;
            }

            toBeSigned = Encoding.UTF8.GetBytes(str);


            switch (alg)
            {
            case "RS256":
            case "RS384":
            case "RS512": {
                if (key.AsString("kty") != "RSA")
                {
                    throw new JoseException("Wrong Key");
                }
                RsaDigestSigner  signer = new RsaDigestSigner(digest);
                RsaKeyParameters pub    = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e"));

                signer.Init(false, pub);
                signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                if (!signer.VerifySignature(signature))
                {
                    throw new JoseException("Message failed to verify");
                }
            }
            break;

            case "PS256":
            case "PS384":
            case "PS512": {
                PssSigner        signer = new PssSigner(new RsaEngine(), digest, digest2, digest2.GetDigestSize());
                RsaKeyParameters pub    = new RsaKeyParameters(false, key.AsBigInteger("n"), key.AsBigInteger("e"));

                signer.Init(false, pub);
                signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                if (!signer.VerifySignature(signature))
                {
                    throw new JoseException("Message failed to verify");
                }
            }

            break;

            case "ES256":
            case "ES384":
            case "ES512": {
                digest.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                byte[] o1 = new byte[digest.GetDigestSize()];
                digest.DoFinal(o1, 0);

                if (key.AsString("kty") != "EC")
                {
                    throw new JoseException("Wrong Key Type");
                }

                ICipherParameters pubKey = keyToSign.AsPublicKey();
                ECDsaSigner       ecdsa  = new ECDsaSigner();
                ecdsa.Init(false, pubKey);

                BigInteger r = new BigInteger(1, signature, 0, signature.Length / 2);
                BigInteger s = new BigInteger(1, signature, signature.Length / 2, signature.Length / 2);

                if (!ecdsa.VerifySignature(o1, r, s))
                {
                    throw new JoseException("Signature did not validate");
                }
            }
            break;

            case "HS256":
            case "HS384":
            case "HS512": {
                HMac         hmac = new HMac(digest);
                KeyParameter K    = new KeyParameter(Message.base64urldecode(key.AsString("k")));
                hmac.Init(K);
                hmac.BlockUpdate(toBeSigned, 0, toBeSigned.Length);

                byte[] resBuf = new byte[hmac.GetMacSize()];
                hmac.DoFinal(resBuf, 0);

                bool fVerify = true;
                for (int i = 0; i < resBuf.Length; i++)
                {
                    if (resBuf[i] != signature[i])
                    {
                        fVerify = false;
                    }
                }

                if (!fVerify)
                {
                    throw new JoseException("Signature did not validate");
                }
            }
            break;

            case "EdDSA": {
                ISigner eddsa;
                if (key.AsString("kty") != "OKP")
                {
                    throw new JoseException("Wrong Key Type");
                }
                switch (key.AsString("crv"))
                {
                case "Ed25519": {
                    Ed25519PublicKeyParameters privKey =
                        new Ed25519PublicKeyParameters(key.AsBytes("X"), 0);
                    eddsa = new Ed25519Signer();
                    eddsa.Init(false, privKey);

                    eddsa.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                    if (!eddsa.VerifySignature(signature))
                    {
                        throw new JoseException("Signature did not validate");
                    }

                    break;
                }

                default:
                    throw new JoseException("Unknown algorithm");
                }

                break;
            }

            default:
                throw new JoseException("Unknown algorithm");
            }

            return(true);
        }