示例#1
0
        public CoralFormField(CBORObject type, CBORObject value, Cori baseCori, CoralDictionary dictionary)
        {
            CBORObject o = (CBORObject)dictionary.Reverse(type, false);

            if (o == null)
            {
                FieldTypeInt = type.AsInt32();
            }
            else if (o.Type == CBORType.Array)
            {
                FieldType = new Cori(o);
                if (type.Type == CBORType.Integer)
                {
                    FieldTypeInt = type.AsInt32();
                }
            }
            else
            {
                throw new ArgumentException("Not a valid form field type");
            }

            o = (CBORObject)dictionary.Reverse(value, true);

            if (o == null)
            {
                LiteralInt = value.AsInt32();
            }
            else if (o.Type == CBORType.Array)
            {
                Url = new Cori(o);
                if (baseCori != null)
                {
                    Url = Url.ResolveTo(baseCori);
                }

                if (value.Type == CBORType.Integer)
                {
                    LiteralInt = value.Untag().AsInt32();
                }
            }
            else
            {
                Literal = o;
                if (value.IsTagged && value.HasOneTag(CoralDictionary.DictionaryTag) && value.Type == CBORType.Integer)
                {
                    LiteralInt = value.Untag().AsInt32();
                }
            }
        }
示例#2
0
        public static String GetAlgorithmName(CBORObject cborValue)
        {
            switch (cborValue.AsInt32())
            {
            case -7:
                return("SHA256withECDSA");

            case -35:
                return("SHA384withECDSA");

            case -36:
                return("SHA512withECDSA");

            case -37:
                return("SHA256withRSA/PSS");

            case -38:
                return("SHA384withRSA/PSS");

            case -39:
                return("SHA512withRSA/PSS");

            default:
                break;
            }
            return(null);
        }
示例#3
0
        public int GetKeySize(CBORObject alg)
        {
            if (alg.Type == CBORType.TextString)
            {
                throw new CoseException("Unknown Algorithm Specified");
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.AES_GCM_128:
                case AlgorithmValuesInt.AES_CCM_16_64_128:
                case AlgorithmValuesInt.AES_CCM_16_128_128:
                case AlgorithmValuesInt.AES_CCM_64_64_128:
                case AlgorithmValuesInt.AES_CCM_64_128_128:
                    return(128);

                case AlgorithmValuesInt.AES_GCM_192:
                    return(192);

                case AlgorithmValuesInt.AES_GCM_256:
                case AlgorithmValuesInt.AES_CCM_16_64_256:
                case AlgorithmValuesInt.AES_CCM_16_128_256:
                case AlgorithmValuesInt.AES_CCM_64_64_256:
                case AlgorithmValuesInt.AES_CCM_64_128_256:
                case AlgorithmValuesInt.ChaCha20_Poly1305:
                    return(256);

                default:
                    throw new CoseException("Unknown Algorithm Specified");
                }
            }
            throw new CoseException("Invalid Algorithm Specified");
        }
示例#4
0
        public void LookupString()
        {
            CBORObject result = _dictionary.Lookup("http://www.iana.org/assignments/relation/item>", false);

            Assert.AreEqual(CBORType.Integer, result.Type);
            Assert.AreEqual(1, result.AsInt32());

            result = _dictionary.Lookup(CBORObject.FromObject("http://www.iana.org/assignments/relation/item>"), false);
            Assert.AreEqual(CBORType.Integer, result.Type);
            Assert.AreEqual(1, result.AsInt32());

            result = _dictionary.Lookup(CBORObject.FromObject("http://www.iana.org/assignments/relation/item>"), true);
            Assert.AreEqual(CBORType.Integer, result.Type);
            Assert.IsTrue(result.IsTagged);
            Assert.IsTrue(result.HasOneTag(CoralDictionary.DictionaryTag));
            Assert.AreEqual(1, result.Untag().AsInt32());
        }
示例#5
0
        protected void DecryptWithKey(byte[] CEK)
        {
            if (RgbEncrypted == null)
            {
                throw new CoseException("No Encrypted Content Specified.");
            }
            if (CEK == null)
            {
                throw new CoseException("Null Key Supplied");
            }

            CBORObject alg = FindAttribute(HeaderKeys.Algorithm);

            if (alg == null)
            {
                throw new CoseException("No Algorithm Specified");
            }

            if (alg.Type == CBORType.TextString)
            {
                throw new CoseException("Algorithm not supported " + alg.AsString());
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.AES_GCM_128:
                case AlgorithmValuesInt.AES_GCM_192:
                case AlgorithmValuesInt.AES_GCM_256:
                    AES_Decrypt(alg, CEK);
                    break;

                case AlgorithmValuesInt.AES_CCM_16_64_128:
                case AlgorithmValuesInt.AES_CCM_16_64_256:
                case AlgorithmValuesInt.AES_CCM_16_128_128:
                case AlgorithmValuesInt.AES_CCM_16_128_256:
                case AlgorithmValuesInt.AES_CCM_64_64_128:
                case AlgorithmValuesInt.AES_CCM_64_64_256:
                case AlgorithmValuesInt.AES_CCM_64_128_128:
                case AlgorithmValuesInt.AES_CCM_64_128_256:
                    AES_CCM_Decrypt(alg, CEK);
                    break;

#if CHACHA20
                case AlgorithmValuesInt.ChaCha20_Poly1305:
                    ChaCha20_Poly1305_Decrypt(alg, CEK);
                    break;
#endif

                default:
                    throw new CoseException("Unknown algorithm found");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }
        }
示例#6
0
        public void LookupInteger()
        {
            CBORObject result = _dictionary.Lookup(CBORObject.FromObject(5), true);

            Assert.AreEqual(CBORType.Integer, result.Type);
            Assert.IsFalse(result.IsTagged);
            Assert.AreEqual(5, result.AsInt32());

            result = _dictionary.Lookup(CBORObject.FromObject(5), false);
            Assert.AreEqual(CBORType.Integer, result.Type);
            Assert.IsFalse(result.IsTagged);
            Assert.AreEqual(5, result.AsInt32());

            result = _dictionary.Lookup(CBORObject.FromObject(-5), true);
            Assert.AreEqual(CBORType.Integer, result.Type);
            Assert.IsFalse(result.IsTagged);
            Assert.AreEqual(-5, result.AsInt32());
        }
示例#7
0
        public void AddKey()
        {
            CBORObject result = _dictionary.Lookup("missing", false);

            Assert.AreEqual("missing", result.AsString());

            _dictionary.Add(7, "missing");

            result = _dictionary.Lookup("missing", false);
            Assert.AreEqual(7, result.AsInt32());

            Cori cori = new Cori("coap://host2:99/path1/path2/path4");

            _dictionary.Add(8, cori);
            Cori ciri2 = new Cori(cori.ToString());

            result = _dictionary.Lookup(ciri2, false);
            Assert.AreEqual(8, result.AsInt32());
            _dictionary.Add(9, new Cori(CBORObject.DecodeFromBytes(Hex.Decode("8405000664666F726D"))));

            Assert.ThrowsException <ArgumentException>(() => _dictionary.Add(10, CBORObject.FromObject(DateTime.UtcNow)));
        }
示例#8
0
        private static CBORObject readString(Stream stream, char firstChar)
        {
            var builder = new StringBuilder();

            if (firstChar < (int)'0' && firstChar > (int)'9')
            {
                throw new CBORException("Invalid integer encoding");
            }
            builder.Append(firstChar);
            while (true)
            {
                int c = stream.ReadByte();
                if (c < 0)
                {
                    throw new CBORException("Premature end of data");
                }
                if (c >= (int)'0' && c <= (int)'9')
                {
                    builder.Append((char)c);
                }
                else if (c == (int)':')
                {
                    break;
                }
                else
                {
                    throw new CBORException("Invalid integer encoding");
                }
            }
            CBORObject number = CBORDataUtilities.ParseJSONNumber(
                builder.ToString(),
                true,
                true);
            var length = 0;

            try {
                length = number.AsInt32();
            } catch (ArithmeticException ex) {
                throw new CBORException("Length too long", ex);
            }
            builder = new StringBuilder();
            switch (DataUtilities.ReadUtf8(stream, length, builder, false))
            {
            case -2:
                throw new CBORException("Premature end of data");

            case -1:
                throw new CBORException("Invalid UTF-8");
            }
            return(CBORObject.FromObject(builder.ToString()));
        }
示例#9
0
        public X9ECParameters GetCurve()
        {
            CBORObject cborKeyType = m_map[CoseKeyKeys.KeyType];

            if (cborKeyType == null)
            {
                throw new CoseException("Malformed key struture");
            }
            if ((cborKeyType.Type != CBORType.Number) &&
                !((cborKeyType == GeneralValues.KeyType_EC) || (cborKeyType == GeneralValues.KeyType_OKP)))
            {
                throw new CoseException("Not an EC key");
            }

            CBORObject cborCurve = m_map[CoseKeyParameterKeys.EC_Curve];

            if (cborCurve.Type == CBORType.Number)
            {
                switch ((GeneralValuesInt)cborCurve.AsInt32())
                {
                case GeneralValuesInt.P256: return(NistNamedCurves.GetByName("P-256"));

                case GeneralValuesInt.P384: return(NistNamedCurves.GetByName("P-384"));

                case GeneralValuesInt.P521: return(NistNamedCurves.GetByName("P-521"));

                case GeneralValuesInt.X25519: return(CustomNamedCurves.GetByName("CURVE25519"));

                default:
                    throw new CoseException("Unsupported key type: " + cborKeyType.AsInt32());
                }
            }
            else if (cborCurve.Type == CBORType.TextString)
            {
                switch (cborCurve.AsString())
                {
                default:
                    throw new CoseException("Unsupported key type: " + cborKeyType.AsString());
                }
            }
            else
            {
                throw new CoseException("Incorrectly encoded key type");
            }
        }
示例#10
0
        public void SetClaim(CBORObject claim, CBORObject value)
        {
            switch ((ClaimID)claim.AsInt32())
            {
            case ClaimID.Issuer:
            case ClaimID.Subject:
            case ClaimID.Audience:
                if (value.Type != CBORType.TextString)
                {
                    throw new CwtException("Claim value type is incorrect for the claim");
                }
                break;

            case ClaimID.ExpirationTime:
            case ClaimID.NotBefore:
            case ClaimID.IssuedAt:
                if (value.Type != CBORType.Number)
                {
                    throw new CwtException("Claim value type is incorrect for the claim");
                }
                if ((value.GetTags().Count() != 1) || (value.OutermostTag.intValue() != 1))
                {
                    throw new CwtException("Claim value type is incorrect for the claim");
                }
                break;

            case ClaimID.CWTId:
                if (value.Type != CBORType.ByteString)
                {
                    throw new CwtException("Claim value type is incorrect for the claim");
                }
                break;

            default:
                //  We don't know how to check this
                break;
            }

            claims[claim] = value;
        }
示例#11
0
        public bool Validate(Recipient recipientReceiver)
        {
            byte[] rgbKey = null;
            int    cbitKey;

            CBORObject alg = FindAttribute(COSE.HeaderKeys.Algorithm);

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "AES-CMAC-128/64":
                    cbitKey = 128;
                    break;

                case "AES-CMAC-256/64":
                    cbitKey = 256;
                    break;

                default:
                    throw new Exception("MAC algorithm is not recognized");
                }
            }
            else if (alg.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256_64:
                case AlgorithmValuesInt.HMAC_SHA_256:
                    cbitKey = 256;
                    break;

                case AlgorithmValuesInt.HMAC_SHA_384: cbitKey = 384; break;

                case AlgorithmValuesInt.HMAC_SHA_512: cbitKey = 512; break;

                case AlgorithmValuesInt.AES_CBC_MAC_128_64:
                case AlgorithmValuesInt.AES_CBC_MAC_128_128:
                    cbitKey = 128;
                    break;

                case AlgorithmValuesInt.AES_CBC_MAC_256_64:
                case AlgorithmValuesInt.AES_CBC_MAC_256_128:
                    cbitKey = 256;
                    break;

                default:
                    throw new Exception("MAC algorithm not recognized" + alg.AsInt32());
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }


            foreach (Recipient msgRecpient in recipientList)
            {
                if (recipientReceiver == msgRecpient)
                {
                    try {
                        rgbKey = msgRecpient.Decrypt(cbitKey, alg);
                    }
                    catch (CoseException) { }
                }
                else if (recipientReceiver == null)
                {
                    ;
                }
                if (rgbKey != null)
                {
                    break;
                }
            }

            if (rgbKey == null)
            {
                throw new CoseException("Recipient not found");
            }

            byte[] rgbCheck;

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "AES-CMAC-128/64":
                case "AES-CMAC-256/64":
                    rgbCheck = AES_CMAC(alg, rgbKey);
                    break;

                default:
                    throw new Exception("MAC algorithm is not recognized");
                }
            }
            else if (alg.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256:
                case AlgorithmValuesInt.HMAC_SHA_384:
                case AlgorithmValuesInt.HMAC_SHA_512:
                case AlgorithmValuesInt.HMAC_SHA_256_64:
                    rgbCheck = HMAC(alg, rgbKey);
                    break;

                case AlgorithmValuesInt.AES_CBC_MAC_128_64:
                case AlgorithmValuesInt.AES_CBC_MAC_128_128:
                case AlgorithmValuesInt.AES_CBC_MAC_256_64:
                case AlgorithmValuesInt.AES_CBC_MAC_256_128:
                    rgbCheck = AES_CBC_MAC(alg, rgbKey);
                    break;

                default:
                    throw new Exception("MAC algorithm not recognized" + alg.AsInt32());
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            bool fReturn = true;

            for (int i = 0; i < rgbCheck.Length; i++)
            {
                fReturn &= (rgbTag[i] == rgbCheck[i]);
            }
            return(fReturn);
        }
示例#12
0
        protected byte[] AES_CBC_MAC(CBORObject alg, byte[] K)
        {
            int cbitKey;
            int cbitTag;
            //  Defaults to PKCS#7

            IBlockCipher aes = new AesFastEngine();

            KeyParameter ContentKey;

            //  The requirements from spec
            //  IV is 128 bits of zeros
            //  key sizes are 128, 192 and 256 bits
            //  Authentication tag sizes are 64 and 128 bits

            byte[] IV = new byte[128 / 8];

            Debug.Assert(alg.Type == CBORType.Number);
            switch ((AlgorithmValuesInt)alg.AsInt32())
            {
            case AlgorithmValuesInt.AES_CBC_MAC_128_64:
                cbitKey = 128;
                cbitTag = 64;
                break;

            case AlgorithmValuesInt.AES_CBC_MAC_256_64:
                cbitKey = 256;
                cbitTag = 64;
                break;

            case AlgorithmValuesInt.AES_CBC_MAC_128_128:
                cbitKey = 128;
                cbitTag = 128;
                break;

            case AlgorithmValuesInt.AES_CBC_MAC_256_128:
                cbitKey = 256;
                cbitTag = 128;
                break;

            default:
                throw new Exception("Unrecognized algorithm");
            }

            IMac mac = new CbcBlockCipherMac(aes, cbitTag, null);

            if (K.Length != cbitKey / 8)
            {
                throw new CoseException("Key is incorrectly sized");
            }
            ContentKey = new KeyParameter(K);

            //  Build the text to be digested

            mac.Init(ContentKey);

            byte[] toDigest = BuildContentBytes();

            byte[] C = new byte[128 / 8];
            mac.BlockUpdate(toDigest, 0, toDigest.Length);
            mac.DoFinal(C, 0);

            byte[] rgbResult = new byte[cbitTag / 8];
            Array.Copy(C, 0, rgbResult, 0, cbitTag / 8);

            return(rgbResult);
        }
示例#13
0
        public bool Validate(byte[] content, byte[] msgAttributes)
        {
            CBORObject alg = null; // Get the set algorithm or infer one

            byte[] bytesToBeSigned = toBeSigned(content, msgAttributes);

            alg = FindAttribute(HeaderKeys.Algorithm);

            if (alg == null)
            {
                throw new Exception("No Signature algorithm known");
            }

            IDigest digest;
            IDigest digest2;

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "PS384":
                    digest  = new Sha384Digest();
                    digest2 = new Sha384Digest();
                    break;

                default:
                    throw new Exception("Unknown signature algorithm");
                }
            }
            else if (alg.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.ECDSA_256:
                case AlgorithmValuesInt.RSA_PSS_256:
                    digest  = new Sha256Digest();
                    digest2 = new Sha256Digest();
                    break;

                case AlgorithmValuesInt.ECDSA_384:
                case AlgorithmValuesInt.RSA_PSS_384:
                    digest  = new Sha384Digest();
                    digest2 = new Sha384Digest();
                    break;

                case AlgorithmValuesInt.ECDSA_512:
                case AlgorithmValuesInt.RSA_PSS_512:
                    digest  = new Sha512Digest();
                    digest2 = new Sha512Digest();
                    break;

                default:
                    throw new CoseException("Unknown signature algorith");
                }
            }
            else
            {
                throw new CoseException("Algorthm incorrectly encoded");
            }

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "PS384": {
                    PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetByteLength());

                    RsaKeyParameters     prv   = new RsaPrivateCrtKeyParameters(keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_n), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_e), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_d), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_p), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_q), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dP), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dQ), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_qInv));
                    ParametersWithRandom param = new ParametersWithRandom(prv, Message.GetPRNG());

                    signer.Init(true, param);
                    signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                    return(signer.VerifySignature(rgbSignature));
                }

                default:
                    throw new CoseException("Unknown Algorithm");
                }
            }
            else if (alg.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.RSA_PSS_256:
                case AlgorithmValuesInt.RSA_PSS_512: {
                    PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetByteLength());

                    RsaKeyParameters     prv   = new RsaPrivateCrtKeyParameters(keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_n), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_e), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_d), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_p), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_q), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dP), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dQ), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_qInv));
                    ParametersWithRandom param = new ParametersWithRandom(prv, Message.GetPRNG());

                    signer.Init(true, param);
                    signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                    return(signer.VerifySignature(rgbSignature));
                }

                case AlgorithmValuesInt.ECDSA_256:
                case AlgorithmValuesInt.ECDSA_384:
                case AlgorithmValuesInt.ECDSA_512: {
                    digest.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                    byte[] digestedMessage = new byte[digest.GetDigestSize()];
                    digest.DoFinal(digestedMessage, 0);

                    X9ECParameters        p          = keyToSign.GetCurve();
                    ECDomainParameters    parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H);
                    ECPoint               point      = keyToSign.GetPoint();
                    ECPublicKeyParameters param      = new ECPublicKeyParameters(point, parameters);

                    ECDsaSigner ecdsa = new ECDsaSigner();
                    ecdsa.Init(false, param);

                    BigInteger r = new BigInteger(1, rgbSignature, 0, rgbSignature.Length / 2);
                    BigInteger s = new BigInteger(1, rgbSignature, rgbSignature.Length / 2, rgbSignature.Length / 2);
                    return(ecdsa.VerifySignature(digestedMessage, r, s));
                }

                default:
                    throw new CoseException("Unknown Algorithm");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }
        }
示例#14
0
        public bool Validate(Key recipientReceiver)
        {
            byte[] rgbKey = null;
            int    cbitKey;

            if (recipientReceiver[CoseKeyKeys.KeyType].AsInt32() != (int)GeneralValuesInt.KeyType_Octet)
            {
                throw new CoseException("Key type not octet");
            }
            rgbKey = recipientReceiver[CoseKeyParameterKeys.Octet_k].GetByteString();

            CBORObject alg = FindAttribute(COSE.HeaderKeys.Algorithm);

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "AES-CMAC-128/64":
                    cbitKey = 128;
                    break;

                case "AES-CMAC-256/64":
                    cbitKey = 256;
                    break;

                default:
                    throw new Exception("MAC algorithm is not recognized");
                }
            }
            else if (alg.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256_64:
                case AlgorithmValuesInt.HMAC_SHA_256:
                    cbitKey = 256;
                    break;

                case AlgorithmValuesInt.HMAC_SHA_384: cbitKey = 384; break;

                case AlgorithmValuesInt.HMAC_SHA_512: cbitKey = 512; break;

                case AlgorithmValuesInt.AES_CBC_MAC_128_64:
                case AlgorithmValuesInt.AES_CBC_MAC_128_128:
                    cbitKey = 128;
                    break;

                case AlgorithmValuesInt.AES_CBC_MAC_256_64:
                case AlgorithmValuesInt.AES_CBC_MAC_256_128:
                    cbitKey = 256;
                    break;

                default:
                    throw new Exception("MAC algorithm not recognized" + alg.AsInt32());
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            if (rgbKey == null)
            {
                throw new CoseException("No Key Provided");
            }

            byte[] rgbCheck;

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "AES-CMAC-128/64":
                case "AES-CMAC-256/64":
                    rgbCheck = AES_CMAC(alg, rgbKey);
                    break;

                default:
                    throw new Exception("MAC algorithm is not recognized");
                }
            }
            else if (alg.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256:
                case AlgorithmValuesInt.HMAC_SHA_384:
                case AlgorithmValuesInt.HMAC_SHA_512:
                case AlgorithmValuesInt.HMAC_SHA_256_64:
                    rgbCheck = HMAC(alg, rgbKey);
                    break;

                case AlgorithmValuesInt.AES_CBC_MAC_128_64:
                case AlgorithmValuesInt.AES_CBC_MAC_128_128:
                case AlgorithmValuesInt.AES_CBC_MAC_256_64:
                case AlgorithmValuesInt.AES_CBC_MAC_256_128:
                    rgbCheck = AES_CBC_MAC(alg, rgbKey);
                    break;

                default:
                    throw new Exception("MAC algorithm not recognized" + alg.AsInt32());
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            bool fReturn = true;

            for (int i = 0; i < rgbCheck.Length; i++)
            {
                fReturn &= (rgbTag[i] == rgbCheck[i]);
            }
            return(fReturn);
        }
示例#15
0
        /// <summary>
        /// Compute and derive the keys based on the input data
        /// </summary>
        /// <param name="keys">Public and Private DH keys to use for creating shared secret</param>
        /// <param name="salt">A shared symmetric key if one exists</param>
        /// <param name="otherData">SuppPubInfo other data bytes - changes for each message</param>
        /// <param name="algAEAD">Symmetric algorithm for encryption</param>
        /// <returns>array of two byte arrays.  The first is the key, the second is the IV</returns>
        protected static byte[][] _DeriveKeys(OneKey[] keys, byte[] salt, byte[] otherData, CBORObject algAEAD)
        {
            int cbitKey = 0;
            int cbitIV  = 0;

            byte[] secret = ECDH_GenerateSecret(keys);

            if (algAEAD.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)algAEAD.AsInt32())
                {
                case AlgorithmValuesInt.AES_CCM_64_64_128:
                    cbitKey = 128;
                    cbitIV  = 58;
                    break;

                default:
                    throw new Exception("Unknown Algorithm");
                }
            }
            else if (algAEAD.Type == CBORType.TextString)
            {
                switch (algAEAD.AsString())
                {
                case "EDHOC OSCOAP Master Secret":
                    cbitKey = 128;
                    break;

                case "EDHOC OSCOAP Master Salt":
                    cbitKey = 64;
                    break;

                default:
                    throw new Exception("Unknown Algorithm");
                }
            }
            else
            {
                throw new Exception("Internal Error");
            }

            CBORObject partyInfo;

            partyInfo = CBORObject.NewArray();
            partyInfo.Add(CBORObject.Null);
            partyInfo.Add(CBORObject.Null);
            partyInfo.Add(CBORObject.Null);

            CBORObject context = CBORObject.NewArray();

            context.Add(algAEAD);       // Alg
            context.Add(partyInfo);     // Party U
            context.Add(partyInfo);     // Party V

            CBORObject obj = CBORObject.NewArray();

            obj.Add(cbitKey / 8);
            obj.Add(CBORObject.FromObject(new byte[0]));
            obj.Add(otherData);
            context.Add(obj);           // SuppPubInfo

            byte[] rgbContext = context.EncodeToBytes();

            byte[][] returnValue = new byte[2][];

            returnValue[0] = HKDF(secret, salt, rgbContext, cbitKey, new Sha256Digest());

            if (cbitIV > 0)
            {
                obj[0]         = CBORObject.FromObject(cbitIV / 8);
                context[0]     = CBORObject.FromObject("IV-GENERATION");
                returnValue[1] = HKDF(secret, salt, rgbContext, cbitIV, new Sha256Digest());
            }
            return(returnValue);
        }
示例#16
0
        private byte[] Sign(byte[] bytesToBeSigned)
        {
            CBORObject alg = null; // Get the set algorithm or infer one

            alg = FindAttribute(HeaderKeys.Algorithm);

            if (alg == null)
            {
                if (keyToSign[CoseKeyKeys.KeyType].Type == CBORType.Number)
                {
                    switch ((GeneralValuesInt)keyToSign[CoseKeyKeys.KeyType].AsInt32())
                    {
                    case GeneralValuesInt.KeyType_RSA:
                        alg = CBORObject.FromObject("PS256");
                        break;

                    case GeneralValuesInt.KeyType_EC2:
                        if (keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.Number)
                        {
                            switch ((GeneralValuesInt)keyToSign[CoseKeyParameterKeys.EC_Curve].AsInt32())
                            {
                            case GeneralValuesInt.P256:
                                alg = AlgorithmValues.ECDSA_256;
                                break;

                            case GeneralValuesInt.P384:
                                alg = AlgorithmValues.ECDSA_384;
                                break;

                            case GeneralValuesInt.P521:
                                alg = AlgorithmValues.ECDSA_512;
                                break;

                            default:
                                throw new CoseException("Unknown curve");
                            }
                        }
                        else if (keyToSign[CoseKeyParameterKeys.EC_Curve].Type == CBORType.TextString)
                        {
                            switch (keyToSign[CoseKeyParameterKeys.EC_Curve].AsString())
                            {
                            default:
                                throw new CoseException("Unknown curve");
                            }
                        }
                        else
                        {
                            throw new CoseException("Curve is incorrectly encoded");
                        }
                        break;

                    default:
                        throw new Exception("Unknown or unsupported key type " + keyToSign.AsString("kty"));
                    }
                }
                else if (keyToSign[CoseKeyKeys.KeyType].Type == CBORType.TextString)
                {
                    throw new CoseException("Unknown or unsupported key type " + keyToSign[CoseKeyKeys.KeyType].AsString());
                }
                else
                {
                    throw new CoseException("Key type is not correctly encoded");
                }
                objUnprotected.Add(HeaderKeys.Algorithm, alg);
            }

            IDigest digest;
            IDigest digest2;

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "PS384":
                    digest  = new Sha384Digest();
                    digest2 = new Sha384Digest();
                    break;

                default:
                    throw new Exception("Unknown signature algorithm");
                }
            }
            else if (alg.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.ECDSA_256:
                case AlgorithmValuesInt.RSA_PSS_256:
                    digest  = new Sha256Digest();
                    digest2 = new Sha256Digest();
                    break;

                case AlgorithmValuesInt.ECDSA_384:
                case AlgorithmValuesInt.RSA_PSS_384:
                    digest  = new Sha384Digest();
                    digest2 = new Sha384Digest();
                    break;

                case AlgorithmValuesInt.ECDSA_512:
                case AlgorithmValuesInt.RSA_PSS_512:
                    digest  = new Sha512Digest();
                    digest2 = new Sha512Digest();
                    break;

                default:
                    throw new CoseException("Unknown signature algorith");
                }
            }
            else
            {
                throw new CoseException("Algorthm incorrectly encoded");
            }

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "PS384":
                {
                    PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetByteLength());

                    RsaKeyParameters     prv   = new RsaPrivateCrtKeyParameters(keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_n), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_e), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_d), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_p), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_q), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dP), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dQ), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_qInv));
                    ParametersWithRandom param = new ParametersWithRandom(prv, Message.GetPRNG());

                    signer.Init(true, param);
                    signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                    return(signer.GenerateSignature());
                }

                default:
                    throw new CoseException("Unknown Algorithm");
                }
            }
            else if (alg.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.RSA_PSS_256:
                case AlgorithmValuesInt.RSA_PSS_512:
                {
                    PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetByteLength());

                    RsaKeyParameters     prv   = new RsaPrivateCrtKeyParameters(keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_n), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_e), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_d), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_p), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_q), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dP), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_dQ), keyToSign.AsBigInteger(CoseKeyParameterKeys.RSA_qInv));
                    ParametersWithRandom param = new ParametersWithRandom(prv, Message.GetPRNG());

                    signer.Init(true, param);
                    signer.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                    return(signer.GenerateSignature());
                }

                case AlgorithmValuesInt.ECDSA_256:
                case AlgorithmValuesInt.ECDSA_384:
                case AlgorithmValuesInt.ECDSA_512:
                {
                    SecureRandom random = Message.GetPRNG();

                    digest.BlockUpdate(bytesToBeSigned, 0, bytesToBeSigned.Length);
                    byte[] digestedMessage = new byte[digest.GetDigestSize()];
                    digest.DoFinal(digestedMessage, 0);

                    X9ECParameters         p          = keyToSign.GetCurve();
                    ECDomainParameters     parameters = new ECDomainParameters(p.Curve, p.G, p.N, p.H);
                    ECPrivateKeyParameters privKey    = new ECPrivateKeyParameters("ECDSA", ConvertBigNum(keyToSign[CoseKeyParameterKeys.EC_D]), parameters);
                    ParametersWithRandom   param      = new ParametersWithRandom(privKey, random);

                    ECDsaSigner ecdsa = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
                    ecdsa.Init(true, param);

                    BigInteger[] sig = ecdsa.GenerateSignature(digestedMessage);
                    byte[]       r   = sig[0].ToByteArrayUnsigned();
                    byte[]       s   = sig[1].ToByteArrayUnsigned();

                    int cbR = (p.Curve.FieldSize + 7) / 8;

                    byte[] sigs = new byte[cbR * 2];
                    Array.Copy(r, 0, sigs, cbR - r.Length, r.Length);
                    Array.Copy(s, 0, sigs, cbR + cbR - s.Length, s.Length);

                    return(sigs);
                }

                default:
                    throw new CoseException("Unknown Algorithm");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }
        }
示例#17
0
        public static byte[] Sign(byte[] toBeSigned, CBORObject alg, OneKey keyToSign)
        {
            IDigest digest  = null;
            IDigest digest2 = null;

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "PS384":
                    digest  = new Sha384Digest();
                    digest2 = new Sha384Digest();
                    break;

                case "HSS-LMS":
                    break;

                default:
                    throw new Exception("Unknown signature algorithm");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.ECDSA_256:
                case AlgorithmValuesInt.RSA_PSS_256:
                    digest  = new Sha256Digest();
                    digest2 = new Sha256Digest();
                    break;

                case AlgorithmValuesInt.ECDSA_384:
                case AlgorithmValuesInt.RSA_PSS_384:
                    digest  = new Sha384Digest();
                    digest2 = new Sha384Digest();
                    break;

                case AlgorithmValuesInt.ECDSA_512:
                case AlgorithmValuesInt.RSA_PSS_512:
                    digest  = new Sha512Digest();
                    digest2 = new Sha512Digest();
                    break;

                case AlgorithmValuesInt.EdDSA:
                    break;

                default:
                    throw new CoseException("Unknown signature algorithm");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "HSS-LMS":
                    HashSig sig       = new HashSig(keyToSign[CoseKeyParameterKeys.Lms_Private].AsString());
                    byte[]  signBytes = sig.Sign(toBeSigned);
                    keyToSign.Replace(CoseKeyParameterKeys.Lms_Private, CBORObject.FromObject(sig.PrivateKey));
                    return(signBytes);

                default:
                    throw new CoseException("Unknown Algorithm");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.RSA_PSS_256:
                case AlgorithmValuesInt.RSA_PSS_384:
                case AlgorithmValuesInt.RSA_PSS_512: {
                    PssSigner signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetDigestSize());

                    ICipherParameters    prv   = keyToSign.AsPrivateKey();
                    ParametersWithRandom param = new ParametersWithRandom(prv, Message.GetPRNG());

                    signer.Init(true, param);
                    signer.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                    return(signer.GenerateSignature());
                }

                case AlgorithmValuesInt.ECDSA_256:
                case AlgorithmValuesInt.ECDSA_384:
                case AlgorithmValuesInt.ECDSA_512: {
                    SecureRandom random = Message.GetPRNG();

                    digest.BlockUpdate(toBeSigned, 0, toBeSigned.Length);
                    byte[] digestedMessage = new byte[digest.GetDigestSize()];
                    digest.DoFinal(digestedMessage, 0);

                    ICipherParameters privKey = keyToSign.AsPrivateKey();
                    X9ECParameters    p       = keyToSign.GetCurve();

                    ParametersWithRandom param = new ParametersWithRandom(privKey, random);

                    ECDsaSigner ecdsa = new ECDsaSigner(new HMacDsaKCalculator(new Sha256Digest()));
                    ecdsa.Init(true, param);

                    BigInteger[] sig = ecdsa.GenerateSignature(digestedMessage);
                    byte[]       r   = sig[0].ToByteArrayUnsigned();
                    byte[]       s   = sig[1].ToByteArrayUnsigned();

                    int cbR = (p.Curve.FieldSize + 7) / 8;

                    byte[] sigs = new byte[cbR * 2];
                    Array.Copy(r, 0, sigs, cbR - r.Length, r.Length);
                    Array.Copy(s, 0, sigs, cbR + cbR - s.Length, s.Length);

                    return(sigs);
                }

                case AlgorithmValuesInt.EdDSA: {
                    ISigner eddsa;
                    if (keyToSign[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed25519))
                    {
                        ICipherParameters privKey = keyToSign.AsPrivateKey();
                        eddsa = new Ed25519Signer();
                        eddsa.Init(true, privKey);
                    }
                    else if (keyToSign[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed448))
                    {
                        ICipherParameters privKey = keyToSign.AsPrivateKey();
                        eddsa = new Ed448Signer(new byte[0]);
                        eddsa.Init(true, privKey);
                    }
                    else
                    {
                        throw new CoseException("Unrecognized curve");
                    }


                    eddsa.BlockUpdate(toBeSigned, 0, toBeSigned.Length);

                    return(eddsa.GenerateSignature());
                }

                default:
                    throw new CoseException("Unknown Algorithm");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }
        }
示例#18
0
        public static bool Validate(byte[] content, CBORObject alg, OneKey signKey, byte[] rgbSignature)
        {
            IDigest digest  = null;
            IDigest digest2 = null;

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "HSS-LMS":
                    break;

                default:
                    throw new Exception("Unknown signature algorithm");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.ECDSA_256:
                case AlgorithmValuesInt.RSA_PSS_256:
                    digest  = new Sha256Digest();
                    digest2 = new Sha256Digest();
                    break;

                case AlgorithmValuesInt.ECDSA_384:
                case AlgorithmValuesInt.RSA_PSS_384:
                    digest  = new Sha384Digest();
                    digest2 = new Sha384Digest();
                    break;

                case AlgorithmValuesInt.ECDSA_512:
                case AlgorithmValuesInt.RSA_PSS_512:
                    digest  = new Sha512Digest();
                    digest2 = new Sha512Digest();
                    break;

                case AlgorithmValuesInt.EdDSA:
                    break;

                default:
                    throw new CoseException("Unknown signature algorith");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "HSS-LMS":
                    return(HashSig.Validate(content,
                                            signKey[CoseKeyParameterKeys.Lms_Public].GetByteString(),
                                            rgbSignature));

                default:
                    throw new CoseException("Unknown Algorithm");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.RSA_PSS_256:
                case AlgorithmValuesInt.RSA_PSS_384:
                case AlgorithmValuesInt.RSA_PSS_512: {
                    PssSigner         signer = new PssSigner(new RsaEngine(), digest, digest2, digest.GetDigestSize());
                    ICipherParameters prv    = signKey.AsPublicKey();

                    ParametersWithRandom param = new ParametersWithRandom(prv, Message.GetPRNG());

                    signer.Init(false, param);
                    signer.BlockUpdate(content, 0, content.Length);
                    return(signer.VerifySignature(rgbSignature));
                }

                case AlgorithmValuesInt.ECDSA_256:
                case AlgorithmValuesInt.ECDSA_384:
                case AlgorithmValuesInt.ECDSA_512: {
                    if (signKey.GetKeyType() != GeneralValuesInt.KeyType_EC2)
                    {
                        throw new CoseException("Key is not correctly constructed.");
                    }

                    digest.BlockUpdate(content, 0, content.Length);
                    byte[] digestedMessage = new byte[digest.GetDigestSize()];
                    digest.DoFinal(digestedMessage, 0);

                    ICipherParameters param = signKey.AsPublicKey();

                    ECDsaSigner ecdsa = new ECDsaSigner();
                    ecdsa.Init(false, param);

                    BigInteger r = new BigInteger(1, rgbSignature, 0, rgbSignature.Length / 2);
                    BigInteger s = new BigInteger(1, rgbSignature, rgbSignature.Length / 2, rgbSignature.Length / 2);
                    return(ecdsa.VerifySignature(digestedMessage, r, s));
                }

#if true
                case AlgorithmValuesInt.EdDSA: {
                    ISigner eddsa;
                    if (signKey[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed25519))
                    {
                        ICipherParameters privKey = signKey.AsPublicKey();
                        eddsa = new Ed25519Signer();
                        eddsa.Init(false, privKey);
                    }
                    else if (signKey[CoseKeyParameterKeys.EC_Curve].Equals(GeneralValues.Ed448))
                    {
                        Ed448PublicKeyParameters privKey =
                            new Ed448PublicKeyParameters(signKey[CoseKeyParameterKeys.OKP_X].GetByteString(), 0);
                        eddsa = new Ed448Signer(new byte[0]);
                        eddsa.Init(false, privKey);
                    }
                    else
                    {
                        throw new CoseException("Unrecognized curve");
                    }

                    eddsa.BlockUpdate(content, 0, content.Length);
                    return(eddsa.VerifySignature(rgbSignature));
                }
#endif

                default:
                    throw new CoseException("Unknown Algorithm");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }
        }
示例#19
0
        public void ReverseNegativeKey()
        {
            CBORObject result = (CBORObject)_dictionary.Reverse(CBORObject.FromObject(-5), true);

            Assert.AreEqual(-5, result.AsInt32());
        }
示例#20
0
        public bool Validate(byte[] rgbKey)
        {
            int cbitKey;

            CBORObject alg = FindAttribute(HeaderKeys.Algorithm);

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "AES-CMAC-128/64":
                    cbitKey = 128;
                    break;

                case "AES-CMAC-256/64":
                    cbitKey = 256;
                    break;

                default:
                    throw new CoseException("Unknown Algorithm Specified");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256_64:
                case AlgorithmValuesInt.HMAC_SHA_256:
                    cbitKey = 256;
                    break;

                case AlgorithmValuesInt.HMAC_SHA_384: cbitKey = 384; break;

                case AlgorithmValuesInt.HMAC_SHA_512: cbitKey = 512; break;

                case AlgorithmValuesInt.AES_CBC_MAC_128_64:
                case AlgorithmValuesInt.AES_CBC_MAC_128_128:
                    cbitKey = 128;
                    break;

                case AlgorithmValuesInt.AES_CBC_MAC_256_64:
                case AlgorithmValuesInt.AES_CBC_MAC_256_128:
                    cbitKey = 256;
                    break;

                default:
                    throw new CoseException("MAC algorithm not recognized " + alg.AsInt32());
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            if (rgbKey == null)
            {
                throw new CoseException("No Key Provided");
            }
            if (cbitKey / 8 != rgbKey.Length)
            {
                throw new CoseException("Incorrect key length for operation");
            }

            byte[] rgbCheck;

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                case "AES-CMAC-128/64":
                case "AES-CMAC-256/64":
                    rgbCheck = AES_CMAC(alg, rgbKey);
                    break;

                default:
                    throw new CoseException("Unknown Algorithm Specified");
                }
            }
            else if (alg.Type == CBORType.Integer)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256:
                case AlgorithmValuesInt.HMAC_SHA_384:
                case AlgorithmValuesInt.HMAC_SHA_512:
                case AlgorithmValuesInt.HMAC_SHA_256_64:
                    rgbCheck = HMAC(alg, rgbKey);
                    break;

                case AlgorithmValuesInt.AES_CBC_MAC_128_64:
                case AlgorithmValuesInt.AES_CBC_MAC_128_128:
                case AlgorithmValuesInt.AES_CBC_MAC_256_64:
                case AlgorithmValuesInt.AES_CBC_MAC_256_128:
                    rgbCheck = AES_CBC_MAC(alg, rgbKey);
                    break;

                default:
                    throw new CoseException("MAC algorithm not recognized " + alg.AsInt32());
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            bool fReturn = true;

            for (int i = 0; i < rgbCheck.Length; i++)
            {
                fReturn &= (RgbTag[i] == rgbCheck[i]);
            }
            return(fReturn);
        }
示例#21
0
        private byte[] AES(CBORObject alg, byte[] K)
        {
            GcmBlockCipher cipher = new GcmBlockCipher(new AesEngine(), new BasicGcmMultiplier());
            KeyParameter   ContentKey;

            byte[]     IV;
            CBORObject cbor;

            //  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];
            cbor = FindAttribute(HeaderKeys.IV);
            if (cbor != null)
            {
                if (cbor.Type != CBORType.ByteString)
                {
                    throw new CoseException("IV is incorrectly formed.");
                }
                if (cbor.GetByteString().Length != IV.Length)
                {
                    throw new CoseException("IV size is incorrect.");
                }
                Array.Copy(cbor.GetByteString(), IV, IV.Length);
            }
            else
            {
                s_PRNG.NextBytes(IV);
                AddAttribute(HeaderKeys.IV, CBORObject.FromObject(IV), UNPROTECTED);
            }

            if (K == null)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.AES_GCM_128:
                    K = new byte[128 / 8];
                    break;

                case AlgorithmValuesInt.AES_GCM_192:
                    K = new byte[192 / 8];
                    break;

                case AlgorithmValuesInt.AES_GCM_256:
                    K = new byte[256 / 8];
                    break;

                default:
                    throw new CoseException("Unsupported algorithm: " + alg);
                }
                s_PRNG.NextBytes(K);
            }

            ContentKey = new KeyParameter(K);

            //  Build the object to be hashed

            AeadParameters parameters = new AeadParameters(ContentKey, 128, IV, getAADBytes());

            cipher.Init(true, parameters);

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

            len += cipher.DoFinal(C, len);

            RgbEncrypted = C;

            return(K);
        }
示例#22
0
 public static void TestNumber(CBORObject o)
 {
     if (o.Type != CBORType.Number) {
     return;
       }
       if (o.IsPositiveInfinity() || o.IsNegativeInfinity() ||
       o.IsNaN()) {
     try {
       o.AsByte();
       Assert.Fail("Should have failed");
     } catch (OverflowException) {
       new Object();
     } catch (Exception ex) {
       Assert.Fail("Object: " + o + ", " + ex); throw new
     InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsInt16();
       Assert.Fail("Should have failed");
     } catch (OverflowException) {
       new Object();
     } catch (Exception ex) {
       Assert.Fail("Object: " + o + ", " + ex); throw new
     InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsInt32();
       Assert.Fail("Should have failed");
     } catch (OverflowException) {
       new Object();
     } catch (Exception ex) {
       Assert.Fail("Object: " + o + ", " + ex); throw new
     InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsInt64();
       Assert.Fail("Should have failed");
     } catch (OverflowException) {
       new Object();
     } catch (Exception ex) {
       Assert.Fail("Object: " + o + ", " + ex); throw new
     InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsSingle();
     } catch (Exception ex) {
       Assert.Fail(ex.ToString());
       throw new InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsDouble();
     } catch (Exception ex) {
       Assert.Fail(ex.ToString());
       throw new InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsEInteger();
       Assert.Fail("Should have failed");
     } catch (OverflowException) {
       new Object();
     } catch (Exception ex) {
       Assert.Fail("Object: " + o + ", " + ex); throw new
     InvalidOperationException(String.Empty, ex);
     }
     return;
       }
       try {
     o.AsSingle();
       } catch (Exception ex) {
     Assert.Fail("Object: " + o + ", " + ex); throw new
       InvalidOperationException(String.Empty, ex);
       }
       try {
     o.AsDouble();
       } catch (Exception ex) {
     Assert.Fail("Object: " + o + ", " + ex); throw new
       InvalidOperationException(String.Empty, ex);
       }
 }
示例#23
0
        protected byte[] HMAC(CBORObject alg, byte[] K)
        {
            int     cbitKey;
            int     cbResult;
            IDigest digest;

            if (alg.Type == CBORType.TextString)
            {
                switch (alg.AsString())
                {
                default:
                    throw new Exception("Unrecognized algorithm");
                }
            }
            else if (alg.Type == CBORType.Number)
            {
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.HMAC_SHA_256:
                    cbitKey  = 256;
                    cbResult = 256 / 8;
                    digest   = new Sha256Digest();
                    break;

                case AlgorithmValuesInt.HMAC_SHA_256_64:
                    cbitKey  = 256;
                    digest   = new Sha256Digest();
                    cbResult = 64 / 8;
                    break;

                case AlgorithmValuesInt.HMAC_SHA_384:
                    cbitKey  = 384;
                    digest   = new Sha384Digest();
                    cbResult = cbitKey / 8;
                    break;

                case AlgorithmValuesInt.HMAC_SHA_512:
                    cbitKey  = 512;
                    digest   = new Sha512Digest();
                    cbResult = cbitKey / 8;
                    break;

                default:
                    throw new CoseException("Unknown or unsupported algorithm");
                }
            }
            else
            {
                throw new CoseException("Algorithm incorrectly encoded");
            }

            if (K == null)
            {
                throw new CoseException("No Key value");
            }

            HMac         hmac = new HMac(digest);
            KeyParameter key  = new KeyParameter(K);

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

            byte[] toDigest = BuildContentBytes();

            hmac.Init(key);
            hmac.BlockUpdate(toDigest, 0, toDigest.Length);
            hmac.DoFinal(resBuf, 0);

            byte[] rgbOut = new byte[cbResult];
            Array.Copy(resBuf, rgbOut, cbResult);

            return(rgbOut);
        }
示例#24
0
        private void AES_CCM_Decrypt(CBORObject alg, byte[] K)
        {
            CcmBlockCipher cipher = new CcmBlockCipher(new AesEngine());
            KeyParameter   ContentKey;
            int            cbitTag;
            int            cbIV;
            int            cbitKey;

            //  Figure out what the correct internal parameters to use are

            Debug.Assert(alg.Type == CBORType.Integer);
            switch ((AlgorithmValuesInt)alg.AsInt32())
            {
            case AlgorithmValuesInt.AES_CCM_16_64_128:
            case AlgorithmValuesInt.AES_CCM_64_64_128:
                cbitKey = 128;
                cbitTag = 64;
                break;

            case AlgorithmValuesInt.AES_CCM_16_128_128:
            case AlgorithmValuesInt.AES_CCM_64_128_128:
                cbitKey = 128;
                cbitTag = 128;
                break;

            case AlgorithmValuesInt.AES_CCM_16_64_256:
            case AlgorithmValuesInt.AES_CCM_64_64_256:
                cbitKey = 256;
                cbitTag = 64;
                break;

            case AlgorithmValuesInt.AES_CCM_16_128_256:
            case AlgorithmValuesInt.AES_CCM_64_128_256:
                cbitKey = 256;
                cbitTag = 128;
                break;

            default:
                throw new CoseException("Unsupported algorithm: " + alg);
            }

            switch ((AlgorithmValuesInt)alg.AsInt32())
            {
            case AlgorithmValuesInt.AES_CCM_16_64_128:
            case AlgorithmValuesInt.AES_CCM_16_64_256:
            case AlgorithmValuesInt.AES_CCM_16_128_128:
            case AlgorithmValuesInt.AES_CCM_16_128_256:
                cbIV = 15 - 2;
                break;

            case AlgorithmValuesInt.AES_CCM_64_64_128:
            case AlgorithmValuesInt.AES_CCM_64_64_256:
            case AlgorithmValuesInt.AES_CCM_64_128_256:
            case AlgorithmValuesInt.AES_CCM_64_128_128:
                cbIV = 15 - 8;
                break;

            default:
                throw new CoseException("Unsupported algorithm: " + alg);
            }

            //  The requirements from JWA

            byte[]     IV   = new byte[cbIV];
            CBORObject cbor = FindAttribute(HeaderKeys.IV);

            if (cbor != null)
            {
                if (cbor.Type != CBORType.ByteString)
                {
                    throw new CoseException("IV is incorrectly formed.");
                }
                if (cbor.GetByteString().Length > IV.Length)
                {
                    throw new CoseException("IV is too long.");
                }
                Array.Copy(cbor.GetByteString(), 0, IV, 0, IV.Length);
            }
            else
            {
                s_PRNG.NextBytes(IV);
                AddAttribute(HeaderKeys.IV, CBORObject.FromObject(IV), UNPROTECTED);
            }

            if (K == null)
            {
                throw new CoseException("Internal error");
            }
            if (K.Length != cbitKey / 8)
            {
                throw new CoseException("Incorrect key length");
            }

            ContentKey = new KeyParameter(K);

            //  Build the object to be hashed

            AeadParameters parameters = new AeadParameters(ContentKey, cbitTag, IV, getAADBytes());

            cipher.Init(false, parameters);
            byte[] C   = new byte[cipher.GetOutputSize(RgbEncrypted.Length)];
            int    len = cipher.ProcessBytes(RgbEncrypted, 0, RgbEncrypted.Length, C, 0);

            len += cipher.DoFinal(C, len);

            rgbContent = C;
        }
示例#25
0
        private byte[] ChaCha20_Poly1305(CBORObject alg, byte[] K)
        {
            ChaCha20Poly1305 cipher = new ChaCha20Poly1305();

            KeyParameter ContentKey;
            int          cbitTag = 128;

            //  The requirements from JWA
            //  IV is 96 bits
            //  Authentication tag is 128 bits
            //  key size is 256 bits

            byte[]     IV   = new byte[96 / 8];
            CBORObject cbor = FindAttribute(HeaderKeys.IV);

            if (cbor != null)
            {
                if (cbor.Type != CBORType.ByteString)
                {
                    throw new CoseException("IV is incorrectly formed.");
                }
                if (cbor.GetByteString().Length > IV.Length)
                {
                    throw new CoseException("IV is too long.");
                }
                Array.Copy(cbor.GetByteString(), 0, IV, IV.Length - cbor.GetByteString().Length, cbor.GetByteString().Length);
            }
            else
            {
                s_PRNG.NextBytes(IV);
                AddAttribute(HeaderKeys.IV, CBORObject.FromObject(IV), UNPROTECTED);
            }

            if (K == null)
            {
                Debug.Assert(alg.Type == CBORType.Number);
                switch ((AlgorithmValuesInt)alg.AsInt32())
                {
                case AlgorithmValuesInt.ChaCha20_Poly1305:
                    K       = new byte[256 / 8];
                    cbitTag = 128;
                    break;

                default:
                    throw new CoseException("Unsupported algorithm: " + alg);
                }
                s_PRNG.NextBytes(K);
            }

            //  Generate key

            ContentKey = new KeyParameter(K);

            //  Build the object to be hashed

            byte[]         aad        = getAADBytes();
            AeadParameters parameters = new AeadParameters(ContentKey, cbitTag, IV, aad);

            cipher.Init(true, parameters);

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

            len += cipher.DoFinal(C, len);

            RgbEncrypted = C;

            return(K);
        }
示例#26
0
#pragma warning disable CS0618
        public static void TestNumber(CBORObject o)
        {
            if (o.Type != CBORType.Number)
            {
                return;
            }
            if (o.IsPositiveInfinity() || o.IsNegativeInfinity() ||
                o.IsNaN())
            {
                try {
                    o.AsByte();
                    Assert.Fail("Should have failed");
                } catch (OverflowException) {
                    // NOTE: Intentionally empty
                } catch (Exception ex) {
                    Assert.Fail("Object: " + o + ", " + ex);
                    throw new InvalidOperationException(String.Empty, ex);
                }
                try {
                    o.AsInt16();
                    Assert.Fail("Should have failed");
                } catch (OverflowException) {
                    // NOTE: Intentionally empty
                } catch (Exception ex) {
                    Assert.Fail("Object: " + o + ", " + ex);
                    throw new InvalidOperationException(String.Empty, ex);
                }
                try {
                    o.AsInt32();
                    Assert.Fail("Should have failed");
                } catch (OverflowException) {
                    // NOTE: Intentionally empty
                } catch (Exception ex) {
                    Assert.Fail("Object: " + o + ", " + ex);
                    throw new InvalidOperationException(String.Empty, ex);
                }
                try {
                    o.AsInt64();
                    Assert.Fail("Should have failed");
                } catch (OverflowException) {
                    // NOTE: Intentionally empty
                } catch (Exception ex) {
                    Assert.Fail("Object: " + o + ", " + ex);
                    throw new InvalidOperationException(String.Empty, ex);
                }
                try {
                    o.AsSingle();
                } catch (Exception ex) {
                    Assert.Fail(ex.ToString());
                    throw new InvalidOperationException(String.Empty, ex);
                }
                try {
                    o.AsDouble();
                } catch (Exception ex) {
                    Assert.Fail(ex.ToString());
                    throw new InvalidOperationException(String.Empty, ex);
                }
                try {
                    o.AsEInteger();
                    Assert.Fail("Should have failed");
                } catch (OverflowException) {
                    // NOTE: Intentionally empty
                } catch (Exception ex) {
                    Assert.Fail("Object: " + o + ", " + ex);
                    throw new InvalidOperationException(String.Empty, ex);
                }
                return;
            }
            try {
                o.AsSingle();
            } catch (Exception ex) {
                Assert.Fail("Object: " + o + ", " + ex);
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                o.AsDouble();
            } catch (Exception ex) {
                Assert.Fail("Object: " + o + ", " + ex);
                throw new InvalidOperationException(String.Empty, ex);
            }
        }
示例#27
0
        private string _PrintCBOR(CBORObject obj, int iLevel)
        {
            string strOut = "";
            string strLine;
            string pad = ((String)"                    ").Substring(0, iLevel);

            switch (obj.Type)
            {
            case CBORType.Array:
                strOut = "[\n";
                for (int i = 0; i < obj.Count; i++)
                {
                    strOut += pad + " " + _PrintCBOR(obj[i], iLevel + 1) + ",\n";
                }
                strOut += pad + "]";
                break;

            case CBORType.Map:
                strOut = "{\n";
                foreach (CBORObject key in obj.Keys)
                {
                    strOut += pad + " " + _PrintCBOR(key, 0) + " : " + _PrintCBOR(obj[key], iLevel + 1) + ",\n";
                }
                strOut += pad + "}";
                break;

            case CBORType.ByteString:
                strLine = pad + "h'";
                byte[] rgb  = obj.GetByteString();
                byte[] rgb2 = new byte[1];
                foreach (byte b in rgb)
                {
                    if (strLine.Length > 66)
                    {
                        if (strOut == "")
                        {
                            strOut = strLine.Substring(iLevel) + "\n";
                        }
                        else
                        {
                            strOut += strLine + "\n";
                        }
                        strLine = pad + "  ";
                    }
                    rgb2[0]  = b;
                    strLine += BitConverter.ToString(rgb2);
                }
                strOut += strLine;
                strOut += "'";
                break;

            case CBORType.Integer:
                strOut = obj.AsInt32().ToString();
                break;

            case CBORType.SimpleValue:
                if (obj.IsNull)
                {
                    return("null");
                }
                return(obj.Type.ToString());

            case CBORType.TextString:
                strOut = "\"" + obj.AsString() + "\"";
                break;

            default:
                strOut = obj.Type.ToString();
                break;
            }

            return(strOut);
        }