Example #1
0
 public static void AssertRoundTrip(CBORObject o)
 {
     CBORObject o2 = FromBytesTestAB(o.EncodeToBytes());
       TestCommon.CompareTestEqual(o, o2);
       TestNumber(o);
       TestCommon.AssertEqualsHashCode(o, o2);
 }
Example #2
0
   internal static CBORObject ConvertToDecimalFrac(
 CBORObject o,
 bool isDecimal,
 bool extended)
   {
       if (o.Type != CBORType.Array) {
       throw new CBORException("Big fraction must be an array");
         }
         if (o.Count != 2) {
       throw new CBORException("Big fraction requires exactly 2 items");
         }
         if (!o[0].IsIntegral) {
       throw new CBORException("Exponent is not an integer");
         }
         if (!o[1].IsIntegral) {
       throw new CBORException("Mantissa is not an integer");
         }
         EInteger exponent = o[0].AsEInteger();
         EInteger mantissa = o[1].AsEInteger();
         if (exponent.GetSignedBitLength() > 64 && !extended) {
       throw new CBORException("Exponent is too big");
         }
         if (exponent.IsZero) {
       // Exponent is 0, so return mantissa instead
       return CBORObject.FromObject(mantissa);
         }
         // NOTE: Discards tags. See comment in CBORTag2.
         return isDecimal ?
         CBORObject.FromObject(EDecimal.Create(mantissa, exponent)) :
         CBORObject.FromObject(EFloat.Create(mantissa, exponent));
   }
Example #3
0
 public CBORObject ValidateObject(CBORObject obj)
 {
     if (obj.Type != CBORType.Array) {
     throw new CBORException("Rational number must be an array");
       }
       if (obj.Count != 2) {
     throw new CBORException("Rational number requires exactly 2 items");
       }
       CBORObject first = obj[0];
       CBORObject second = obj[1];
       if (!first.IsIntegral) {
     throw new CBORException("Rational number requires integer numerator");
       }
       if (!second.IsIntegral) {
     throw new CBORException("Rational number requires integer denominator");
       }
       if (second.Sign <= 0) {
     throw new CBORException("Rational number requires denominator greater than 0");
       }
       EInteger denom = second.AsEInteger();
       // NOTE: Discards tags. See comment in CBORTag2.
       return denom.Equals(EInteger.One) ?
       CBORObject.FromObject(first.AsEInteger()) :
       CBORObject.FromObject(
       new ERational(
       first.AsEInteger(),
       denom));
 }
Example #4
0
 public void AddStringIfNeeded(CBORObject str, int lengthHint)
 {
     #if DEBUG
       if (str == null) {
     throw new ArgumentNullException("str");
       }
       if (!(str.Type == CBORType.ByteString || str.Type ==
     CBORType.TextString)) {
     throw new
       ArgumentException(
      "doesn't satisfy str.Type== ByteString or TextString");
       }
       if (lengthHint < 0) {
     throw new ArgumentException("lengthHint (" + lengthHint +
             ") is less than " + "0 ");
       }
       #endif
       var addStr = false;
       List<CBORObject> lastList = this.stack[this.stack.Count - 1];
       if (lastList.Count < 24) {
     addStr |= lengthHint >= 3;
       } else if (lastList.Count < 256) {
     addStr |= lengthHint >= 4;
       } else if (lastList.Count < 65536) {
     addStr |= lengthHint >= 5;
       } else {
     // NOTE: lastList's size can't be higher than (2^64)-1
     addStr |= lengthHint >= 7;
       }
       // NOTE: An additional branch, with lengthHint >= 11, would
       // be needed if the size could be higher than (2^64)-1
       if (addStr) {
     lastList.Add(str);
       }
 }
Example #5
0
 public static void AssertSer(CBORObject o, String s)
 {
     if (!s.Equals(o.ToString())) {
     Assert.AreEqual(s, o.ToString(), "o is not equal to s");
       }
       // Test round-tripping
       CBORObject o2 = FromBytesTestAB(o.EncodeToBytes());
       if (!s.Equals(o2.ToString())) {
     Assert.AreEqual(s, o2.ToString(), "o2 is not equal to s");
       }
       TestNumber(o);
       TestCommon.AssertEqualsHashCode(o, o2);
 }
Example #6
0
 internal static CBORObject ConvertToBigNum(CBORObject o, bool negative)
 {
     if (o.Type != CBORType.ByteString) {
     throw new CBORException("Byte array expected");
       }
       byte[] data = o.GetByteString();
       if (data.Length <= 7) {
     long x = 0;
     for (var i = 0; i < data.Length; ++i) {
       x <<= 8;
       x |= ((long)data[i]) & 0xff;
     }
     if (negative) {
       x = -x;
       --x;
     }
     return FromObjectAndInnerTags(x, o);
       }
       int neededLength = data.Length;
       byte[] bytes;
       EInteger bi;
       var extended = false;
       if (((data[0] >> 7) & 1) != 0) {
     // Increase the needed length
     // if the highest bit is set, to
     // distinguish negative and positive
     // values
     ++neededLength;
     extended = true;
       }
       bytes = new byte[neededLength];
       for (var i = 0; i < data.Length; ++i) {
     bytes[i] = data[data.Length - 1 - i];
     if (negative) {
       bytes[i] = (byte)((~((int)bytes[i])) & 0xff);
     }
       }
       if (extended) {
       bytes[bytes.Length - 1] = negative ? (byte)0xff : (byte)0;
       }
       bi = EInteger.FromBytes(bytes, true);
       // NOTE: Here, any tags are discarded; when called from
       // the Read method, "o" will have no tags anyway (beyond tag 2),
       // and when called from FromObjectAndTag, we prefer
       // flexibility over throwing an error if the input
       // object contains other tags. The tag 2 is also discarded
       // because we are returning a "natively" supported CBOR object.
       return CBORObject.FromObject(bi);
 }
Example #7
0
       private static CBORObject FromObjectAndInnerTags(
 object objectValue,
 CBORObject objectWithTags)
       {
           CBORObject newObject = CBORObject.FromObject(objectValue);
             if (!objectWithTags.IsTagged) {
           return newObject;
             }
             objectWithTags = objectWithTags.UntagOne();
             if (!objectWithTags.IsTagged) {
           return newObject;
             }
             EInteger[] tags = objectWithTags.GetAllTags();
             for (int i = tags.Length - 1; i >= 0; --i) {
           newObject = CBORObject.FromObjectAndTag(newObject, tags[i]);
             }
             return newObject;
       }
Example #8
0
 /**
  * Constructor creating an empty CWT.
  */
 public CWT()
 {
     CwtObject = CBORObject.NewMap();
 }
Example #9
0
 public FidoU2f(CBORObject attStmt, byte[] authenticatorData, byte[] clientDataHash, IMetadataService metadataService, bool requireValidAttestationRoot) : base(attStmt, authenticatorData, clientDataHash)
 {
     _metadataService             = metadataService;
     _requireValidAttestationRoot = requireValidAttestationRoot;
 }
Example #10
0
        public override void Verify()
        {
            // verify that aaguid is 16 empty bytes (note: required by fido2 conformance testing, could not find this in spec?)
            if (false == AuthData.AttData.Aaguid.SequenceEqual(Guid.Empty.ToByteArray()))
            {
                throw new Fido2VerificationException("Aaguid was not empty parsing fido-u2f atttestation statement");
            }

            // 1. Verify that attStmt is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the contained fields.
            if (null == X5c || CBORType.Array != X5c.Type || X5c.Count != 1)
            {
                throw new Fido2VerificationException("Malformed x5c in fido - u2f attestation");
            }

            // 2a. the attestation certificate attestnCert MUST be the first element in the array
            if (null == X5c.Values || 0 == X5c.Values.Count ||
                CBORType.ByteString != X5c.Values.First().Type ||
                0 == X5c.Values.First().GetByteString().Length)
            {
                throw new Fido2VerificationException("Malformed x5c in fido-u2f attestation");
            }

            var cert = new X509Certificate2(X5c.Values.First().GetByteString());

            // 2b. If certificate public key is not an Elliptic Curve (EC) public key over the P-256 curve, terminate this algorithm and return an appropriate error
            var pubKey = (ECDsaCng)cert.GetECDsaPublicKey();

            if (CngAlgorithm.ECDsaP256 != pubKey.Key.Algorithm)
            {
                throw new Fido2VerificationException("Attestation certificate public key is not an Elliptic Curve (EC) public key over the P-256 curve");
            }

            // 3. Extract the claimed rpIdHash from authenticatorData, and the claimed credentialId and credentialPublicKey from authenticatorData
            // see rpIdHash, credentialId, and credentialPublicKey variables

            // 4. Convert the COSE_KEY formatted credentialPublicKey (see Section 7 of [RFC8152]) to CTAP1/U2F public Key format
            var publicKeyU2F = CryptoUtils.U2FKeyFromCOSEKey(CredentialPublicKey);

            // 5. Let verificationData be the concatenation of (0x00 || rpIdHash || clientDataHash || credentialId || publicKeyU2F)
            var verificationData = new byte[1] {
                0x00
            };

            verificationData = verificationData
                               .Concat(AuthData.RpIdHash)
                               .Concat(clientDataHash)
                               .Concat(AuthData.AttData.CredentialID)
                               .Concat(publicKeyU2F.ToArray())
                               .ToArray();

            // 6. Verify the sig using verificationData and certificate public key
            if (null == Sig || CBORType.ByteString != Sig.Type || 0 == Sig.GetByteString().Length)
            {
                throw new Fido2VerificationException("Invalid fido-u2f attestation signature");
            }

            var ecsig = CryptoUtils.SigFromEcDsaSig(Sig.GetByteString(), pubKey.KeySize);

            if (null == ecsig)
            {
                throw new Fido2VerificationException("Failed to decode fido-u2f attestation signature from ASN.1 encoded form");
            }

            if (true != pubKey.VerifyData(verificationData, ecsig, CryptoUtils.algMap[CredentialPublicKey[CBORObject.FromObject(3)].AsInt32()]))
            {
                throw new Fido2VerificationException("Invalid fido-u2f attestation signature");
            }
        }
Example #11
0
 public AndroidKey(CBORObject attStmt, byte[] authenticatorData, byte[] clientDataHash) : base(attStmt, authenticatorData, clientDataHash)
 {
 }
Example #12
0
 private static EDecimal AsED(CBORObject obj)
 {
     return EDecimal.FromString(
     obj.AsEDecimal().ToString());
 }
Example #13
0
 public static CBORObject Subtract(CBORObject a, CBORObject b)
 {
     if (a == null) {
     throw new ArgumentNullException("a");
       }
       if (b == null) {
     throw new ArgumentNullException("b");
       }
       if (a.Type != CBORType.Number) {
     throw new ArgumentException("a.Type (" + a.Type +
       ") is not equal to " + CBORType.Number);
       }
       if (b.Type != CBORType.Number) {
     throw new ArgumentException("b.Type (" + b.Type +
       ") is not equal to " + CBORType.Number);
       }
       object objA = a.ThisItem;
       object objB = b.ThisItem;
       int typeA = a.ItemType;
       int typeB = b.ItemType;
       if (typeA == CBORObject.CBORObjectTypeInteger && typeB ==
       CBORObject.CBORObjectTypeInteger) {
     var valueA = (long)objA;
     var valueB = (long)objB;
     if ((valueB < 0 && Int64.MaxValue + valueB < valueA) ||
         (valueB > 0 && Int64.MinValue + valueB > valueA)) {
       // would overflow, convert to EInteger
       return CBORObject.FromObject(((EInteger)valueA) -
       (EInteger)valueB);
     }
     return CBORObject.FromObject(valueA - valueB);
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedRational ||
      typeB == CBORObject.CBORObjectTypeExtendedRational) {
     ERational e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
     ERational e2 =
     CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
     return CBORObject.FromObject(e1.Subtract(e2));
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedDecimal ||
      typeB == CBORObject.CBORObjectTypeExtendedDecimal) {
     EDecimal e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedDecimal(objA);
     EDecimal e2 =
     CBORObject.GetNumberInterface(typeB).AsExtendedDecimal(objB);
     return CBORObject.FromObject(e1.Subtract(e2));
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedFloat || typeB ==
       CBORObject.CBORObjectTypeExtendedFloat ||
        typeA == CBORObject.CBORObjectTypeDouble || typeB ==
        CBORObject.CBORObjectTypeDouble ||
        typeA == CBORObject.CBORObjectTypeSingle || typeB ==
        CBORObject.CBORObjectTypeSingle) {
     EFloat e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedFloat(objA);
     EFloat e2 = CBORObject.GetNumberInterface(typeB).AsExtendedFloat(objB);
     return CBORObject.FromObject(e1.Subtract(e2));
       } else {
     EInteger b1 = CBORObject.GetNumberInterface(typeA).AsEInteger(objA);
     EInteger b2 = CBORObject.GetNumberInterface(typeB).AsEInteger(objB);
     return CBORObject.FromObject(b1 - (EInteger)b2);
       }
 }
Example #14
0
 public CBORObject ValidateObject(CBORObject obj)
 {
     return ConvertToDecimalFrac(obj, false, this.extended);
 }
Example #15
0
        public static void KdcToken(string[] cmds)
        {
            if (cmds.Length != 7)
            {
                Console.WriteLine("Incorrect argument Count: KdcToken <AS> <Audience> <Scope> <OscoreKeys> <Kdc> <Store>");
                return;
            }

            Request request = new Request(Method.POST)
            {
                URI = new Uri(cmds[1])
            };

            Oauth.Request oRequest = new Oauth.Request(Oauth.Request.GrantType_ClientToken)
            {
                Audience = cmds[2],
                Scope    = CBORObject.FromObject(cmds[3])
            };

            request.Payload       = oRequest.EncodeToBytes();
            request.ContentType   = MediaType.ApplicationAceCbor;
            request.OscoreContext = Program._OscoreKeys[cmds[4]];

            request.Send();
            Response response = request.WaitForResponse();

            if (response.StatusCode != StatusCode.Created)
            {
                Console.WriteLine($"Error with response from the AS - Code is {response.StatusCode}");
                return;
            }

            Oauth.Response oResponse = Oauth.Response.FromCBOR(response.Payload);

            Confirmation cnf = oResponse.Confirmation;

            byte[][] oscoreSalts = new byte[2][];

            request = new Request(Method.POST)
            {
                URI = new Uri(cmds[5])
            };

            CBORObject kdcRequest = CBORObject.NewMap();

            kdcRequest.Add(Oauth_Parameter.Access_Token.Key, oResponse.Token);
            if (cnf.AsCBOR.ContainsKey(CBORObject.FromObject(Confirmation.ConfirmationIds.COSE_OSCORE)))
            {
                oscoreSalts[0] = SecureRandom.GetNextBytes(new SecureRandom(), 8);
                kdcRequest.Add(Oauth_Parameter.CNonce.Key, CBORObject.FromObject(oscoreSalts[0]));
                request.ContentFormat = MediaType.ApplicationAceCbor;
            }

            request.Payload = kdcRequest.EncodeToBytes();


            request.Send();
            response = request.WaitForResponse();

            if (response.StatusCode != StatusCode.Created)
            {
                Console.WriteLine("Failure");
                return;
            }

            Console.WriteLine("Successfully posted to KDC");
            CBORObject cborResponse = CBORObject.DecodeFromBytes(response.Payload);

            GroupData groupData = new GroupData();

            if (cborResponse.ContainsKey(Oauth_Parameter.CNonce.Key))
            {
                groupData.ServerNonce = cborResponse[Oauth_Parameter.CNonce.Key].GetByteString();
            }

            if (cborResponse.ContainsKey("sign_info"))
            {
                groupData.SignInfo = CBORObject.DecodeFromBytes(cborResponse["sign_info"].GetByteString());
            }
            else
            {
                groupData.SignInfo = CBORObject.DecodeFromBytes(new byte[] { 0x83, 0x27, 0x06, 0x82, 0x01, 0x06 });
            }

            if (cborResponse.ContainsKey("pub_key_enc"))
            {
                groupData.PubKeyEnc = cborResponse["pub_key_enc"].GetByteString();
            }

            groupData.SignNonce = cborResponse["SignNonce"].GetByteString();

            if (cnf.AsCBOR.ContainsKey(CBORObject.FromObject(Confirmation.ConfirmationIds.COSE_OSCORE)))
            {
                CBORObject oscoreContext = cnf.AsCBOR[CBORObject.FromObject(Confirmation.ConfirmationIds.COSE_OSCORE)];

                byte[] salt = new byte[0];
                if (oscoreContext.ContainsKey(CBORObject.FromObject(6)))
                {
                    salt = oscoreContext[CBORObject.FromObject(CBORObject.FromObject(6))].GetByteString();
                }
                CBORObject alg = null;
                if (oscoreContext.ContainsKey(CBORObject.FromObject(5)))
                {
                    alg = oscoreContext[CBORObject.FromObject(5)];
                }
                CBORObject kdf = null;
                if (oscoreContext.ContainsKey(CBORObject.FromObject(4)))
                {
                    kdf = oscoreContext[CBORObject.FromObject(4)];
                }
                byte[] keyContext = null;
                if (oscoreContext.ContainsKey(CBORObject.FromObject(7)))
                {
                    keyContext = oscoreContext[CBORObject.FromObject(7)].GetByteString();
                }

                oscoreSalts[1] = cborResponse[Oauth_Parameter.CNonce.Key].GetByteString();

                byte[] newSalt = new byte[salt.Length + oscoreSalts[0].Length + oscoreSalts[1].Length];
                Array.Copy(salt, newSalt, salt.Length);
                Array.Copy(oscoreSalts[0], 0, newSalt, salt.Length, oscoreSalts[0].Length);
                Array.Copy(oscoreSalts[1], 0, newSalt, salt.Length + oscoreSalts[0].Length, oscoreSalts[1].Length);

                SecurityContext oscoapContext = SecurityContext.DeriveContext(
                    oscoreContext[CBORObject.FromObject(1)].GetByteString(), keyContext,
                    oscoreContext[CBORObject.FromObject(2)].GetByteString(),
                    oscoreContext[CBORObject.FromObject(3)].GetByteString(),
                    newSalt, alg, kdf);
                oscoapContext.UserData = groupData;

                Program._OscoreKeys.Add(cmds[6], oscoapContext);
            }
            else if (cnf.AsCBOR.ContainsKey(CBORObject.FromObject(Confirmation.ConfirmationIds.COSE_Key)))
            {
                TlsKeyPair tlsKey = new TlsKeyPair(cnf.Key);
                tlsKey.PrivateKey.UserData = groupData;

                Program._TlsKeys.Add(cmds[5], new TlsKeyPair(cnf.Key));
            }
            else
            {
                Console.WriteLine("Don't know how to get the key");
            }
        }
Example #16
0
 public void TestAsEDecimal()
 {
     {
         object objectTemp  = CBORTestCommon.DecPosInf;
         object objectTemp2 =
             ToObjectTest.TestToFromObjectRoundTrip(Single.PositiveInfinity)
             .AsNumber().ToEDecimal();
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = CBORTestCommon.DecNegInf;
         object objectTemp2 =
             ToObjectTest.TestToFromObjectRoundTrip(Single.NegativeInfinity)
             .AsNumber().ToEDecimal();
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         string stringTemp = ToObjectTest.TestToFromObjectRoundTrip(
             Single.NaN).AsNumber().ToEDecimal().ToString();
         Assert.AreEqual(
             "NaN",
             stringTemp);
     }
     {
         object objectTemp  = CBORTestCommon.DecPosInf;
         object objectTemp2 =
             ToObjectTest.TestToFromObjectRoundTrip(Double.PositiveInfinity)
             .AsNumber().ToEDecimal();
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = CBORTestCommon.DecNegInf;
         object objectTemp2 =
             ToObjectTest.TestToFromObjectRoundTrip(Double.NegativeInfinity)
             .AsNumber().ToEDecimal();
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = "NaN";
         object objectTemp2 =
             ToObjectTest.TestToFromObjectRoundTrip(
                 Double.NaN).AsNumber().ToEDecimal()
             .ToString();
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     try {
         CBORObject.NewArray().AsNumber().ToEDecimal();
         Assert.Fail("Should have failed");
     } catch (InvalidOperationException) {
         // NOTE: Intentionally empty
     } catch (Exception ex) {
         Assert.Fail(ex.ToString());
         throw new InvalidOperationException(String.Empty, ex);
     }
     try {
         CBORObject.NewMap().AsNumber().ToEDecimal();
         Assert.Fail("Should have failed");
     } catch (InvalidOperationException) {
         // NOTE: Intentionally empty
     } catch (Exception ex) {
         Assert.Fail(ex.ToString());
         throw new InvalidOperationException(String.Empty, ex);
     }
     try {
         CBORObject.True.AsNumber().ToEDecimal();
         Assert.Fail("Should have failed");
     } catch (InvalidOperationException) {
         // NOTE: Intentionally empty
     } catch (Exception ex) {
         Assert.Fail(ex.ToString());
         throw new InvalidOperationException(String.Empty, ex);
     }
     try {
         CBORObject.False.AsNumber().ToEDecimal();
         Assert.Fail("Should have failed");
     } catch (InvalidOperationException) {
         // NOTE: Intentionally empty
     } catch (Exception ex) {
         Assert.Fail(ex.ToString());
         throw new InvalidOperationException(String.Empty, ex);
     }
     try {
         CBORObject.Undefined.AsNumber().ToEDecimal();
         Assert.Fail("Should have failed");
     } catch (InvalidOperationException) {
         // NOTE: Intentionally empty
     } catch (Exception ex) {
         Assert.Fail(ex.ToString());
         throw new InvalidOperationException(String.Empty, ex);
     }
     try {
         ToObjectTest.TestToFromObjectRoundTrip(
             String.Empty).AsNumber().ToEDecimal();
         Assert.Fail("Should have failed");
     } catch (InvalidOperationException) {
         // NOTE: Intentionally empty
     } catch (Exception ex) {
         Assert.Fail(ex.ToString());
         throw new InvalidOperationException(String.Empty, ex);
     }
 }
Example #17
0
        public void TestAsEInteger()
        {
            try {
                ToObjectTest.TestToFromObjectRoundTrip(
                    (object)null).AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (InvalidOperationException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                CBORObject.Null.AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (InvalidOperationException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                CBORObject.True.AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (InvalidOperationException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                CBORObject.False.AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (InvalidOperationException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                CBORObject.Undefined.AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (InvalidOperationException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                CBORObject.NewArray().AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (InvalidOperationException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                CBORObject.NewMap().AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (InvalidOperationException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            CBORObject numbers = CBORObjectTest.GetNumberData();

            for (int i = 0; i < numbers.Count; ++i)
            {
                CBORObject numberinfo   = numbers[i];
                string     numberString = numberinfo["number"].AsString();
                CBORObject cbornumber   =
                    ToObjectTest.TestToFromObjectRoundTrip(EDecimal.FromString(
                                                               numberString));
                if (!numberinfo["integer"].Equals(CBORObject.Null))
                {
                    Assert.AreEqual(
                        numberinfo["integer"].AsString(),
                        cbornumber.AsNumber().ToEInteger().ToString());
                }
                else
                {
                    try {
                        cbornumber.AsNumber().ToEInteger();
                        Assert.Fail("Should have failed");
                    } catch (OverflowException) {
                        // NOTE: Intentionally empty
                    } catch (Exception ex) {
                        Assert.Fail(ex.ToString());
                        throw new InvalidOperationException(String.Empty, ex);
                    }
                }
            }

            {
                string stringTemp =
                    ToObjectTest.TestToFromObjectRoundTrip(0.75f).AsNumber().ToEInteger()
                    .ToString();
                Assert.AreEqual(
                    "0",
                    stringTemp);
            }
            {
                string stringTemp =
                    ToObjectTest.TestToFromObjectRoundTrip(0.99f).AsNumber().ToEInteger()
                    .ToString();
                Assert.AreEqual(
                    "0",
                    stringTemp);
            }
            {
                string stringTemp =
                    ToObjectTest.TestToFromObjectRoundTrip(0.0000000000000001f)
                    .AsNumber().ToEInteger().ToString();
                Assert.AreEqual(
                    "0",
                    stringTemp);
            }
            {
                string stringTemp =
                    ToObjectTest.TestToFromObjectRoundTrip(0.5f).AsNumber().ToEInteger()
                    .ToString();
                Assert.AreEqual(
                    "0",
                    stringTemp);
            }
            {
                string stringTemp =
                    ToObjectTest.TestToFromObjectRoundTrip(1.5f).AsNumber().ToEInteger()
                    .ToString();
                Assert.AreEqual(
                    "1",
                    stringTemp);
            }
            {
                string stringTemp =
                    ToObjectTest.TestToFromObjectRoundTrip(2.5f).AsNumber().ToEInteger()
                    .ToString();
                Assert.AreEqual(
                    "2",
                    stringTemp);
            }
            {
                string stringTemp =

                    ToObjectTest.TestToFromObjectRoundTrip(
                        (float)328323f).AsNumber().ToEInteger().ToString();
                Assert.AreEqual(
                    "328323",
                    stringTemp);
            }
            {
                string stringTemp =
                    ToObjectTest.TestToFromObjectRoundTrip(
                        (double)0.75).AsNumber().ToEInteger()
                    .ToString();
                Assert.AreEqual(
                    "0",
                    stringTemp);
            }
            {
                string stringTemp = ToObjectTest.TestToFromObjectRoundTrip(
                    (double)0.99).AsNumber().ToEInteger().ToString();
                Assert.AreEqual(
                    "0",
                    stringTemp);
            }
            {
                string stringTemp =
                    ToObjectTest.TestToFromObjectRoundTrip((double)0.0000000000000001)
                    .AsNumber().ToEInteger().ToString();
                Assert.AreEqual(
                    "0",
                    stringTemp);
            }
            {
                string stringTemp = ToObjectTest.TestToFromObjectRoundTrip(
                    (double)0.5).AsNumber().ToEInteger().ToString();
                Assert.AreEqual(
                    "0",
                    stringTemp);
            }
            {
                string stringTemp =
                    ToObjectTest.TestToFromObjectRoundTrip(
                        (double)1.5).AsNumber().ToEInteger()
                    .ToString();
                Assert.AreEqual(
                    "1",
                    stringTemp);
            }
            {
                string stringTemp = ToObjectTest.TestToFromObjectRoundTrip(
                    (double)2.5).AsNumber().ToEInteger().ToString();
                Assert.AreEqual(
                    "2",
                    stringTemp);
            }
            {
                double dbl        = 328323;
                string stringTemp = ToObjectTest.TestToFromObjectRoundTrip(dbl)
                                    .AsNumber().ToEInteger().ToString();
                Assert.AreEqual(
                    "328323",
                    stringTemp);
            }
            try {
                ToObjectTest.TestToFromObjectRoundTrip(Single.PositiveInfinity)
                .AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (OverflowException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                ToObjectTest.TestToFromObjectRoundTrip(Single.NegativeInfinity)
                .AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (OverflowException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                ToObjectTest.TestToFromObjectRoundTrip(
                    Single.NaN).AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (OverflowException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                ToObjectTest.TestToFromObjectRoundTrip(Double.PositiveInfinity)
                .AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (OverflowException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                ToObjectTest.TestToFromObjectRoundTrip(Double.NegativeInfinity)
                .AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (OverflowException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
            try {
                ToObjectTest.TestToFromObjectRoundTrip(
                    Double.NaN).AsNumber().ToEInteger();
                Assert.Fail("Should have failed");
            } catch (OverflowException) {
                // NOTE: Intentionally empty
            } catch (Exception ex) {
                Assert.Fail(ex.ToString());
                throw new InvalidOperationException(String.Empty, ex);
            }
        }
Example #18
0
 private static EDecimal AsED(CBORObject obj)
 {
     return((EDecimal)obj.ToObject(typeof(EDecimal)));
 }
Example #19
0
 public Packed(CBORObject attStmt, byte[] authenticatorData, byte[] clientDataHash, IMetadataService metadataService)
     : base(attStmt, authenticatorData, clientDataHash)
 {
     _metadataService = metadataService;
 }
Example #20
0
        public override void Verify()
        {
            // Verify that attStmt is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the contained fields
            if (0 == attStmt.Keys.Count || 0 == attStmt.Values.Count)
            {
                throw new Fido2VerificationException("Attestation format packed must have attestation statement");
            }

            if (null == Sig || CBORType.ByteString != Sig.Type || 0 == Sig.GetByteString().Length)
            {
                throw new Fido2VerificationException("Invalid packed attestation signature");
            }
            // 2a. Verify that sig is a valid signature over the concatenation of authenticatorData and clientDataHash
            // using the attestation public key in attestnCert with the algorithm specified in alg
            if (null == X5c && CBORType.Array != X5c.Type && 0 == X5c.Count)
            {
                throw new Fido2VerificationException("Malformed x5c in android-key attestation");
            }

            if (null == X5c.Values || 0 == X5c.Values.Count ||
                CBORType.ByteString != X5c.Values.First().Type ||
                0 == X5c.Values.First().GetByteString().Length)
            {
                throw new Fido2VerificationException("Malformed x5c in android-key attestation");
            }

            X509Certificate2 androidKeyCert   = null;
            ECDsaCng         androidKeyPubKey = null;

            try
            {
                androidKeyCert   = new X509Certificate2(X5c.Values.First().GetByteString());
                androidKeyPubKey = (ECDsaCng)androidKeyCert.GetECDsaPublicKey(); // attestation public key
            }
            catch (Exception ex)
            {
                throw new Fido2VerificationException("Failed to extract public key from android key" + ex.Message);
            }

            if (null == Alg || CBORType.Number != Alg.Type || false == CryptoUtils.algMap.ContainsKey(Alg.AsInt32()))
            {
                throw new Fido2VerificationException("Invalid attestation algorithm");
            }
            if (true != androidKeyPubKey.VerifyData(Data, CryptoUtils.SigFromEcDsaSig(Sig.GetByteString(), androidKeyPubKey.KeySize), CryptoUtils.algMap[Alg.AsInt32()]))
            {
                throw new Fido2VerificationException("Invalid android key signature");
            }

            var credentialPublicKey = CBORObject.DecodeFromBytes(AuthData.AttData.CredentialPublicKey);
            var cng = ECDsa.Create(new ECParameters
            {
                Curve = ECCurve.NamedCurves.nistP256,
                Q     = new ECPoint
                {
                    X = credentialPublicKey[CBORObject.FromObject(-2)].GetByteString(),
                    Y = credentialPublicKey[CBORObject.FromObject(-3)].GetByteString()
                }
            });

            // Verify that the public key in the first certificate in in x5c matches the credentialPublicKey in the attestedCredentialData in authenticatorData.
            if (true != cng.VerifyData(Data, CryptoUtils.SigFromEcDsaSig(Sig.GetByteString(), cng.KeySize), CryptoUtils.algMap[Alg.AsInt32()]))
            {
                throw new Fido2VerificationException("Invalid android key signature");
            }

            // Verify that in the attestation certificate extension data:
            var attExtBytes = AttestationExtensionBytes(androidKeyCert.Extensions);

            // 1. The value of the attestationChallenge field is identical to clientDataHash.
            var attestationChallenge = GetAttestationChallenge(attExtBytes);

            if (false == clientDataHash.SequenceEqual(attestationChallenge))
            {
                throw new Fido2VerificationException("Mismatched between attestationChallenge and hashedClientDataJson verifying android key attestation certificate extension");
            }

            // 2. The AuthorizationList.allApplications field is not present, since PublicKeyCredential MUST be bound to the RP ID.
            if (true == FindAllApplicationsField(attExtBytes))
            {
                throw new Fido2VerificationException("Found all applications field in android key attestation certificate extension");
            }

            // 3. The value in the AuthorizationList.origin field is equal to KM_ORIGIN_GENERATED ( which == 0).
            if (false == IsOriginGenerated(attExtBytes))
            {
                throw new Fido2VerificationException("Found origin field not set to KM_ORIGIN_GENERATED in android key attestation certificate extension");
            }

            // 4. The value in the AuthorizationList.purpose field is equal to KM_PURPOSE_SIGN (which == 2).
            if (false == IsPurposeSign(attExtBytes))
            {
                throw new Fido2VerificationException("Found purpose field not set to KM_PURPOSE_SIGN in android key attestation certificate extension");
            }
        }
Example #21
0
        public void TestFromObject()
        {
            var cborarray = new CBORObject[2];
              cborarray[0] = CBORObject.False;
              cborarray[1] = CBORObject.True;
              CBORObject cbor = CBORObject.FromObject(cborarray);
              Assert.AreEqual(2, cbor.Count);
              Assert.AreEqual(CBORObject.False, cbor[0]);
              Assert.AreEqual(CBORObject.True, cbor[1]);
              CBORTestCommon.AssertRoundTrip(cbor);
              Assert.AreEqual(CBORObject.Null, CBORObject.FromObject((int[])null));
              long[] longarray = { 2, 3 };
              cbor = CBORObject.FromObject(longarray);
              Assert.AreEqual(2, cbor.Count);
              Assert.IsTrue(CBORObject.FromObject(2).CompareTo(cbor[0]) == 0);
              Assert.IsTrue(CBORObject.FromObject(3).CompareTo(cbor[1]) == 0);
              CBORTestCommon.AssertRoundTrip(cbor);
              Assert.AreEqual(
            CBORObject.Null,
            CBORObject.FromObject((ERational)null));
              Assert.AreEqual(
            CBORObject.Null,
            CBORObject.FromObject((EDecimal)null));
              Assert.AreEqual(
            CBORObject.FromObject(10),
            CBORObject.FromObject(ERational.Create(10, 1)));
              try {
            CBORObject.FromObject(ERational.Create(10, 2));
              } catch (Exception ex) {
            Assert.Fail(ex.ToString());
            throw new InvalidOperationException(String.Empty, ex);
              }

              try {
            CBORObject.FromObject(CBORObject.FromObject(Double.NaN).Sign);
            Assert.Fail("Should have failed");
              } catch (InvalidOperationException) {
            new Object();
              } catch (Exception ex) {
            Assert.Fail(ex.ToString());
            throw new InvalidOperationException(String.Empty, ex);
              }
              cbor = CBORObject.True;
              try {
            CBORObject.FromObject(cbor[0]);
            Assert.Fail("Should have failed");
              } catch (InvalidOperationException) {
            new Object();
              } catch (Exception ex) {
            Assert.Fail(ex.ToString());
            throw new InvalidOperationException(String.Empty, ex);
              }
              try {
            cbor[0] = CBORObject.False;
            Assert.Fail("Should have failed");
              } catch (InvalidOperationException) {
            new Object();
              } catch (Exception ex) {
            Assert.Fail(ex.ToString());
            throw new InvalidOperationException(String.Empty, ex);
              }
              try {
            cbor = CBORObject.False;
            CBORObject.FromObject(cbor.Keys);
            Assert.Fail("Should have failed");
              } catch (InvalidOperationException) {
            new Object();
              } catch (Exception ex) {
            Assert.Fail(ex.ToString());
            throw new InvalidOperationException(String.Empty, ex);
              }
              try {
            CBORObject.FromObject(CBORObject.NewArray().Keys);
            Assert.Fail("Should have failed");
              } catch (InvalidOperationException) {
            new Object();
              } catch (Exception ex) {
            Assert.Fail(ex.ToString());
            throw new InvalidOperationException(String.Empty, ex);
              }
              try {
            CBORObject.FromObject(CBORObject.NewArray().Sign);
            Assert.Fail("Should have failed");
              } catch (InvalidOperationException) {
            new Object();
              } catch (Exception ex) {
            Assert.Fail(ex.ToString());
            throw new InvalidOperationException(String.Empty, ex);
              }
              try {
            CBORObject.FromObject(CBORObject.NewMap().Sign);
            Assert.Fail("Should have failed");
              } catch (InvalidOperationException) {
            new Object();
              } catch (Exception ex) {
            Assert.Fail(ex.ToString());
            throw new InvalidOperationException(String.Empty, ex);
              }
        }
Example #22
0
 private static void AssertReadThree(byte[] bytes, CBORObject cbor)
 {
     try {
     using (var ms = new MemoryStream(bytes)) {
       CBORObject cbor1, cbor2, cbor3;
       cbor1 = CBORObject.Read(ms);
       cbor2 = CBORObject.Read(ms);
       cbor3 = CBORObject.Read(ms);
       TestCommon.CompareTestEqualAndConsistent(cbor1, cbor);
       TestCommon.CompareTestRelations(cbor1, cbor2, cbor3);
       TestCommon.CompareTestEqualAndConsistent(cbor1, cbor2);
       TestCommon.CompareTestEqualAndConsistent(cbor2, cbor3);
       TestCommon.CompareTestEqualAndConsistent(cbor3, cbor1);
     }
       } catch (Exception ex) {
     Assert.Fail(ex.ToString() + "\r\n" +
       TestCommon.ToByteArrayString(bytes) + "\r\n" +
       "cbor = " + cbor.ToString() + "\r\n");
     throw new InvalidOperationException(ex.ToString(), ex);
       }
 }
Example #23
0
            public void GetRpkKey(RawPublicKey rpk)
            {
                AsymmetricKeyParameter key;

                try {
                    key = PublicKeyFactory.CreateKey(rpk.SubjectPublicKeyInfo());
                }
                catch (Exception e) {
                    throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e);
                }

                if (key is ECPublicKeyParameters)
                {
                    ECPublicKeyParameters ecKey = (ECPublicKeyParameters)key;

                    string s      = ecKey.AlgorithmName;
                    OneKey newKey = new OneKey();
                    newKey.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_EC);
                    if (ecKey.Parameters.Curve.Equals(NistNamedCurves.GetByName("P-256").Curve))
                    {
                        newKey.Add(CoseKeyParameterKeys.EC_Curve, GeneralValues.P256);
                    }

                    newKey.Add(CoseKeyParameterKeys.EC_X, CBORObject.FromObject(ecKey.Q.Normalize().XCoord.ToBigInteger().ToByteArrayUnsigned()));
                    newKey.Add(CoseKeyParameterKeys.EC_Y, CBORObject.FromObject(ecKey.Q.Normalize().YCoord.ToBigInteger().ToByteArrayUnsigned()));

                    if (_serverKeys != null)
                    {
                        foreach (OneKey k in _serverKeys)
                        {
                            if (k.Compare(newKey))
                            {
                                AuthenticationKey = k;
                                return;
                            }
                        }
                    }

                    TlsEvent ev = new TlsEvent(TlsEvent.EventCode.ServerCertificate)
                    {
                        KeyValue = newKey
                    };

                    EventHandler <TlsEvent> handler = TlsEventHandler;
                    if (handler != null)
                    {
                        handler(this, ev);
                    }

                    if (!ev.Processed)
                    {
                        //                    throw new TlsFatalAlert(AlertDescription.certificate_unknown);
                    }

                    AuthenticationKey = ev.KeyValue;
                }
                else
                {
                    // throw new TlsFatalAlert(AlertDescription.certificate_unknown);
                }
            }
Example #24
0
 public static CBORObject Multiply(CBORObject a, CBORObject b)
 {
     if (a == null) {
     throw new ArgumentNullException("a");
       }
       if (b == null) {
     throw new ArgumentNullException("b");
       }
       if (a.Type != CBORType.Number) {
     throw new ArgumentException("a.Type (" + a.Type +
       ") is not equal to " + CBORType.Number);
       }
       if (b.Type != CBORType.Number) {
     throw new ArgumentException("b.Type (" + b.Type +
       ") is not equal to " + CBORType.Number);
       }
       object objA = a.ThisItem;
       object objB = b.ThisItem;
       int typeA = a.ItemType;
       int typeB = b.ItemType;
       if (typeA == CBORObject.CBORObjectTypeInteger && typeB ==
       CBORObject.CBORObjectTypeInteger) {
     var valueA = (long)objA;
     var valueB = (long)objB;
     bool apos = valueA > 0L;
     bool bpos = valueB > 0L;
     if (
       (apos && ((!bpos && (Int64.MinValue / valueA) > valueB) ||
       (bpos && valueA > (Int64.MaxValue / valueB)))) ||
       (!apos && ((!bpos && valueA != 0L &&
       (Int64.MaxValue / valueA) > valueB) ||
       (bpos && valueA < (Int64.MinValue / valueB))))) {
       // would overflow, convert to EInteger
       var bvalueA = (EInteger)valueA;
       var bvalueB = (EInteger)valueB;
       return CBORObject.FromObject(bvalueA * (EInteger)bvalueB);
     }
     return CBORObject.FromObject(valueA * valueB);
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedRational ||
      typeB == CBORObject.CBORObjectTypeExtendedRational) {
     ERational e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
     ERational e2 =
     CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
     return CBORObject.FromObject(e1.Multiply(e2));
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedDecimal ||
      typeB == CBORObject.CBORObjectTypeExtendedDecimal) {
     EDecimal e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedDecimal(objA);
     EDecimal e2 =
     CBORObject.GetNumberInterface(typeB).AsExtendedDecimal(objB);
     return CBORObject.FromObject(e1.Multiply(e2));
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedFloat || typeB ==
       CBORObject.CBORObjectTypeExtendedFloat ||
        typeA == CBORObject.CBORObjectTypeDouble || typeB ==
        CBORObject.CBORObjectTypeDouble ||
        typeA == CBORObject.CBORObjectTypeSingle || typeB ==
        CBORObject.CBORObjectTypeSingle) {
     EFloat e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedFloat(objA);
     EFloat e2 = CBORObject.GetNumberInterface(typeB).AsExtendedFloat(objB);
     return CBORObject.FromObject(e1.Multiply(e2));
       } else {
     EInteger b1 = CBORObject.GetNumberInterface(typeA).AsEInteger(objA);
     EInteger b2 = CBORObject.GetNumberInterface(typeB).AsEInteger(objB);
     return CBORObject.FromObject(b1 * (EInteger)b2);
       }
 }
Example #25
0
        protected override void DoGet(CoapExchange exchange)
        {
#if true
            exchange.Respond(StatusCode.Content, _now.ToString(), MediaType.TextPlain);
#else
            Request request = exchange.Request;

            IEnumerable <Option> options = request.GetOptions(OptionType.Accept);
            int  useAccept   = MediaType.Undefined;
            bool acceptFound = false;

            foreach (var acccept in options)
            {
                switch (acccept.IntValue)
                {
                case MediaType.TextPlain:
                case MediaType.ApplicationCbor:
                    useAccept = acccept.IntValue;
                    break;

                default:
                    acceptFound = true;
                    break;
                }

                if (useAccept != MediaType.Undefined)
                {
                    break;
                }
            }

            if (useAccept == MediaType.Undefined)
            {
                if (acceptFound)
                {
                    exchange.Respond(StatusCode.UnsupportedMediaType);
                    return;
                }
                useAccept = MediaType.TextPlain;
            }

            Response response = Response.CreateResponse(request, StatusCode.Content);

            switch (useAccept)
            {
            case MediaType.TextPlain:
                string x = request.GetParameter("format");
                if (String.IsNullOrEmpty(x))
                {
                    response.PayloadString = _now.ToShortTimeString();
                }
                else
                {
                    response.PayloadString = _now.ToString(x);
                }
                request.ContentType = useAccept;
                break;

            case MediaType.ApplicationCbor:
                CBORObject obj = CBORObject.FromObject(_now);
                request.Payload     = obj.EncodeToBytes();
                request.ContentType = useAccept;
                break;
            }

            exchange.Respond(response);
#endif
        }
Example #26
0
        public CBORObject ReadForFirstByte(
  int firstbyte,
  CBORTypeFilter filter)
        {
            if (this.depth > 500) {
            throw new CBORException("Too deeply nested");
              }
              if (firstbyte < 0) {
            throw new CBORException("Premature end of data");
              }
              if (firstbyte == 0xff) {
            throw new CBORException("Unexpected break code encountered");
              }
              int type = (firstbyte >> 5) & 0x07;
              int additional = firstbyte & 0x1f;
              int expectedLength = CBORObject.GetExpectedLength(firstbyte);
              // Data checks
              if (expectedLength == -1) {
            // if the head byte is invalid
            throw new CBORException("Unexpected data encountered");
              }
              if (filter != null) {
            // Check for valid major types if asked
            if (!filter.MajorTypeMatches(type)) {
              throw new CBORException("Unexpected data type encountered");
            }
            if (firstbyte >= 0xe0 && firstbyte <= 0xff && firstbyte != 0xf9 &&
            firstbyte != 0xfa && firstbyte != 0xfb) {
              if (!filter.NonFPSimpleValueAllowed()) {
            throw new CBORException("Unexpected data type encountered");
              }
            }
              }
              // Check if this represents a fixed object
              CBORObject fixedObject = CBORObject.GetFixedObject(firstbyte);
              if (fixedObject != null) {
            return fixedObject;
              }
              // Read fixed-length data
              byte[] data = null;
              if (expectedLength != 0) {
            data = new byte[expectedLength];
            // include the first byte because GetFixedLengthObject
            // will assume it exists for some head bytes
            data[0] = unchecked((byte)firstbyte);
            if (expectedLength > 1 &&
            this.stream.Read(data, 1, expectedLength - 1) != expectedLength
            - 1) {
              throw new CBORException("Premature end of data");
            }
            CBORObject cbor = CBORObject.GetFixedLengthObject(firstbyte, data);
            if (this.stringRefs != null && (type == 2 || type == 3)) {
              this.stringRefs.AddStringIfNeeded(cbor, expectedLength - 1);
            }
            if (this.addSharedRef && (type == 4 || type == 5)) {
              this.sharedRefs.AddObject(cbor);
            }
            return cbor;
              }
              var uadditional = (long)additional;
              EInteger bigintAdditional = EInteger.Zero;
              var hasBigAdditional = false;
              data = new byte[8];
              var lowAdditional = 0;
              switch (firstbyte & 0x1f) {
            case 24: {
            int tmp = this.stream.ReadByte();
            if (tmp < 0) {
              throw new CBORException("Premature end of data");
            }
            lowAdditional = tmp;
            uadditional = lowAdditional;
            break;
              }
            case 25: {
            if (this.stream.Read(data, 0, 2) != 2) {
              throw new CBORException("Premature end of data");
            }
            lowAdditional = ((int)(data[0] & (int)0xff)) << 8;
            lowAdditional |= (int)(data[1] & (int)0xff);
            uadditional = lowAdditional;
            break;
              }
            case 26: {
            if (this.stream.Read(data, 0, 4) != 4) {
              throw new CBORException("Premature end of data");
            }
            uadditional = ((long)(data[0] & (long)0xff)) << 24;
            uadditional |= ((long)(data[1] & (long)0xff)) << 16;
            uadditional |= ((long)(data[2] & (long)0xff)) << 8;
            uadditional |= (long)(data[3] & (long)0xff);
            break;
              }
            case 27: {
            if (this.stream.Read(data, 0, 8) != 8) {
              throw new CBORException("Premature end of data");
            }
            if ((((int)data[0]) & 0x80) != 0) {
              // Won't fit in a signed 64-bit number
              var uabytes = new byte[9];
              uabytes[0] = data[7];
              uabytes[1] = data[6];
              uabytes[2] = data[5];
              uabytes[3] = data[4];
              uabytes[4] = data[3];
              uabytes[5] = data[2];
              uabytes[6] = data[1];
              uabytes[7] = data[0];
              uabytes[8] = 0;
              hasBigAdditional = true;
              bigintAdditional = EInteger.FromBytes(uabytes, true);
            } else {
              uadditional = ((long)(data[0] & (long)0xff)) << 56;
              uadditional |= ((long)(data[1] & (long)0xff)) << 48;
              uadditional |= ((long)(data[2] & (long)0xff)) << 40;
              uadditional |= ((long)(data[3] & (long)0xff)) << 32;
              uadditional |= ((long)(data[4] & (long)0xff)) << 24;
              uadditional |= ((long)(data[5] & (long)0xff)) << 16;
              uadditional |= ((long)(data[6] & (long)0xff)) << 8;
              uadditional |= (long)(data[7] & (long)0xff);
            }
            break;
              }
              }
              // The following doesn't check for major types 0 and 1,
              // since all of them are fixed-length types and are
              // handled in the call to GetFixedLengthObject.
              if (type == 2) {  // Byte string
            if (additional == 31) {
              // Streaming byte string
              using (var ms = new MemoryStream()) {
            // Requires same type as this one
            while (true) {
              int nextByte = this.stream.ReadByte();
              if (nextByte == 0xff) {
                // break if the "break" code was read
                break;
              }
              long len = ReadDataLength(this.stream, nextByte, 2);
              if ((len >> 63) != 0 || len > Int32.MaxValue) {
                throw new CBORException("Length" + ToUnsignedBigInteger(len) +
                  " is bigger than supported ");
              }
              if (nextByte != 0x40) {  // NOTE: 0x40 means the empty byte string
                ReadByteData(this.stream, len, ms);
              }
            }
            if (ms.Position > Int32.MaxValue) {
              throw new
              CBORException("Length of bytes to be streamed is bigger than supported ");
            }
            data = ms.ToArray();
            return new CBORObject(
              CBORObject.CBORObjectTypeByteString,
              data);
              }
            } else {
              if (hasBigAdditional) {
            throw new CBORException("Length of " +
              CBORUtilities.BigIntToString(bigintAdditional) + " is bigger than supported");
              }
              if (uadditional > Int32.MaxValue) {
            throw new CBORException("Length of " +
              CBORUtilities.LongToString(uadditional) +
              " is bigger than supported");
              }
              data = ReadByteData(this.stream, uadditional, null);
              var cbor = new CBORObject(CBORObject.CBORObjectTypeByteString, data);
              if (this.stringRefs != null) {
            int hint = (uadditional > Int32.MaxValue || hasBigAdditional) ?
            Int32.MaxValue : (int)uadditional;
            this.stringRefs.AddStringIfNeeded(cbor, hint);
              }
              return cbor;
            }
              }
              if (type == 3) {  // Text string
            if (additional == 31) {
              // Streaming text string
              var builder = new StringBuilder();
              while (true) {
            int nextByte = this.stream.ReadByte();
            if (nextByte == 0xff) {
              // break if the "break" code was read
              break;
            }
            long len = ReadDataLength(this.stream, nextByte, 3);
            if ((len >> 63) != 0 || len > Int32.MaxValue) {
              throw new CBORException("Length" + ToUnsignedBigInteger(len) +
                " is bigger than supported");
            }
            if (nextByte != 0x60) {  // NOTE: 0x60 means the empty string
              if (PropertyMap.ExceedsKnownLength(this.stream, len)) {
                // TODO: Remove following line in version 3.0
                PropertyMap.SkipStreamToEnd(this.stream);
                throw new CBORException("Premature end of data");
              }
              switch (
              DataUtilities.ReadUtf8(
              this.stream,
              (int)len,
              builder,
              false)) {
                case -1:
                  throw new CBORException("Invalid UTF-8");
                case -2:
                  throw new CBORException("Premature end of data");
              }
            }
              }
              return new CBORObject(
            CBORObject.CBORObjectTypeTextString,
            builder.ToString());
            } else {
              if (hasBigAdditional) {
            throw new CBORException("Length of " +
              CBORUtilities.BigIntToString(bigintAdditional) + " is bigger than supported");
              }
              if (uadditional > Int32.MaxValue) {
            throw new CBORException("Length of " +
              CBORUtilities.LongToString(uadditional) +
              " is bigger than supported");
              }
              if (PropertyMap.ExceedsKnownLength(this.stream, uadditional)) {
            // TODO: Remove following line in version 3.0
            PropertyMap.SkipStreamToEnd(this.stream);
            throw new CBORException("Premature end of data");
              }
              var builder = new StringBuilder();
              switch (
              DataUtilities.ReadUtf8(
              this.stream,
              (int)uadditional,
              builder,
              false)) {
            case -1:
              throw new CBORException("Invalid UTF-8");
            case -2:
              throw new CBORException("Premature end of data");
              }
              var cbor = new CBORObject(
              CBORObject.CBORObjectTypeTextString,
              builder.ToString());
              if (this.stringRefs != null) {
            int hint = (uadditional > Int32.MaxValue || hasBigAdditional) ?
            Int32.MaxValue : (int)uadditional;
            this.stringRefs.AddStringIfNeeded(cbor, hint);
              }
              return cbor;
            }
              }
              if (type == 4) {  // Array
            CBORObject cbor = CBORObject.NewArray();
            if (this.addSharedRef) {
              this.sharedRefs.AddObject(cbor);
              this.addSharedRef = false;
            }
            if (additional == 31) {
              var vtindex = 0;
              // Indefinite-length array
              while (true) {
            int headByte = this.stream.ReadByte();
            if (headByte < 0) {
              throw new CBORException("Premature end of data");
            }
            if (headByte == 0xff) {
              // Break code was read
              break;
            }
            if (filter != null && !filter.ArrayIndexAllowed(vtindex)) {
              throw new CBORException("Array is too long");
            }
            ++this.depth;
            CBORObject o = this.ReadForFirstByte(
              headByte,
              filter == null ? null : filter.GetSubFilter(vtindex));
            --this.depth;
            cbor.Add(o);
            ++vtindex;
              }
              return cbor;
            }
            if (hasBigAdditional) {
              throw new CBORException("Length of " +
              CBORUtilities.BigIntToString(bigintAdditional) + " is bigger than supported");
            }
            if (uadditional > Int32.MaxValue) {
              throw new CBORException("Length of " +
            CBORUtilities.LongToString(uadditional) +
            " is bigger than supported");
            }
            if (filter != null && !filter.ArrayLengthMatches(uadditional)) {
              throw new CBORException("Array is too long");
            }
            if (PropertyMap.ExceedsKnownLength(this.stream, uadditional)) {
              // TODO: Remove following line in version 3.0
              PropertyMap.SkipStreamToEnd(this.stream);
              throw new CBORException("Remaining data too small for array length");
            }
            ++this.depth;
            for (long i = 0; i < uadditional; ++i) {
              cbor.Add(
            this.Read(filter == null ? null : filter.GetSubFilter(i)));
            }
            --this.depth;
            return cbor;
              }
              if (type == 5) {  // Map, type 5
            CBORObject cbor = CBORObject.NewMap();
            if (this.addSharedRef) {
              this.sharedRefs.AddObject(cbor);
              this.addSharedRef = false;
            }
            if (additional == 31) {
              // Indefinite-length map
              while (true) {
            int headByte = this.stream.ReadByte();
            if (headByte < 0) {
              throw new CBORException("Premature end of data");
            }
            if (headByte == 0xff) {
              // Break code was read
              break;
            }
            ++this.depth;
            CBORObject key = this.ReadForFirstByte(headByte, null);
            CBORObject value = this.Read(null);
            --this.depth;
            if (this.policy == CBORDuplicatePolicy.Disallow) {
              if (cbor.ContainsKey(key)) {
                throw new CBORException("Duplicate key already exists: " + key);
              }
            }
            cbor[key] = value;
              }
              return cbor;
            }
            if (hasBigAdditional) {
              throw new CBORException("Length of " +
              CBORUtilities.BigIntToString(bigintAdditional) + " is bigger than supported");
            }
            if (uadditional > Int32.MaxValue) {
              throw new CBORException("Length of " +
            CBORUtilities.LongToString(uadditional) +
            " is bigger than supported");
            }
            if (PropertyMap.ExceedsKnownLength(this.stream, uadditional)) {
            // TODO: Remove following line in version 3.0
            PropertyMap.SkipStreamToEnd(this.stream);
            throw new CBORException("Remaining data too small for map length");
            }
            for (long i = 0; i < uadditional; ++i) {
              ++this.depth;
              CBORObject key = this.Read(null);
              CBORObject value = this.Read(null);
              --this.depth;
              if (this.policy == CBORDuplicatePolicy.Disallow) {
            if (cbor.ContainsKey(key)) {
              throw new CBORException("Duplicate key already exists: " + key);
            }
              }
              cbor[key] = value;
            }
            return cbor;
              }
              if (type == 6) {  // Tagged item
            ICBORTag taginfo = null;
            var haveFirstByte = false;
            var newFirstByte = -1;
            var unnestedObject = false;
            CBORObject tagObject = null;
            if (!hasBigAdditional) {
              if (filter != null && !filter.TagAllowed(uadditional)) {
            throw new CBORException("Unexpected tag encountered: " +
                 uadditional);
              }
              int uad = uadditional >= 257 ? 257 : (uadditional < 0 ? 0 :
            (int)uadditional);
              switch (uad) {
            case 256:
              // Tag 256: String namespace
              this.stringRefs = this.stringRefs ?? (new StringRefs());
              this.stringRefs.Push();
              break;
            case 25:
              // String reference
              if (this.stringRefs == null) {
                throw new CBORException("No stringref namespace");
              }

              break;
            case 28:
              // Shareable object
              newFirstByte = this.stream.ReadByte();
              if (newFirstByte < 0) {
                throw new CBORException("Premature end of data");
              }
              if (newFirstByte >= 0x80 && newFirstByte < 0xc0) {
                // Major types 4 and 5 (array and map)
                this.addSharedRef = true;
              } else if ((newFirstByte & 0xe0) == 0xc0) {
                // Major type 6 (tagged object)
                tagObject = new CBORObject(CBORObject.Undefined, 28, 0);
                this.sharedRefs.AddObject(tagObject);
              } else {
                // All other major types
                unnestedObject = true;
              }
              haveFirstByte = true;
              break;
              }

              taginfo = CBORObject.FindTagConverterLong(uadditional);
            } else {
              if (filter != null && !filter.TagAllowed(bigintAdditional)) {
            throw new CBORException("Unexpected tag encountered: " +
                 uadditional);
              }
              taginfo = CBORObject.FindTagConverter(bigintAdditional);
            }
            ++this.depth;
            CBORObject o = haveFirstByte ? this.ReadForFirstByte(
              newFirstByte,
              taginfo == null ? null : taginfo.GetTypeFilter()) :
            this.Read(taginfo == null ? null : taginfo.GetTypeFilter());
            --this.depth;
            if (hasBigAdditional) {
              return CBORObject.FromObjectAndTag(o, bigintAdditional);
            }
            if (uadditional < 65536) {
              int uaddl = uadditional >= 257 ? 257 : (uadditional < 0 ? 0 :
            (int)uadditional);
              switch (uaddl) {
            case 256:
              // string tag
              this.stringRefs.Pop();
              break;
            case 25:
              // stringref tag
              return this.stringRefs.GetString(o.AsEInteger());
            case 28:
              // shareable object
              this.addSharedRef = false;
              if (unnestedObject) {
                this.sharedRefs.AddObject(o);
              }
              if (tagObject != null) {
              // TODO: Somehow implement sharable objects
              // without relying on Redefine method
              // tagObject.Redefine(o);
              // o = tagObject;
              }

              break;
            case 29:
              // shared object reference
              return this.sharedRefs.GetObject(o.AsEInteger());
              }

              return CBORObject.FromObjectAndTag(
            o,
            (int)uadditional);
            }
            return CBORObject.FromObjectAndTag(
              o,
              (EInteger)uadditional);
              }
              throw new CBORException("Unexpected data encountered");
        }
Example #27
0
        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);
        }
Example #28
0
 private static void TestWriteToJSON(CBORObject obj)
 {
     CBORObject objA = null;
       string jsonString = String.Empty;
       using (var ms = new MemoryStream()) {
     try {
       obj.WriteJSONTo(ms);
       jsonString = DataUtilities.GetUtf8String(
     ms.ToArray(),
     true);
       objA = CBORObject.FromJSONString(jsonString);
     } catch (CBORException ex) {
       throw new InvalidOperationException(jsonString, ex);
     } catch (IOException ex) {
       throw new InvalidOperationException(String.Empty, ex);
     }
       }
       CBORObject objB = CBORObject.FromJSONString(obj.ToJSONString());
       if (!objA.Equals(objB)) {
     Console.WriteLine(objA);
     Console.WriteLine(objB);
     Assert.Fail("WriteJSONTo gives different results from ToJSONString");
       }
 }
Example #29
0
        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));
            }
        }
Example #30
0
 public FidoU2f(CBORObject attStmt, byte[] authenticatorData, byte[] clientDataHash) : base(attStmt, authenticatorData, clientDataHash)
 {
 }
Example #31
0
        public async Task <CTAPResponseAttestation> SendAndResponse(DevParam devParam)
        {
            // check
            {
                if (RpId == null)
                {
                    RpId = "";
                }
                if (RpName == null)
                {
                    RpName = "";
                }
                if (UserId == null)
                {
                    UserId = "";
                }
                if (UserName == null)
                {
                    UserName = "";
                }
                if (UserDisplayName == null)
                {
                    UserDisplayName = "";
                }
                if (ClientDataHash == null)
                {
                    ClientDataHash = new byte[0];
                }
            }

            var cbor = CBORObject.NewMap();

            // 0x01 : clientDataHash
            cbor.Add(0x01, ClientDataHash);

            // 0x02 : rp
            cbor.Add(0x02, CBORObject.NewMap().Add("id", RpId).Add("name", RpName));

            // 0x03 : user
            {
                var user = CBORObject.NewMap();
                if (UserId_bytearray != null)
                {
                    user.Add("id", UserId_bytearray);
                }
                else
                {
                    user.Add("id", Encoding.ASCII.GetBytes(UserId));
                }

                if (string.IsNullOrEmpty(UserName))
                {
                    user.Add("name", " ");
                }
                else
                {
                    user.Add("name", UserName);
                }

                if (string.IsNullOrEmpty(UserDisplayName))
                {
                    user.Add("displayName", " ");
                }
                else
                {
                    user.Add("displayName", UserDisplayName);
                }

                cbor.Add(0x03, user);
            }

            // 0x04 : pubKeyCredParams
            {
                var pubKeyCredParams = CBORObject.NewMap();
                pubKeyCredParams.Add("alg", -7);
                pubKeyCredParams.Add("type", "public-key");
                cbor.Add(0x04, CBORObject.NewArray().Add(pubKeyCredParams));
            }

            // 0x07 : options
            {
                var opt = CBORObject.NewMap();
                opt.Add("rk", Option_rk);
                opt.Add("uv", Option_uv);
                cbor.Add(0x07, opt);
            }

            if (PinAuth != null)
            {
                // pinAuth(0x08)
                cbor.Add(0x08, PinAuth);

                // 0x09:pinProtocol
                cbor.Add(0x09, 1);
            }

            var resi = await sendCommandandResponse(devParam, 0x01, cbor, this.TimeoutMs);

            var response = new CTAPResponseAttestation(resi);

            response.CommandDataJson = this.payloadJson;
            return(response);
        }
Example #32
0
        public IActionResult RegisterCallback([FromBody] CredentialsModel model)
        {
            // 1. Let JSONtext be the result of running UTF-8 decode on the value of response.clientDataJSON
            var jsonText = Encoding.UTF8.GetString(Base64Url.Decode(model.Response.ClientDataJson));

            // 2. Let C, the client data claimed as collected during the credential creation, be the result of running an implementation-specific JSON parser on JSONtext
            var c = JsonConvert.DeserializeObject <ClientData>(jsonText);

            // 3. Verify that the value of C.type is webauthn.create
            if (c.Type != "webauthn.create")
            {
                throw new Exception("Incorrect client data type");
            }

            // 4. Verify that the value of C.challenge matches the challenge that was sent to the authenticator in the create() call.
            var data      = tempData.LoadTempData(HttpContext);
            var challenge = (string)data["challenge"];

            if (!Base64Url.Decode(c.Challenge).SequenceEqual(Convert.FromBase64String(challenge)))
            {
                throw new Exception("Incorrect challenge");
            }

            // 5. Verify that the value of C.origin matches the Relying Party's origin.
            if (c.Origin != "http://localhost:5000")
            {
                throw new Exception("Incorrect origin");
            }

            // 6. Verify that the value of C.tokenBinding.status matches the state of Token Binding for the TLS connection over which the assertion was obtained.
            // If Token Binding was used on that TLS connection, also verify that C.tokenBinding.id matches the base64url encoding of the Token Binding ID for the connection.
            // TODO: Token binding (once out of draft)

            // 7. Compute the hash of response.clientDataJSON using SHA-256.
            var hasher = new SHA256Managed();
            var hashedClientDataJson = hasher.ComputeHash(Base64Url.Decode(model.Response.ClientDataJson)); // Why???

            // 8. Perform CBOR decoding on the attestationObject field of the AuthenticatorAttestationResponse structure
            // to obtain the attestation statement format fmt, the authenticator data authData, and the attestation statement attStmt.
            CBORObject cbor;

            using (var stream = new MemoryStream(Base64Url.Decode(model.Response.AttestationObject)))
                cbor = CBORObject.Read(stream);

            var authData = cbor["authData"].GetByteString();
            var fmt      = cbor["fmt"].AsString();

            var span     = authData.AsSpan();
            var rpIdHash = span.Slice(0, 32); span = span.Slice(32);

            var flags       = new BitArray(span.Slice(0, 1).ToArray()); span = span.Slice(1);
            var userPresent = flags[0];            // (UP)
            // Bit 1 reserved for future use (RFU1)
            var userVerified = flags[2];           // (UV)
            // Bits 3-5 reserved for future use (RFU2)
            var attestedCredentialData = flags[6]; // (AT) "Indicates whether the authenticator added attested credential data"
            var extensionDataIncluded  = flags[7]; // (ED)

            // Signature counter (4 bytes, big-endian unint32)
            var counterBuf = span.Slice(0, 4); span = span.Slice(4);
            var counter    = BitConverter.ToUInt32(counterBuf); // https://www.w3.org/TR/webauthn/#signature-counter

            // Attested Credential Data
            // cred data - AAGUID (16 bytes)
            var aaguid = span.Slice(0, 16); span = span.Slice(16);

            // cred data - L (2 bytes, big-endian uint16)
            var credIdLenBuf = span.Slice(0, 2); span = span.Slice(2);

            credIdLenBuf.Reverse();
            var credentialIdLength = BitConverter.ToUInt16(credIdLenBuf);

            // cred data - Credential ID (L bytes)
            var credentialId = span.Slice(0, credentialIdLength); span = span.Slice(credentialIdLength);

            // 9. Verify that the RP ID hash in authData is indeed the SHA-256 hash of the RP ID expected by the RP.
            var computedRpIdHash = hasher.ComputeHash(Encoding.UTF8.GetBytes(RelyingPartyId));

            if (!rpIdHash.SequenceEqual(computedRpIdHash))
            {
                throw new Exception("Incorrect RP ID");
            }

            // 10. If user verification is required for this registration, verify that the User Verified bit of the flags in authData is set.
            // TODO: Handle user verificaton required

            // 11. If user verification is not required for this registration, verify that the User Present bit of the flags in authData is set.
            if (userPresent == false)
            {
                throw new Exception("User not present");
            }

            // 12. Verify that the values of the client extension outputs in clientExtensionResults
            // TODO: Handle extension results

            // 13. Determine the attestation statement format by performing a USASCII case-sensitive match on fmt against the set of supported WebAuthn Attestation Statement Format Identifier values
            // TODO: Handle accepted fmt values

            // 14. Verify that attStmt is a correct attestation statement, conveying a valid attestation signature, by using the attestation statement format fmt’s verification procedure given attStmt, authData and the hash of the serialized client data computed in step 7.
            // TODO: Handle fmt specific attestation statement

            // 15. If validation is successful, obtain a list of acceptable trust anchors (attestation root certificates or ECDAA-Issuer public keys) for that attestation type and attestation statement format fmt, from a trusted source or from policy.
            // For example, the FIDO Metadata Service [FIDOMetadataService] provides one way to obtain such information, using the aaguid in the attestedCredentialData in authData.
            // 16. Assess the attestation trustworthiness using the outputs of the verification procedure in step 14
            // TODO: Use of FIDO metadata service

            // 17. Check that the credentialId is not yet registered to any other user &
            var parsedCredentialId = Convert.ToBase64String(credentialId.ToArray());

            if (Users.Any(x => x.CredentialId == parsedCredentialId))
            {
                throw new Exception("Duplicate credential ID");
            }

            // 18. If the attestation statement attStmt verified successfully and is found to be trustworthy, then register the new credential
            var coseStruct = CBORObject.DecodeFromBytes(span.ToArray());
            var key        = JsonConvert.DeserializeObject <CredentialPublicKey>(coseStruct.ToJSONString());

            Users.Add(new User {
                Username = (string)data["username"], CredentialId = parsedCredentialId, PublicKey = key
            });

            return(Ok());
        }
Example #33
0
        static void RunCommand(string[] commands)
        {
            if (commands.Length == 0)
            {
                return;
            }



            switch (commands[0].ToUpper())
            {
            default:
                _dispatchTable.Execute(commands);
                break;


            case "SCRIPT":
                TextReader x = new StreamReader(commands[1]);
                RunScript(x);
                x.Dispose();
                break;



            case "COMMENT":
                break;

            case "EXIT":
                Environment.Exit(0);
                break;

            case "PAUSE":
                Console.ReadLine();
                break;

            case "TIMEOUT":
                break;

            case "LOG-LEVEL":
                if (commands.Length != 2)
                {
                    Console.WriteLine("Incorrect number of args");
                    return;
                }
                switch (commands[1].ToUpper())
                {
                case "INFO":
                    LogManager.Level = LogLevel.Info;
                    break;

                case "NONE":
                    LogManager.Level = LogLevel.None;
                    break;

                case "FATAL":
                    LogManager.Level = LogLevel.Fatal;
                    break;

                default:
                    Console.WriteLine("Unknown level");
                    break;
                }
                break;

            case "LOG-TO":
                break;

            case "OPTION":
                OptionType typ = GetOptionType(commands[1]);
                switch (typ)
                {
                case OptionType.ContentFormat:
                case OptionType.Accept:
                    if (commands.Length == 2)
                    {
                        _Options.Add(Option.Create(typ));
                    }
                    else
                    {
                        for (int i = 2; i < commands.Length; i++)
                        {
                            int val = MediaType.ApplicationLinkFormat;
                            if (int.TryParse(commands[i], out val))
                            {
                                _Options.Add(Option.Create(typ, val));
                            }
                            else
                            {
                                Console.WriteLine($"Bad option value '{commands[i]}'");
                            }
                        }
                    }
                    break;

                case OptionType.Unknown:
                    Console.WriteLine("Unrecognized type string");
                    return;

                default:
                    if (commands.Length == 2)
                    {
                        _Options.Add(Option.Create(typ));
                    }
                    else
                    {
                        for (int i = 2; i < commands.Length; i++)
                        {
                            _Options.Add(Option.Create(typ, commands[i]));
                        }
                    }
                    break;
                }
                break;

            case "CLEAR-OPTION":
                if (commands.Length == 1)
                {
                    _Options.Clear();
                    return;
                }
                typ = GetOptionType(commands[1]);
                List <Option> del = new List <Option>();
                foreach (Option op in _Options)
                {
                    if (op.Type == typ)
                    {
                        del.Add(op);
                    }
                }
                foreach (Option op in del)
                {
                    _Options.Remove(op);
                }
                break;

            case "BODY":
                if (commands.Length == 1)
                {
                    break;
                }
                byte[] b = File.ReadAllBytes(commands[1]);
                Body = b;
                break;



#if false
            case "EDHOC":
                RunEdhoc(commands);
                break;
#endif

            case "ADD-OSCOAP":
                if (commands.Length != 3)
                {
                    Console.WriteLine("Incorrect number of arguments: " + commands.Length);
                    return;
                }

                CBORObject      cbor = CBORDiagnostics.Parse(commands[2]);
                SecurityContext ctx  = SecurityContext.DeriveContext(
                    cbor[CoseKeyParameterKeys.Octet_k].GetByteString(),
                    cbor[CBORObject.FromObject("RecipID")].GetByteString(),
                    cbor[CBORObject.FromObject("SenderID")].GetByteString(), null,
                    cbor[CoseKeyKeys.Algorithm]);

                _OscopKeys.Add(commands[1], ctx);

                break;

#if DEV_VERSION
            case "ADD-OSCOAP-GROUP":
                if (commands.Length != 3)
                {
                    Console.WriteLine("Incorrect number of arguments: " + commands.Length);
                    return;
                }
                cbor = CBORDiagnostics.Parse(commands[2]);
                ctx  = SecurityContext.DeriveGroupContext(cbor[CoseKeyParameterKeys.Octet_k].GetByteString(), cbor[CoseKeyKeys.KeyIdentifier].GetByteString(),
                                                          cbor[CBORObject.FromObject("sender")][CBORObject.FromObject("ID")].GetByteString(), null, null, cbor[CoseKeyKeys.Algorithm]);
                ctx.Sender.SigningKey = new OneKey(cbor["sender"]["sign"]);
                foreach (CBORObject recipient in cbor[CBORObject.FromObject("recipients")].Values)
                {
                    ctx.AddRecipient(recipient[CBORObject.FromObject("ID")].GetByteString(), new OneKey(recipient["sign"]));
                }

                _OscopKeys.Add(commands[1], ctx);
                break;
#endif

            case "USE-OSCOAP":
                if (commands.Length != 2)
                {
                    Console.WriteLine("Incorrect number of arguments: " + commands.Length);
                    return;
                }

                if (commands[1] == "NONE")
                {
                    _CurrentOscoap = null;
                    return;
                }

                if (!_OscopKeys.ContainsKey(commands[1]))
                {
                    Console.WriteLine($"OSCOAP Key {commands[1]} is not defined");
                    return;
                }

                _CurrentOscoap = _OscopKeys[commands[1]];
                break;

            case "OSCOAP-TEST":
                OscoapTests.RunTest(Int32.Parse(commands[1]));
                break;

            case "OSCOAP-PIV":
                _CurrentOscoap.Sender.SequenceNumber = Int32.Parse(commands[1]);
                break;

            case "EDHOC-ADD-SERVER-KEY":
                if (commands.Length != 2)
                {
                    Console.WriteLine("Incorrect number of arguments: " + commands.Length);
                    return;
                }

                cbor = CBORDiagnostics.Parse(commands[2]);
                _EdhocServerKeys.AddKey(new OneKey(cbor));
                break;

            case "EDHOC-ADD-USER-KEY":
                if (commands.Length != 3)
                {
                    Console.WriteLine("Incorrect number of arguments: " + commands.Length);
                    return;
                }

                cbor = CBORDiagnostics.Parse(commands[2]);
                _EdhocValidateKeys.Add(commands[1], new OneKey(cbor));
                break;
            }
        }
Example #34
0
        public override void Verify()
        {
            // verify that aaguid is 16 empty bytes (note: required by fido2 conformance testing, could not find this in spec?)
            if (0 != AuthData.AttestedCredentialData.AaGuid.CompareTo(Guid.Empty))
            {
                throw new VerificationException("Aaguid was not empty parsing fido-u2f atttestation statement");
            }

            // 1. Verify that attStmt is valid CBOR conforming to the syntax defined above and perform CBOR decoding on it to extract the contained fields.
            if (null == X5c || CBORType.Array != X5c.Type || X5c.Count != 1)
            {
                throw new VerificationException("Malformed x5c in fido - u2f attestation");
            }

            // 2a. the attestation certificate attestnCert MUST be the first element in the array
            if (null == X5c.Values || 0 == X5c.Values.Count ||
                CBORType.ByteString != X5c.Values.First().Type ||
                0 == X5c.Values.First().GetByteString().Length)
            {
                throw new VerificationException("Malformed x5c in fido-u2f attestation");
            }

            var cert = new X509Certificate2(X5c.Values.First().GetByteString());

            // TODO : Check why this variable isn't used. Remove it or use it.

            var u2ftransports = U2FTransportsFromAttnCert(cert.Extensions);

            // 2b. If certificate public key is not an Elliptic Curve (EC) public key over the P-256 curve, terminate this algorithm and return an appropriate error
            var pubKey    = cert.GetECDsaPublicKey();
            var keyParams = pubKey.ExportParameters(false);

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                if (!keyParams.Curve.Oid.FriendlyName.Equals(ECCurve.NamedCurves.nistP256.Oid.FriendlyName))
                {
                    throw new VerificationException("Attestation certificate public key is not an Elliptic Curve (EC) public key over the P-256 curve");
                }
            }
            else
            {
                if (!keyParams.Curve.Oid.Value.Equals(ECCurve.NamedCurves.nistP256.Oid.Value))
                {
                    throw new VerificationException("Attestation certificate public key is not an Elliptic Curve (EC) public key over the P-256 curve");
                }
            }
            // 3. Extract the claimed rpIdHash from authenticatorData, and the claimed credentialId and credentialPublicKey from authenticatorData
            // see rpIdHash, credentialId, and credentialPublicKey variables

            // 4. Convert the COSE_KEY formatted credentialPublicKey (see Section 7 of [RFC8152]) to CTAP1/U2F public Key format
            var x = CredentialPublicKey[CBORObject.FromObject(COSE.KeyTypeParameter.X)].GetByteString();
            var y = CredentialPublicKey[CBORObject.FromObject(COSE.KeyTypeParameter.Y)].GetByteString();
            var publicKeyU2F = new byte[1] {
                0x4
            }.Concat(x).Concat(y).ToArray();

            // 5. Let verificationData be the concatenation of (0x00 || rpIdHash || clientDataHash || credentialId || publicKeyU2F)
            var verificationData = new byte[1] {
                0x00
            };

            verificationData = verificationData
                               .Concat(AuthData.RpIdHash)
                               .Concat(clientDataHash)
                               .Concat(AuthData.AttestedCredentialData.CredentialID)
                               .Concat(publicKeyU2F.ToArray())
                               .ToArray();

            // 6. Verify the sig using verificationData and certificate public key
            if (null == Sig || CBORType.ByteString != Sig.Type || 0 == Sig.GetByteString().Length)
            {
                throw new VerificationException("Invalid fido-u2f attestation signature");
            }

            byte[] ecsig;
            try
            {
                ecsig = CryptoUtils.SigFromEcDsaSig(Sig.GetByteString(), pubKey.KeySize);
            }
            catch (Exception ex)
            {
                throw new VerificationException("Failed to decode fido-u2f attestation signature from ASN.1 encoded form", ex);
            }

            var coseAlg = CredentialPublicKey[CBORObject.FromObject(COSE.KeyCommonParameter.Alg)].AsInt32();
            var hashAlg = CryptoUtils.HashAlgFromCOSEAlg(coseAlg);

            if (true != pubKey.VerifyData(verificationData, ecsig, hashAlg))
            {
                throw new VerificationException("Invalid fido-u2f attestation signature");
            }

            if (_requireValidAttestationRoot)
            {
                // 7. Optionally, inspect x5c and consult externally provided knowledge to determine whether attStmt conveys a Basic or AttCA attestation
                var trustPath = X5c.Values
                                .Select(z => new X509Certificate2(z.GetByteString()))
                                .ToArray();

                var aaguid = AaguidFromAttnCertExts(cert.Extensions);

                if (null != _metadataService && null != aaguid)
                {
                    var guidAaguid = AttestedCredentialData.FromBigEndian(aaguid);
                    var entry      = _metadataService.GetEntry(guidAaguid);

                    if (null != entry && null != entry.MetadataStatement)
                    {
                        var attestationRootCertificates = entry.MetadataStatement.AttestationRootCertificates
                                                          .Select(z => new X509Certificate2(Convert.FromBase64String(z)))
                                                          .ToArray();

                        if (false == ValidateTrustChain(trustPath, attestationRootCertificates))
                        {
                            throw new VerificationException("Invalid certificate chain in U2F attestation");
                        }
                    }
                }
            }
        }
Example #35
0
        public static void RunCoapCommand(string[] args)
        {
            int    index   = 0;
            string method  = null;
            Uri    uri     = null;
            string payload = null;

            foreach (string arg in args)
            {
                switch (index)
                {
                case 0:
                    method = arg.ToUpper();
                    break;

                case 1:
                    try {
                        if (Host != null)
                        {
                            uri = new Uri(Host, arg);
                        }
                        else
                        {
                            uri = new Uri(arg);
                        }
                    }
                    catch (Exception ex) {
                        Console.WriteLine("failed parsing URI: " + ex.Message);
                        return;
                    }
                    break;

                case 2:
                    payload = arg;
                    break;

                default:
                    Console.WriteLine("Unexpected argument: " + arg);
                    break;
                }
                index++;
            }

            if (method == null || uri == null)
            {
                Console.WriteLine("Requires method and uri");
                return;
            }

            Request request = NewRequest(method, uri);

            if (request == null)
            {
                Console.WriteLine("Unknown method: " + method);
                return;
            }

            request.Type = Con;
            uri          = request.URI;

            if (!AddEndPoint(request))
            {
                return;
            }

            if (payload != null)
            {
                int mt = MediaType.TextPlain;
                if (request.HasOption(OptionType.ContentFormat))
                {
                    mt = request.ContentFormat;
                }
                request.SetPayload(payload, mt);
            }


            try {
                request.Respond += delegate(Object sender, ResponseEventArgs e)
                {
                    Response response = e.Response;
                    if (response == null)
                    {
                        Console.WriteLine("Request timeout");
                    }
                    else
                    {
                        Console.WriteLine(Utils.ToString(response));
                        if (response.ContentFormat == MediaType.ApplicationCbor)
                        {
                            CBORObject o = CBORObject.DecodeFromBytes(response.Payload);
                            Console.WriteLine(o.ToString());
                        }
                        Console.WriteLine("Time (ms): " + response.RTT);

#if DO_ACE
                        if (response.StatusCode == StatusCode.Unauthorized && AceAuthzHandler != null)
                        {
                            AceAuthzHandler.Process(request, response);
                        }
#endif
                    }
                };
                request.Send();
                Thread.Sleep(1000);
            }
            catch (Exception ex) {
                Console.WriteLine("Failed executing request: " + ex.Message);
                Console.WriteLine(ex);
            }
        }
Example #36
0
 public static void Write(CBORObject obj, Stream stream)
 {
     if (obj == null)
     {
         throw new ArgumentNullException(nameof(obj));
     }
     if (obj.IsNumber)
     {
         if (stream == null)
         {
             throw new ArgumentNullException(nameof(stream));
         }
         stream.WriteByte(unchecked ((byte)((byte)0x69)));
         WriteUtf8(obj.ToObject(typeof(EInteger)).ToString(), stream);
         stream.WriteByte(unchecked ((byte)((byte)0x65)));
     }
     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);
         if (stream == null)
         {
             throw new ArgumentNullException(nameof(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;
             }
             if (stream == null)
             {
                 throw new ArgumentNullException(nameof(stream));
             }
             stream.WriteByte(unchecked ((byte)((byte)0x64)));
             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)0x65)));
         }
         else
         {
             if (stream == null)
             {
                 throw new ArgumentNullException(nameof(stream));
             }
             stream.WriteByte(unchecked ((byte)((byte)0x64)));
             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)0x65)));
         }
     }
     else if (obj.Type == CBORType.Array)
     {
         if (stream == null)
         {
             throw new ArgumentNullException(nameof(stream));
         }
         stream.WriteByte(unchecked ((byte)((byte)0x6c)));
         for (var i = 0; i < obj.Count; ++i)
         {
             Write(obj[i], stream);
         }
         stream.WriteByte(unchecked ((byte)((byte)0x65)));
     }
     else
     {
         string str    = obj.ToJSONString();
         long   length = DataUtilities.GetUtf8Length(str, false);
         if (length < 0)
         {
             throw new CBORException("invalid string");
         }
         WriteUtf8(LongToString(length), stream);
         if (stream == null)
         {
             throw new ArgumentNullException(nameof(stream));
         }
         stream.WriteByte(unchecked ((byte)((byte)':')));
         WriteUtf8(str, stream);
     }
 }
Example #37
0
 public void SetClaim(ClaimID claim, string value)
 {
     SetClaim(claim, CBORObject.FromObject(value));
 }
Example #38
0
 internal static void CompareDecimals(CBORObject o1, CBORObject o2)
 {
     int cmpDecFrac = TestCommon.CompareTestReciprocal(
     o1.AsEDecimal(),
     o2.AsEDecimal());
       int cmpCobj = TestCommon.CompareTestReciprocal(o1, o2);
       if (cmpDecFrac != cmpCobj) {
     Assert.AreEqual(
       cmpDecFrac,
       cmpCobj,
       TestCommon.ObjectMessages(o1, o2, "Compare: Results don't match"));
       }
       CBORTestCommon.AssertRoundTrip(o1);
       CBORTestCommon.AssertRoundTrip(o2);
 }
 public AndroidSafetyNet(CBORObject attStmt, byte[] authenticatorData, byte[] clientDataHash, int driftTolerance) : base(attStmt, authenticatorData, clientDataHash)
 {
     _driftTolerance = driftTolerance;
 }
Example #40
0
 private static void AssertWriteThrow(CBORObject cbor)
 {
     try {
     cbor.WriteTo(null);
     Assert.Fail("Should have failed");
       } catch (ArgumentNullException) {
     new Object();
       } catch (Exception ex) {
     Assert.Fail(ex.ToString());
     throw new InvalidOperationException(String.Empty, ex);
       }
       try {
     CBORObject.Write(cbor, null);
     Assert.Fail("Should have failed");
       } catch (ArgumentNullException) {
     new Object();
       } catch (Exception ex) {
     Assert.Fail(ex.ToString());
     throw new InvalidOperationException(String.Empty, ex);
       }
 }
Example #41
0
#pragma warning restore CA1801

        public CBORObject GetJSON(string name)
        {
            return(CBORObject.FromJSONString(
                       this.GetString(name)));
        }
Example #42
0
 public void AddObject(CBORObject obj)
 {
     this.sharedObjects.Add(obj);
 }
Example #43
0
 public CBORObject this[CBORObject name]
 {
     get { return(m_map[name]); }
 }
Example #44
0
 public static CBORObject Remainder(CBORObject a, CBORObject b)
 {
     if (a == null) {
     throw new ArgumentNullException("a");
       }
       if (b == null) {
     throw new ArgumentNullException("b");
       }
       if (a.Type != CBORType.Number) {
     throw new ArgumentException("a.Type (" + a.Type +
       ") is not equal to " + CBORType.Number);
       }
       if (b.Type != CBORType.Number) {
     throw new ArgumentException("b.Type (" + b.Type +
       ") is not equal to " + CBORType.Number);
       }
       object objA = a.ThisItem;
       object objB = b.ThisItem;
       int typeA = a.ItemType;
       int typeB = b.ItemType;
       if (typeA == CBORObject.CBORObjectTypeInteger && typeB ==
       CBORObject.CBORObjectTypeInteger) {
     var valueA = (long)objA;
     var valueB = (long)objB;
     return (valueA == Int64.MinValue && valueB == -1) ?
     CBORObject.FromObject(0) : CBORObject.FromObject(valueA % valueB);
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedRational ||
      typeB == CBORObject.CBORObjectTypeExtendedRational) {
     ERational e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
     ERational e2 =
     CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
     return CBORObject.FromObject(e1.Remainder(e2));
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedDecimal ||
      typeB == CBORObject.CBORObjectTypeExtendedDecimal) {
     EDecimal e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedDecimal(objA);
     EDecimal e2 =
     CBORObject.GetNumberInterface(typeB).AsExtendedDecimal(objB);
     return CBORObject.FromObject(e1.Remainder(e2, null));
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedFloat || typeB ==
       CBORObject.CBORObjectTypeExtendedFloat ||
        typeA == CBORObject.CBORObjectTypeDouble || typeB ==
        CBORObject.CBORObjectTypeDouble ||
        typeA == CBORObject.CBORObjectTypeSingle || typeB ==
        CBORObject.CBORObjectTypeSingle) {
     EFloat e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedFloat(objA);
     EFloat e2 = CBORObject.GetNumberInterface(typeB).AsExtendedFloat(objB);
     return CBORObject.FromObject(e1.Remainder(e2, null));
       } else {
     EInteger b1 = CBORObject.GetNumberInterface(typeA).AsEInteger(objA);
     EInteger b2 = CBORObject.GetNumberInterface(typeB).AsEInteger(objB);
     return CBORObject.FromObject(b1 % (EInteger)b2);
       }
 }
Example #45
0
 public byte[] AsBytes(CBORObject name)
 {
     return(m_map[name].GetByteString());
 }
Example #46
0
 public static CBORObject Divide(CBORObject a, CBORObject b)
 {
     if (a == null) {
     throw new ArgumentNullException("a");
       }
       if (b == null) {
     throw new ArgumentNullException("b");
       }
       if (a.Type != CBORType.Number) {
     throw new ArgumentException("a.Type (" + a.Type +
       ") is not equal to " + CBORType.Number);
       }
       if (b.Type != CBORType.Number) {
     throw new ArgumentException("b.Type (" + b.Type +
       ") is not equal to " + CBORType.Number);
       }
       object objA = a.ThisItem;
       object objB = b.ThisItem;
       int typeA = a.ItemType;
       int typeB = b.ItemType;
       if (typeA == CBORObject.CBORObjectTypeInteger && typeB ==
       CBORObject.CBORObjectTypeInteger) {
     var valueA = (long)objA;
     var valueB = (long)objB;
     if (valueB == 0) {
       return (valueA == 0) ? CBORObject.NaN : ((valueA < 0) ?
     CBORObject.NegativeInfinity : CBORObject.PositiveInfinity);
     }
     if (valueA == Int64.MinValue && valueB == -1) {
       return CBORObject.FromObject(valueA).Negate();
     }
     long quo = valueA / valueB;
     long rem = valueA - (quo * valueB);
     return (rem == 0) ? CBORObject.FromObject(quo) :
     CBORObject.FromObject(
       new ERational(
       (EInteger)valueA,
       (EInteger)valueB));
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedRational ||
      typeB == CBORObject.CBORObjectTypeExtendedRational) {
     ERational e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
     ERational e2 =
     CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
     return CBORObject.FromObject(e1.Divide(e2));
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedDecimal ||
      typeB == CBORObject.CBORObjectTypeExtendedDecimal) {
     EDecimal e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedDecimal(objA);
     EDecimal e2 =
     CBORObject.GetNumberInterface(typeB).AsExtendedDecimal(objB);
     if (e1.IsZero && e2.IsZero) {
       return CBORObject.NaN;
     }
     EDecimal eret = e1.Divide(e2, null);
     // If either operand is infinity or NaN, the result
     // is already exact. Likewise if the result is a finite number.
     if (!e1.IsFinite || !e2.IsFinite || eret.IsFinite) {
       return CBORObject.FromObject(eret);
     }
     ERational er1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
     ERational er2 =
     CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
     return CBORObject.FromObject(er1.Divide(er2));
       }
       if (typeA == CBORObject.CBORObjectTypeExtendedFloat || typeB ==
       CBORObject.CBORObjectTypeExtendedFloat ||
        typeA == CBORObject.CBORObjectTypeDouble || typeB ==
        CBORObject.CBORObjectTypeDouble ||
        typeA == CBORObject.CBORObjectTypeSingle || typeB ==
        CBORObject.CBORObjectTypeSingle) {
     EFloat e1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedFloat(objA);
     EFloat e2 = CBORObject.GetNumberInterface(typeB).AsExtendedFloat(objB);
     if (e1.IsZero && e2.IsZero) {
       return CBORObject.NaN;
     }
     EFloat eret = e1.Divide(e2, null);
     // If either operand is infinity or NaN, the result
     // is already exact. Likewise if the result is a finite number.
     if (!e1.IsFinite || !e2.IsFinite || eret.IsFinite) {
       return CBORObject.FromObject(eret);
     }
     ERational er1 =
     CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
     ERational er2 =
     CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
     return CBORObject.FromObject(er1.Divide(er2));
       } else {
     EInteger b1 = CBORObject.GetNumberInterface(typeA).AsEInteger(objA);
     EInteger b2 = CBORObject.GetNumberInterface(typeB).AsEInteger(objB);
     if (b2.IsZero) {
       return b1.IsZero ? CBORObject.NaN : ((b1.Sign < 0) ?
     CBORObject.NegativeInfinity : CBORObject.PositiveInfinity);
     }
     EInteger bigrem;
     EInteger bigquo;
     {
     EInteger[] divrem = b1.DivRem(b2);
     bigquo = divrem[0];
     bigrem = divrem[1]; }
     return bigrem.IsZero ? CBORObject.FromObject(bigquo) :
     CBORObject.FromObject(new ERational(b1, b2));
       }
 }
Example #47
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);
       }
 }
Example #48
0
 private static void AddSubCompare(CBORObject o1, CBORObject o2)
 {
     EDecimal cmpDecFrac = AsED(o1).Add(AsED(o2));
       EDecimal cmpCobj = AsED(CBORObject.Addition(o1, o2));
       TestCommon.CompareTestEqual(cmpDecFrac, cmpCobj);
       cmpDecFrac = AsED(o1).Subtract(AsED(o2));
       cmpCobj = AsED(CBORObject.Subtract(o1, o2));
       TestCommon.CompareTestEqual(cmpDecFrac, cmpCobj);
       CBORObjectTest.CompareDecimals(o1, o2);
 }
Example #49
0
 public CBORObject ValidateObject(CBORObject obj)
 {
     return ConvertToBigNum(obj, false);
 }
Example #50
0
 private static string ObjectMessage(CBORObject obj)
 {
     return new System.Text.StringBuilder()
     .Append("CBORObject.DecodeFromBytes(")
        .Append(TestCommon.ToByteArrayString(obj.EncodeToBytes()))
        .Append("); /").Append("/ ").Append(obj.ToJSONString()).ToString();
 }
Example #51
0
 private static byte[] EncodingToBytes(CBORObject b)
 {
     try {
     using (var ms = new MemoryStream()) {
       BEncoding.Write(b, ms);
       return ms.ToArray();
     }
       } catch (IOException ex) {
     throw new CBORException(String.Empty, ex);
       }
 }
Example #52
0
 public Boolean ContainsName(CBORObject key)
 {
     return(m_map.ContainsKey(key));
 }
Example #53
0
#pragma warning restore 618
    private static void FromArrayRecursive(
  Array arr,
  int[] index,
  int dimension,
  CBORObject obj) {
      int dimLength = arr.GetLength(dimension);
      int rank = index.Length;
      for (var i = 0; i < dimLength; ++i) {
        if (dimension + 1 == rank) {
          index[dimension] = i;
          obj.Add(CBORObject.FromObject(arr.GetValue(index)));
        } else {
          CBORObject child = CBORObject.NewArray();
          for (int j = dimension + 1; j < dimLength; ++j) {
            index[j] = 0;
          }
          FromArrayRecursive(arr, index, dimension + 1, child);
          obj.Add(child);
        }
      }
    }
Example #54
0
 private void AssertNegative(CBORObject obj)
 {
     Assert.IsTrue(obj.IsNegative);
       CBORTestCommon.AssertRoundTrip(obj);
 }
Example #55
0
 public Key()
 {
     m_map = CBORObject.NewMap();
 }
Example #56
0
 public Key(CBORObject objKey)
 {
     m_map = objKey;
 }
Example #57
0
 public void Add(CBORObject key, CBORObject value)
 {
     m_map.Add(key, value);
 }
Example #58
0
   internal static void WriteJSONToInternal(
 CBORObject obj,
 StringOutput writer)
   {
       int type = obj.ItemType;
         object thisItem = obj.ThisItem;
         switch (type) {
         case CBORObject.CBORObjectTypeSimpleValue: {
       if (obj.IsTrue) {
         writer.WriteString("true");
         return;
       }
       if (obj.IsFalse) {
         writer.WriteString("false");
         return;
       }
       writer.WriteString("null");
       return;
         }
         case CBORObject.CBORObjectTypeSingle: {
       var f = (float)thisItem;
       if (Single.IsNegativeInfinity(f) ||
           Single.IsPositiveInfinity(f) || Single.IsNaN(f)) {
         writer.WriteString("null");
         return;
       }
       writer.WriteString(
         CBORObject.TrimDotZero(
           CBORUtilities.SingleToString(f)));
       return;
         }
         case CBORObject.CBORObjectTypeDouble: {
       var f = (double)thisItem;
       if (Double.IsNegativeInfinity(f) || Double.IsPositiveInfinity(f) ||
           Double.IsNaN(f)) {
         writer.WriteString("null");
         return;
       }
       string dblString = CBORUtilities.DoubleToString(f);
       writer.WriteString(
         CBORObject.TrimDotZero(dblString));
       return;
         }
         case CBORObject.CBORObjectTypeInteger: {
       var longItem = (long)thisItem;
       writer.WriteString(CBORUtilities.LongToString(longItem));
       return;
         }
         case CBORObject.CBORObjectTypeBigInteger: {
       writer.WriteString(
         CBORUtilities.BigIntToString((EInteger)thisItem));
       return;
         }
         case CBORObject.CBORObjectTypeExtendedDecimal: {
       var dec = (EDecimal)thisItem;
       if (dec.IsInfinity() || dec.IsNaN()) {
         writer.WriteString("null");
       } else {
         writer.WriteString(dec.ToString());
       }
       return;
         }
         case CBORObject.CBORObjectTypeExtendedFloat: {
       var flo = (EFloat)thisItem;
       if (flo.IsInfinity() || flo.IsNaN()) {
         writer.WriteString("null");
         return;
       }
       if (flo.IsFinite &&
           flo.Exponent.Abs().CompareTo((EInteger)2500) > 0) {
         // Too inefficient to convert to a decimal number
         // from a bigfloat with a very high exponent,
         // so convert to double instead
         double f = flo.ToDouble();
         if (Double.IsNegativeInfinity(f) ||
             Double.IsPositiveInfinity(f) || Double.IsNaN(f)) {
           writer.WriteString("null");
           return;
         }
         string dblString =
             CBORUtilities.DoubleToString(f);
         writer.WriteString(
           CBORObject.TrimDotZero(dblString));
         return;
       }
       writer.WriteString(flo.ToString());
       return;
         }
       case CBORObject.CBORObjectTypeByteString:
         {
       var byteArray = (byte[])thisItem;
       if (byteArray.Length == 0) {
         writer.WriteString("\"\"");
         return;
       }
       writer.WriteCodePoint((int)'\"');
       if (obj.HasTag(22)) {
         Base64.WriteBase64(
           writer,
           byteArray,
           0,
           byteArray.Length,
           false);
       } else if (obj.HasTag(23)) {
         // 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]);
         }
       } else {
         Base64.WriteBase64URL(
           writer,
           byteArray,
           0,
           byteArray.Length,
           false);
       }
       writer.WriteCodePoint((int)'\"');
       break;
         }
         case CBORObject.CBORObjectTypeTextString: {
       var thisString = (string)thisItem;
       if (thisString.Length == 0) {
         writer.WriteString("\"\"");
         return;
       }
       writer.WriteCodePoint((int)'\"');
       WriteJSONStringUnquoted(thisString, writer);
       writer.WriteCodePoint((int)'\"');
       break;
         }
         case CBORObject.CBORObjectTypeArray: {
       var first = true;
       writer.WriteCodePoint((int)'[');
       foreach (CBORObject i in obj.AsList()) {
         if (!first) {
           writer.WriteCodePoint((int)',');
         }
         WriteJSONToInternal(i, writer);
         first = false;
       }
       writer.WriteCodePoint((int)']');
       break;
         }
         case CBORObject.CBORObjectTypeExtendedRational: {
       var dec = (ERational)thisItem;
       EDecimal f = dec.ToEDecimalExactIfPossible(
         EContext.Decimal128.WithUnlimitedExponents());
       if (!f.IsFinite) {
         writer.WriteString("null");
       } else {
         writer.WriteString(f.ToString());
       }
       break;
         }
         case CBORObject.CBORObjectTypeMap: {
       var first = true;
       var hasNonStringKeys = false;
       IDictionary<CBORObject, CBORObject> objMap = obj.AsMap();
       foreach (KeyValuePair<CBORObject, CBORObject> entry in objMap) {
         CBORObject key = entry.Key;
         if (key.ItemType != CBORObject.CBORObjectTypeTextString) {
           hasNonStringKeys = true;
           break;
         }
       }
       if (!hasNonStringKeys) {
         writer.WriteCodePoint((int)'{');
         foreach (KeyValuePair<CBORObject, CBORObject> entry in objMap) {
           CBORObject key = entry.Key;
           CBORObject value = entry.Value;
           if (!first) {
             writer.WriteCodePoint((int)',');
           }
           writer.WriteCodePoint((int)'\"');
           WriteJSONStringUnquoted((string)key.ThisItem, writer);
           writer.WriteCodePoint((int)'\"');
           writer.WriteCodePoint((int)':');
           WriteJSONToInternal(value, writer);
           first = false;
         }
         writer.WriteCodePoint((int)'}');
       } 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 objMap) {
           CBORObject key = entry.Key;
           CBORObject value = entry.Value;
          string str = (key.ItemType == CBORObject.CBORObjectTypeTextString) ?
             ((string)key.ThisItem) : key.ToJSONString();
           stringMap[str] = value;
         }
         first = true;
         writer.WriteCodePoint((int)'{');
         foreach (KeyValuePair<string, CBORObject> entry in stringMap) {
           string key = entry.Key;
           CBORObject value = entry.Value;
           if (!first) {
             writer.WriteCodePoint((int)',');
           }
           writer.WriteCodePoint((int)'\"');
           WriteJSONStringUnquoted((string)key, writer);
           writer.WriteCodePoint((int)'\"');
           writer.WriteCodePoint((int)':');
           WriteJSONToInternal(value, writer);
           first = false;
         }
         writer.WriteCodePoint((int)'}');
       }
       break;
         }
       default:
         throw new InvalidOperationException("Unexpected item type");
         }
   }
Example #59
0
 public static void TestNumber(CBORObject o)
 {
     if (o.Type != CBORType.Number) {
     return;
       }
       if (o.IsPositiveInfinity() || o.IsNegativeInfinity() ||
       o.IsNaN()) {
     try {
       o.AsByte();
       Assert.Fail("Should have failed");
     } catch (OverflowException) {
       new Object();
     } catch (Exception ex) {
       Assert.Fail("Object: " + o + ", " + ex); throw new
     InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsInt16();
       Assert.Fail("Should have failed");
     } catch (OverflowException) {
       new Object();
     } catch (Exception ex) {
       Assert.Fail("Object: " + o + ", " + ex); throw new
     InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsInt32();
       Assert.Fail("Should have failed");
     } catch (OverflowException) {
       new Object();
     } catch (Exception ex) {
       Assert.Fail("Object: " + o + ", " + ex); throw new
     InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsInt64();
       Assert.Fail("Should have failed");
     } catch (OverflowException) {
       new Object();
     } catch (Exception ex) {
       Assert.Fail("Object: " + o + ", " + ex); throw new
     InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsSingle();
     } catch (Exception ex) {
       Assert.Fail(ex.ToString());
       throw new InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsDouble();
     } catch (Exception ex) {
       Assert.Fail(ex.ToString());
       throw new InvalidOperationException(String.Empty, ex);
     }
     try {
       o.AsEInteger();
       Assert.Fail("Should have failed");
     } catch (OverflowException) {
       new Object();
     } catch (Exception ex) {
       Assert.Fail("Object: " + o + ", " + ex); throw new
     InvalidOperationException(String.Empty, ex);
     }
     return;
       }
       try {
     o.AsSingle();
       } catch (Exception ex) {
     Assert.Fail("Object: " + o + ", " + ex); throw new
       InvalidOperationException(String.Empty, ex);
       }
       try {
     o.AsDouble();
       } catch (Exception ex) {
     Assert.Fail("Object: " + o + ", " + ex); throw new
       InvalidOperationException(String.Empty, ex);
       }
 }