示例#1
0
        public static void DoTestString(String value)
        {
            String     b   = DataUtilities.GetUtf8Length(value, false) + ":" + value;
            CBORObject beo = EncodingFromBytes(DataUtilities.GetUtf8Bytes(b,
                                                                          false));

            Assert.AreEqual(value, beo.AsString());
            String newb = DataUtilities.GetUtf8String(EncodingToBytes(beo), false);

            Assert.AreEqual(b, newb);
        }
示例#2
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");
            }
        }
示例#3
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)));
        }
        public CBORObject Lookup(CBORObject value, bool isIntLegal)
        {
            if (value.Type == CBORType.TextString)
            {
                return(Lookup(value.AsString(), isIntLegal));
            }

            foreach (KeyValuePair <int, object> o in _dictionary)
            {
                if (value.Equals(o.Value))
                {
                    if (isIntLegal)
                    {
                        return(CBORObject.FromObjectAndTag(o.Key, DictionaryTag));
                    }

                    return(CBORObject.FromObject(o.Key));
                }
            }

            return(value);
        }
        public CoralDictionary Add(int key, CBORObject value)
        {
            if (key < 0)
            {
                throw new ArgumentException("Key must be a non-negative value", nameof(key));
            }

            if (!CoralItem.IsLiteral(value))
            {
                throw new ArgumentException("Value must be a literal value");
            }

            if (value.Type == CBORType.TextString)
            {
                _dictionary.Add(key, value.AsString());
            }
            else
            {
                _dictionary.Add(key, value);
            }

            return(this);
        }
示例#6
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");
            }
        }
示例#7
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);
        }
示例#8
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);
        }
示例#9
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");
            }
        }
示例#10
0
        private static RemoteResource DeserializeCbor(CBORObject cbor)
        {
            if (cbor.Type != CBORType.Array)
            {
                throw new ArgumentException();
            }

            RemoteResource root = new RemoteResource(string.Empty);

            for (int i = 0; i < cbor.Count; i++)
            {
                string href;
                if (cbor[i].ContainsKey("href"))
                {
                    href = cbor[i]["href"].AsString();
                }
                else
                {
                    href = cbor[i][CBORObject.FromObject(1)].AsString();
                }

                RemoteResource child = new RemoteResource(href);

                foreach (CBORObject key in cbor[i].Keys)
                {
                    string keyName;
                    if (key.Type == CBORType.Number)
                    {
                        keyName = null;
                        foreach (KeyValuePair <string, CBORObject> kvp  in _CborAttributeKeys)
                        {
                            if (key.Equals(kvp.Value))
                            {
                                keyName = kvp.Key;
                                break;
                            }
                        }
                        if (keyName == null)
                        {
                            throw new ArgumentException("Invalid numeric key");
                        }
                    }
                    else if (key.Type == CBORType.TextString)
                    {
                        keyName = key.AsString();
                    }
                    else
                    {
                        throw new ArgumentException("Unexpected key type found");
                    }

                    if (keyName == "href")
                    {
                        continue;
                    }

                    CBORObject value = cbor[i][key];

                    if (value.Type == CBORType.TextString)
                    {
                        child.Attributes.Add(keyName, value.AsString());
                    }
                    else if (value.Type == CBORType.Boolean)
                    {
                        child.Attributes.Add(keyName);
                    }
                    else if (value.Type == CBORType.Array)
                    {
                        for (int i1 = 0; i1 < value.Count; i1++)
                        {
                            if (value[i1].Type == CBORType.TextString)
                            {
                                child.Attributes.Add(keyName, value[i1].AsString());
                            }
                            else if (value[i1].Type == CBORType.Boolean)
                            {
                                if (value[i1].AsBoolean() != true)
                                {
                                    throw new ArgumentException("false unexpectedly found");
                                }
                                child.Attributes.Add(keyName);
                            }
                            else
                            {
                                throw new ArgumentException("Unexpected value type found");
                            }
                        }
                    }
                    else
                    {
                        throw new ArgumentException("Unexpected value type found");
                    }
                }

                root.AddSubResource(child);
            }


            return(root);
        }
示例#11
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);
        }
示例#12
0
        static bool ValidateEnveloped(CBORObject control)
        {
            CBORObject input   = control["input"];
            CBORObject encrypt = input["enveloped"];

            if ((!encrypt.ContainsKey("recipients")) || (encrypt["recipients"].Type != CBORType.Array))
            {
                throw new Exception("Missing or malformed recipients");
            }

            for (int iRecipient = 0; iRecipient < encrypt["recipients"].Count; iRecipient++)
            {
                bool           fFail = HasFailMarker(control) || HasFailMarker(encrypt);
                EncryptMessage encryptMessage;

                try {
                    Message    message;
                    CBORObject obj = control["output"]["json"];
                    if (obj.Type == CBORType.TextString)
                    {
                        message = Message.DecodeFromString(obj.AsString());
                    }
                    else
                    {
                        message = Message.DecodeFromJSON(obj);
                    }

                    encryptMessage = (EncryptMessage)message;
                }
                catch (Exception) {
                    if (fFail)
                    {
                        return(true);
                    }
                    return(false);
                }

                if (encrypt.ContainsKey("unsent"))
                {
                    AddAttributes(encryptMessage, encrypt["unsent"], 2);
                }
                CBORObject recipient        = encrypt["recipients"][iRecipient];
                Recipient  recipientMessage = encryptMessage.RecipientList[iRecipient];

                recipientMessage = SetReceivingAttributes(recipientMessage, recipient);

                /*
                 * if (recipient["sender_key"] != null)
                 * {
                 *  if (recipientMessage.FindAttribute(HeaderKeys.StaticKey) == null)
                 *  {
                 *      recipientMessage.AddAttribute(HeaderKeys.StaticKey, GetKey(recipient["sender_key"], true).AsCBOR(),
                 *          Attributes.DO_NOT_SEND);
                 *  }
                 * }
                 */

                bool fFailRecipient = HasFailMarker(recipient);

                try {
                    encryptMessage.Decrypt(recipientMessage);

                    if (encryptMessage.GetContentAsString() != input["plaintext"].AsString())
                    {
                        return(false);
                    }
                }
                catch (Exception) {
                    if (fFail || fFailRecipient)
                    {
                        return(true);
                    }
                    return(false);
                }
            }


            return(true);
        }
示例#13
0
        static bool ProcessJSON(CBORObject control)
        {
            bool       modified = false;
            StaticPrng prng     = new StaticPrng();

            if (control.ContainsKey("title"))
            {
                Console.Write("Processing: " + control["title"].AsString());
            }

            if (control["input"].ContainsKey("rng_stream"))
            {
                if (control["input"]["rng_stream"].Type == CBORType.TextString)
                {
                    prng.AddSeedMaterial(Program.FromHex(control["input"]["rng_stream"].AsString()));
                }
                else if (control["input"]["rng_stream"].Type == CBORType.Array)
                {
                    foreach (var x in control["input"]["rng_stream"].Values)
                    {
                        prng.AddSeedMaterial(Program.FromHex(x.AsString()));
                    }
                }
            }

            Message.SetPRNG(prng);

            try {
                prng.Reset();
                Message result;


                if (control["input"].ContainsKey("enveloped"))
                {
                    result = ProcessEnveloped(control, ref modified);
                }
                else if (control["input"].ContainsKey("sign"))
                {
                    result = ProcessSign(control, ref modified);
                }
                else
                {
                    throw new Exception("Unknown operation in control");
                }

                foreach (string format in Formats)
                {
                    CBORObject json     = null;
                    string     jsonText = null;

                    try {
                        switch (format)
                        {
                        case "json":
                            json = result.EncodeToJSON(false);
                            break;

                        case "json_flat":
                            json = result.EncodeToJSON(true);
                            break;

                        case "compact":
                            jsonText = result.EncodeCompressed();
                            break;
                        }
                    }
                    catch (JoseException) {
                        // Ignore
                    }


                    if (control["output"].ContainsKey(format))
                    {
                        if (json == null && jsonText == null)
                        {
                            control["output"].Remove(format);
                            modified = true;
                        }
                        else
                        {
                            CBORObject oldVersion = control["output"][format];

                            if (format == "compact")
                            {
                                if (oldVersion.Type != CBORType.TextString || jsonText != oldVersion.AsString())
                                {
                                    Console.WriteLine();
                                    Console.WriteLine($"******************* New and Old do not match {format}!!!");
                                    Console.WriteLine();

                                    control["output"][format] = CBORObject.FromObject(jsonText);
                                    modified = true;
                                }
                            }
                            else if (json.ToJSONString() != oldVersion.ToJSONString())
                            {
                                Console.WriteLine();
                                Console.WriteLine($"******************* New and Old do not match {format}!!!");
                                Console.WriteLine();

                                control["output"][format] = json;
                                modified = true;
                            }
                        }
                    }
                    else
                    {
                        if (format == "compact" && jsonText != null)
                        {
                            control["output"].Add(format, jsonText);
                            modified = true;
                        }
                        else if (json != null)
                        {
                            control["output"].Add(format, json);
                            modified = true;
                        }
                    }
                }


                if (prng.IsDirty)
                {
                    if (prng.Buffer != null)
                    {
                        if (control["input"].ContainsKey("rng_stream"))
                        {
                            control["input"]["rng_stream"] = prng.Buffer;
                        }
                        else
                        {
                            control["input"].Add("rng_stream", prng.Buffer);
                        }
                    }
                    else
                    {
                        if (control["input"].ContainsKey("rng_stream"))
                        {
                            control["input"].Remove(CBORObject.FromObject("rng_stream"));
                        }
                    }

                    modified = true;
                }
            }
            catch (Com.AugustCellars.JOSE.JoseException e) {
                Console.WriteLine($"JOSE threw an error '{e}'.");
            }

            return(modified);
        }
示例#14
0
文件: TestFiles.cs 项目: lulzzz/CWT
        void ProcessFile(FileInfo testCase)
        {
            if (testCase.Extension != ".json")
            {
                return;
            }
            if (testCase.Name[0] == '.')
            {
                return;
            }

            Debug.Print($"Working on file {testCase}");
            Console.WriteLine("Working on file '" + testCase + "'");

            string     inputText  = testCase.OpenText().ReadToEnd();
            CBORObject test       = CBORObject.FromJSONString(inputText);
            KeySet     decodeKeys = new KeySet();
            KeySet     signKeys   = new KeySet();

            CBORObject input = test["input"];

            CWT cwt = new CWT();

            if (input.ContainsKey("encrypted"))
            {
                OneKey key = LoadKey(input["encrypted"]["key"]);
                cwt.EncryptionKey = key;
                decodeKeys.AddKey(key);
            }

            if (input.ContainsKey("mac0"))
            {
                OneKey key = LoadKey(input["mac0"]["key"]);
                cwt.MacKey = key;
                decodeKeys.AddKey(key);
            }

            if (input.ContainsKey("sign0"))
            {
                OneKey key = LoadKey(input["sign0"]["key"]);
                cwt.SigningKey = key;
                signKeys.AddKey(key.PublicKey());
            }

            CWT cwt2 = CWT.Decode(FromHex(test["output"]["cbor"].AsString()), decodeKeys, signKeys);



            CBORObject token = input["token"];

            foreach (CBORObject key in token.Keys)
            {
                CBORObject value = token[key];
                CBORObject key2  = key;
                if (key.AsString().EndsWith("_hex"))
                {
                    value = CBORObject.FromObject(FromHex(value.AsString()));
                    key2  = CBORObject.FromObject(key.AsString().Substring(0, key.AsString().Length - 4));
                }

                cwt.SetClaim(key2, value);

                Assert.True(cwt2.HasClaim(key2), $"Missing Claim {key2}");
                Assert.AreEqual(value, cwt.GetClaim(key2));
            }

            byte[] foo = cwt.EncodeToBytes();

            cwt2 = CWT.Decode(foo, decodeKeys, signKeys);
            foreach (CBORObject key in token.Keys)
            {
                CBORObject value = token[key];
                CBORObject key2  = key;
                if (key.AsString().EndsWith("_hex"))
                {
                    value = CBORObject.FromObject(FromHex(value.AsString()));
                    key2  = CBORObject.FromObject(key.AsString().Substring(0, key.AsString().Length - 4));
                }

                Assert.True(cwt2.HasClaim(key2));
                Assert.AreEqual(value, cwt.GetClaim(key2));
            }
        }
示例#15
0
文件: TestFiles.cs 项目: lulzzz/CWT
        OneKey LoadKey(CBORObject obj)
        {
            OneKey     newKey = new OneKey();
            CBORObject kty;

            switch (obj["kty"].AsString())
            {
            case "oct":
                kty = GeneralValues.KeyType_Octet;
                break;

            case "EC":
                kty = GeneralValues.KeyType_EC;
                break;

            default:
                throw new Exception("Unknown key type " + obj["cty"].AsString());
            }

            foreach (CBORObject key in obj.Keys)
            {
                CBORObject value = obj[key];
                CBORObject key2  = key;

                if (key.AsString().EndsWith("_hex"))
                {
                    value = CBORObject.FromObject(FromHex(value.AsString()));
                    key2  = CBORObject.FromObject(key.AsString().Substring(0, key.AsString().Length - 4));
                }

                key2 = MapKey(key2);
                if (key2.Equals(CoseKeyKeys.KeyType))
                {
                    value = kty;
                }
                else if (key2.Equals(CoseKeyKeys.KeyIdentifier))
                {
                    value = CBORObject.FromObject(Encoding.UTF8.GetBytes(value.AsString()));
                }
                else if (key2.Equals(CoseKeyKeys.Algorithm))
                {
                    value = MapAlgorithm(value.AsString());
                }
                else if (kty.Equals(GeneralValues.KeyType_EC) && key2.Equals(CoseKeyParameterKeys.EC_Curve))
                {
                    switch (value.AsString())
                    {
                    case "P-256":
                        value = GeneralValues.P256;
                        break;

                    default:
                        throw new Exception("Unknown curve " + value.AsString());
                    }
                }

                newKey.Add(key2, value);
            }

            return(newKey);
        }
示例#16
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");
            }
        }
示例#17
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;
        }
示例#18
0
        static void _AddAttributes(Attributes msg, CBORObject map, CBORObject items, int destination)
        {
            foreach (CBORObject cborKey2 in items.Keys)
            {
                CBORObject cborValue = items[cborKey2];
                CBORObject cborKey   = cborKey2;
                string     strKey    = cborKey.AsString();

                if ((strKey.Length > 4) && (strKey.Substring(strKey.Length - 4, 4) == "_hex"))
                {
                    cborKey   = CBORObject.FromObject(strKey.Substring(0, strKey.Length - 4));
                    cborValue = CBORObject.FromObject(FromHex(cborValue.AsString()));
                }

                if (cborKey.AsString() == "comment")
                {
                    continue;
                }

                switch (cborKey.AsString())
                {
                case "alg":
                    break;

                case "kid":
binFromText:
                    break;

                case "epk":
                    break;

                case "spk":
                    break;

                case "salt":
                    goto binFromText;

                case "apu_id":
                    goto binFromText;

                case "apv_id":
                    goto binFromText;

                case "apu_nonce":
                    goto binFromText;

                case "apv_nonce":
                    goto binFromText;

                case "apu_other":
                    goto binFromText;

                case "apv_other":
                    goto binFromText;

                case "pub_other":
                    goto binFromText;

                case "priv_other":
                    goto binFromText;

                case "spk_kid":
                    goto binFromText;

                case "IV":
                    goto binFromText;

                case "partialIV":
                    goto binFromText;

                case "crit":

                    break;

                case "op time":
                {
                    DateTime when = DateTime.Parse(cborValue.AsString());
                    cborValue = CBORObject.FromObject(
                        (long)(when - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);
                }
                break;

                case "ctyp":
                    break;


                case "x5u":
                    break;

                case "x5u-sender":
                    break;

                default:
                    break;
                }

                switch (destination)
                {
                case 0:
                    msg.AddAttribute(cborKey, cborValue, Attributes.PROTECTED);
                    break;

                case 1:
                    msg.AddAttribute(cborKey, cborValue, Attributes.UNPROTECTED);
                    break;

                case 2:
                    msg.AddAttribute(cborKey, cborValue, Attributes.DO_NOT_SEND);
                    break;

                case 4:
                    map[cborKey] = cborValue;
                    break;
                }
            }
        }
示例#19
0
        private static IEnumerable <WebLink> ParseCommon(CBORObject links, Dictionary <string, CBORObject> dictionary)
        {
            if (links.Type != CBORType.Array)
            {
                throw new ArgumentException("Not an array");
            }

            for (int i = 0; i < links.Count; i++)
            {
                CBORObject resource = links[i];
                if (resource.Type != CBORType.Map)
                {
                    throw new ArgumentException("Element not correctly formatted");
                }

                string name;
                if (resource.ContainsKey("href"))
                {
                    name = resource["href"].AsString();
                }
                else
                {
                    name = resource[CBORObject.FromObject(1)].AsString();
                }

                WebLink link = new WebLink(name);

                foreach (CBORObject key in resource.Keys)
                {
                    string keyName = null;
                    if (dictionary != null && key.Type == CBORType.Number)
                    {
                        foreach (KeyValuePair <string, CBORObject> kvp in dictionary)
                        {
                            if (key.Equals(kvp.Value))
                            {
                                keyName = kvp.Key;
                                break;
                            }
                        }
                    }
                    if (keyName == null)
                    {
                        keyName = key.AsString();
                    }

                    if (ParseStrictMode && SingleOccuranceAttributes.Contains(keyName))
                    {
                        throw new ArgumentException($"'{keyName}' occurs multiple times");
                    }

                    CBORObject value = resource[key];
                    if (value.Type == CBORType.Boolean)
                    {
                        link.Attributes.Add(name);
                    }
                    else if (value.Type == CBORType.TextString)
                    {
                        link.Attributes.Add(name, value.AsString());
                    }
                    else if (value.Type == CBORType.Array)
                    {
                        for (int i1 = 0; i1 < value.Count; i1++)
                        {
                            if (value.Type == CBORType.Boolean)
                            {
                                link.Attributes.Add(name);
                            }
                            else if (value.Type == CBORType.TextString)
                            {
                                link.Attributes.Add(name, value.AsString());
                            }
                            else
                            {
                                throw new ArgumentException("incorrect type");
                            }
                        }
                    }
                    else
                    {
                        throw new ArgumentException("incorrect type");
                    }
                }

                yield return(link);
            }
        }
示例#20
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);
        }
示例#21
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");
            }
        }
示例#22
0
 public static void Write(CBORObject obj, Stream stream)
 {
     if (obj.Type == CBORType.Number)
     {
         stream.WriteByte(unchecked ((byte)((byte)'i')));
         writeUtf8(obj.AsEInteger().ToString(), stream);
         stream.WriteByte(unchecked ((byte)((byte)'e')));
     }
     else if (obj.Type == CBORType.TextString)
     {
         string s      = obj.AsString();
         long   length = DataUtilities.GetUtf8Length(s, false);
         if (length < 0)
         {
             throw new CBORException("invalid string");
         }
         writeUtf8(LongToString(length), stream);
         stream.WriteByte(unchecked ((byte)((byte)':')));
         writeUtf8(s, stream);
     }
     else if (obj.Type == CBORType.Map)
     {
         var hasNonStringKeys = false;
         foreach (CBORObject key in obj.Keys)
         {
             if (key.Type != CBORType.TextString)
             {
                 hasNonStringKeys = true;
                 break;
             }
         }
         if (hasNonStringKeys)
         {
             var valueSMap = new Dictionary <String, CBORObject>();
             // Copy to a map with String keys, since
             // some keys could be duplicates
             // when serialized to strings
             foreach (CBORObject key in obj.Keys)
             {
                 CBORObject value = obj[key];
                 string     str   = (key.Type == CBORType.TextString) ?
                                    key.AsString() : key.ToJSONString();
                 valueSMap[str] = value;
             }
             stream.WriteByte(unchecked ((byte)((byte)'d')));
             foreach (KeyValuePair <string, CBORObject> entry in valueSMap)
             {
                 string     key    = entry.Key;
                 CBORObject value  = entry.Value;
                 long       length = DataUtilities.GetUtf8Length(key, false);
                 if (length < 0)
                 {
                     throw new CBORException("invalid string");
                 }
                 writeUtf8(
                     LongToString(length),
                     stream);
                 stream.WriteByte(unchecked ((byte)((byte)':')));
                 writeUtf8(key, stream);
                 Write(value, stream);
             }
             stream.WriteByte(unchecked ((byte)((byte)'e')));
         }
         else
         {
             stream.WriteByte(unchecked ((byte)((byte)'d')));
             foreach (CBORObject key in obj.Keys)
             {
                 string str    = key.AsString();
                 long   length = DataUtilities.GetUtf8Length(str, false);
                 if (length < 0)
                 {
                     throw new CBORException("invalid string");
                 }
                 writeUtf8(LongToString(length), stream);
                 stream.WriteByte(unchecked ((byte)((byte)':')));
                 writeUtf8(str, stream);
                 Write(obj[key], stream);
             }
             stream.WriteByte(unchecked ((byte)((byte)'e')));
         }
     }
     else if (obj.Type == CBORType.Array)
     {
         stream.WriteByte(unchecked ((byte)((byte)'l')));
         for (var i = 0; i < obj.Count; ++i)
         {
             Write(obj[i], stream);
         }
         stream.WriteByte(unchecked ((byte)((byte)'e')));
     }
     else
     {
         string str    = obj.ToJSONString();
         long   length = DataUtilities.GetUtf8Length(str, false);
         if (length < 0)
         {
             throw new CBORException("invalid string");
         }
         writeUtf8(LongToString(length), stream);
         stream.WriteByte(unchecked ((byte)((byte)':')));
         writeUtf8(str, stream);
     }
 }
示例#23
0
        private byte[] Kdf(byte[] secret, EncryptMessage msg, int cbitKey, string algorithmId)
        {
            //  Build a long byte array
            //  four byte counter
            //  secret
            //  AlgorithmID - [32-bit size || algorithm identifier ]
            //  PartyUInfo - [32-bit size || PartyUInfo ] ---- "apu"
            //  PartyVInfo - [32-bit size || PartyVInfo ] ---- "apv"
            //  SuppPubInfo - 32-bit - key data len
            //  SuppPrivInfo - nothing

            byte[] rgbPartyU = new byte[0];
            byte[] rgbPartyV = new byte[0];
            byte[] algId     = Encoding.UTF8.GetBytes(algorithmId);

            CBORObject j = FindAttr("apu", msg);

            if (j != null)
            {
                rgbPartyU = Message.base64urldecode(j.AsString());
            }

            j = FindAttr("apv", msg);
            if (j != null)
            {
                rgbPartyV = Message.base64urldecode(j.AsString());
            }

            int c = 4 + secret.Length + 4 + algId.Length + 4 + rgbPartyU.Length + 4 + rgbPartyV.Length + 4;

            byte[] rgb = new byte[c];

            //  Counter starts at 0

            Array.Copy(secret, 0, rgb, 4, secret.Length);
            c = 4 + secret.Length;

            if (algorithmId.Length > 255)
            {
                throw new JoseException("Internal error");
            }
            rgb[c + 3] = (byte)algId.Length;
            Array.Copy(algId, 0, rgb, c + 4, algId.Length);
            c += 4 + algorithmId.Length;

            if (rgbPartyU.Length > 255)
            {
                throw new JoseException("Internal error");
            }
            rgb[c + 3] = (byte)rgbPartyU.Length;
            Array.Copy(rgbPartyU, 0, rgb, c + 4, rgbPartyU.Length);
            c += 4 + rgbPartyU.Length;

            if (rgbPartyV.Length > 255)
            {
                throw new JoseException("internal error");
            }
            rgb[c + 3] = (byte)rgbPartyV.Length;
            Array.Copy(rgbPartyV, 0, rgb, c + 4, rgbPartyV.Length);
            c += 4 + rgbPartyV.Length;

            if (cbitKey / (256 * 256) != 0)
            {
                throw new JoseException("internal error");
            }
            rgb[c + 3] = (byte)(cbitKey % 256);
            rgb[c + 2] = (byte)(cbitKey / 256);

            //  Now do iterative hashing

            IDigest digest = new Sha256Digest();
            int     cIters = (cbitKey + 255) / 256;

            byte[] rgbDigest = new byte[256 / 8 * cIters];

            for (int i = 0; i < cIters; i++)
            {
                rgb[3] = (byte)(i + 1);
                digest.Reset();
                digest.BlockUpdate(rgb, 0, rgb.Length);
                digest.DoFinal(rgbDigest, (256 / 8) * i);
            }

            byte[] rgbOut = new byte[cbitKey / 8];
            Array.Copy(rgbDigest, rgbOut, rgbOut.Length);
            return(rgbOut);
        }
示例#24
0
 public static void Write(CBORObject obj, Stream stream)
 {
     if (obj.Type == CBORType.Number) {
     stream.WriteByte(unchecked((byte)((byte)'i')));
     writeUtf8(obj.AsEInteger().ToString(), stream);
     stream.WriteByte(unchecked((byte)((byte)'e')));
       } else if (obj.Type == CBORType.TextString) {
     string s = obj.AsString();
     long length = DataUtilities.GetUtf8Length(s, false);
     if (length < 0) {
       throw new CBORException("invalid string");
     }
     writeUtf8(LongToString(length), stream);
     stream.WriteByte(unchecked((byte)((byte)':')));
     writeUtf8(s, stream);
       } else if (obj.Type == CBORType.Map) {
     var hasNonStringKeys = false;
     foreach (CBORObject key in obj.Keys) {
       if (key.Type != CBORType.TextString) {
     hasNonStringKeys = true;
     break;
       }
     }
     if (hasNonStringKeys) {
       var valueSMap = new Dictionary<String, CBORObject>();
       // Copy to a map with String keys, since
       // some keys could be duplicates
       // when serialized to strings
       foreach (CBORObject key in obj.Keys) {
     CBORObject value = obj[key];
     string str = (key.Type == CBORType.TextString) ?
       key.AsString() : key.ToJSONString();
     valueSMap[str] = value;
       }
       stream.WriteByte(unchecked((byte)((byte)'d')));
       foreach (KeyValuePair<string, CBORObject> entry in valueSMap) {
     string key = entry.Key;
     CBORObject value = entry.Value;
     long length = DataUtilities.GetUtf8Length(key, false);
     if (length < 0) {
       throw new CBORException("invalid string");
     }
     writeUtf8(
       LongToString(length),
       stream);
     stream.WriteByte(unchecked((byte)((byte)':')));
     writeUtf8(key, stream);
     Write(value, stream);
       }
       stream.WriteByte(unchecked((byte)((byte)'e')));
     } else {
       stream.WriteByte(unchecked((byte)((byte)'d')));
       foreach (CBORObject key in obj.Keys) {
     string str = key.AsString();
     long length = DataUtilities.GetUtf8Length(str, false);
     if (length < 0) {
       throw new CBORException("invalid string");
     }
     writeUtf8(LongToString(length), stream);
     stream.WriteByte(unchecked((byte)((byte)':')));
     writeUtf8(str, stream);
     Write(obj[key], stream);
       }
       stream.WriteByte(unchecked((byte)((byte)'e')));
     }
       } else if (obj.Type == CBORType.Array) {
     stream.WriteByte(unchecked((byte)((byte)'l')));
     for (var i = 0; i < obj.Count; ++i) {
       Write(obj[i], stream);
     }
     stream.WriteByte(unchecked((byte)((byte)'e')));
       } else {
     string str = obj.ToJSONString();
     long length = DataUtilities.GetUtf8Length(str, false);
     if (length < 0) {
       throw new CBORException("invalid string");
     }
     writeUtf8(LongToString(length), stream);
     stream.WriteByte(unchecked((byte)((byte)':')));
     writeUtf8(str, stream);
       }
 }
示例#25
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);
        }
示例#26
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);
        }
示例#27
0
        internal static void WritePlistToInternalCore(
            CBORObject obj,
            StringOutput writer,
            JSONOptions options,
            IList <CBORObject> stack)
        {
            if (obj.IsNumber)
            {
                if (obj.AsNumber().IsInteger())
                {
                    writer.WriteString("<integer>");
                    writer.WriteString(obj.ToJSONString());
                    writer.WriteString("</integer>");
                }
                else
                {
                    writer.WriteString("<real>");
                    writer.WriteString(obj.ToJSONString());
                    writer.WriteString("</real>");
                }
                return;
            }
            if (obj.HasMostOuterTag(0) || obj.HasMostOuterTag(1))
            {
                CBORDateConverter conv = CBORDateConverter.TaggedString;
                var year         = new EInteger[1];
                var lesserFields = new int[7];
                if (!conv.TryGetDateTimeFields(obj, year, lesserFields))
                {
                    throw new InvalidOperationException("Unsupported date/time");
                }
                // Set fractional seconds and offset to 0, since
                // they're not needed
                lesserFields[5] = 0;
                lesserFields[6] = 0;
                CBORObject newobj = conv.DateTimeFieldsToCBORObject(year[0],
                                                                    lesserFields);
                writer.WriteString("<date>");
                writer.WriteString(newobj.AsString());
                writer.WriteString("</date>");
                return;
            }
            switch (obj.Type)
            {
            case CBORType.Integer: {
                CBORObject untaggedObj = obj.Untag();
                writer.WriteString("<integer>");
                writer.WriteString(untaggedObj.ToJSONString());
                writer.WriteString("</integer>");
                break;
            }

            case CBORType.FloatingPoint: {
                CBORObject untaggedObj = obj.Untag();
                writer.WriteString("<real>");
                writer.WriteString(untaggedObj.ToJSONString());
                writer.WriteString("</real>");
                break;
            }

            case CBORType.Boolean: {
                if (obj.IsTrue)
                {
                    writer.WriteString("<true/>");
                    return;
                }
                if (obj.IsFalse)
                {
                    writer.WriteString("<false/>");
                    return;
                }
                return;
            }

            case CBORType.SimpleValue: {
                // Write all CBOR simple values (other than true and false) as the text string
                // "null".
                writer.WriteString("<str");
                writer.WriteString("ing>");
                writer.WriteString("null");
                writer.WriteString("</str");
                writer.WriteString("ing>");
                return;
            }

            case CBORType.ByteString: {
                byte[] byteArray = obj.GetByteString();
                if (byteArray.Length == 0)
                {
                    writer.WriteString("<data></data>");
                    return;
                }
                if (obj.HasTag(22))
                {
                    writer.WriteString("<data>");
                    // Base64 with padding
                    Base64.WriteBase64(
                        writer,
                        byteArray,
                        0,
                        byteArray.Length,
                        true);
                    writer.WriteString("</data>");
                }
                else if (obj.HasTag(23))
                {
                    writer.WriteString("<str");
                    writer.WriteString("ing>");
                    // Write as base16
                    for (int i = 0; i < byteArray.Length; ++i)
                    {
                        writer.WriteCodePoint((int)Hex16[(byteArray[i] >> 4) & 15]);
                        writer.WriteCodePoint((int)Hex16[byteArray[i] & 15]);
                    }
                    writer.WriteString("</str");
                    writer.WriteString("ing>");
                }
                else
                {
                    writer.WriteString("<data>");
                    // Base64 with padding
                    Base64.WriteBase64(
                        writer,
                        byteArray,
                        0,
                        byteArray.Length,
                        true);
                    writer.WriteString("</data>");
                }
                break;
            }

            case CBORType.TextString: {
                string thisString = obj.AsString();
                if (thisString.Length == 0)
                {
                    writer.WriteString("<str");
                    writer.WriteString("ing>");
                    writer.WriteString("</str");
                    writer.WriteString("ing>");
                    return;
                }
                writer.WriteString("<str");
                writer.WriteString("ing>");
                WritePlistStringUnquoted(thisString, writer, options);
                writer.WriteString("</str");
                writer.WriteString("ing>");
                break;
            }

            case CBORType.Array: {
                writer.WriteString("<array>");
                for (var i = 0; i < obj.Count; ++i)
                {
                    bool pop = CheckCircularRef(stack, obj, obj[i]);
                    WritePlistToInternalCore(obj[i], writer, options, stack);
                    PopRefIfNeeded(stack, pop);
                }
                writer.WriteString("</array>");
                break;
            }

            case CBORType.Map: {
                var hasNonStringKeys = false;
                ICollection <KeyValuePair <CBORObject, CBORObject> > entries =
                    obj.Entries;
                foreach (KeyValuePair <CBORObject, CBORObject> entry in entries)
                {
                    CBORObject key = entry.Key;
                    if (key.Type != CBORType.TextString ||
                        key.IsTagged)
                    {
                        // treat a non-text-string item or a tagged item
                        // as having non-string keys
                        hasNonStringKeys = true;
                        break;
                    }
                }
                if (!hasNonStringKeys)
                {
                    writer.WriteString("<dict>");
                    foreach (KeyValuePair <CBORObject, CBORObject> entry in entries)
                    {
                        CBORObject key   = entry.Key;
                        CBORObject value = entry.Value;
                        writer.WriteString("<key>");
                        WritePlistStringUnquoted(key.AsString(), writer, options);
                        writer.WriteString("</key>");
                        bool pop = CheckCircularRef(stack, obj, value);
                        WritePlistToInternalCore(value, writer, options, stack);
                        PopRefIfNeeded(stack, pop);
                    }
                    writer.WriteString("</dict>");
                }
                else
                {
                    // This map has non-string keys
                    IDictionary <string, CBORObject> stringMap = new
                                                                 Dictionary <string, CBORObject>();
                    // Copy to a map with String keys, since
                    // some keys could be duplicates
                    // when serialized to strings
                    foreach (KeyValuePair <CBORObject, CBORObject> entry
                             in entries)
                    {
                        CBORObject key   = entry.Key;
                        CBORObject value = entry.Value;
                        string     str   = null;
                        switch (key.Type)
                        {
                        case CBORType.TextString:
                            str = key.AsString();
                            break;

                        case CBORType.Array:
                        case CBORType.Map: {
                            var  sb  = new StringBuilder();
                            var  sw  = new StringOutput(sb);
                            bool pop = CheckCircularRef(stack, obj, key);
                            WritePlistToInternalCore(key, sw, options, stack);
                            PopRefIfNeeded(stack, pop);
                            str = sb.ToString();
                            break;
                        }

                        default: str = key.ToJSONString(options);
                            break;
                        }
                        if (stringMap.ContainsKey(str))
                        {
                            throw new CBORException(
                                      "Duplicate Plist string equivalents of map" +
                                      "\u0020keys");
                        }
                        stringMap[str] = value;
                    }
                    writer.WriteString("<dict>");
                    foreach (KeyValuePair <string, CBORObject> entry in stringMap)
                    {
                        string     key   = entry.Key;
                        CBORObject value = entry.Value;
                        writer.WriteString("<key>");
                        WritePlistStringUnquoted((string)key, writer, options);
                        writer.WriteString("</key>");
                        bool pop = CheckCircularRef(stack, obj, value);
                        WritePlistToInternalCore(value, writer, options, stack);
                        PopRefIfNeeded(stack, pop);
                    }
                    writer.WriteString("</dict>");
                }
                break;
            }

            default: throw new InvalidOperationException("Unexpected item" +
                                                         "\u0020type");
            }
        }
示例#28
0
        public void ReverseKey()
        {
            CBORObject result = (CBORObject)_dictionary.Reverse(CBORObject.FromObject(1), false);

            Assert.AreEqual("http://www.iana.org/assignments/relation/item>", result.AsString());
        }