public static void AssertRoundTrip(CBORObject o) { CBORObject o2 = FromBytesTestAB(o.EncodeToBytes()); TestCommon.CompareTestEqual(o, o2); TestNumber(o); TestCommon.AssertEqualsHashCode(o, o2); }
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)); }
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)); }
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); } }
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); }
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); }
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; }
/** * Constructor creating an empty CWT. */ public CWT() { CwtObject = CBORObject.NewMap(); }
public FidoU2f(CBORObject attStmt, byte[] authenticatorData, byte[] clientDataHash, IMetadataService metadataService, bool requireValidAttestationRoot) : base(attStmt, authenticatorData, clientDataHash) { _metadataService = metadataService; _requireValidAttestationRoot = requireValidAttestationRoot; }
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"); } }
public AndroidKey(CBORObject attStmt, byte[] authenticatorData, byte[] clientDataHash) : base(attStmt, authenticatorData, clientDataHash) { }
private static EDecimal AsED(CBORObject obj) { return EDecimal.FromString( obj.AsEDecimal().ToString()); }
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); } }
public CBORObject ValidateObject(CBORObject obj) { return ConvertToDecimalFrac(obj, false, this.extended); }
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"); } }
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); } }
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); } }
private static EDecimal AsED(CBORObject obj) { return((EDecimal)obj.ToObject(typeof(EDecimal))); }
public Packed(CBORObject attStmt, byte[] authenticatorData, byte[] clientDataHash, IMetadataService metadataService) : base(attStmt, authenticatorData, clientDataHash) { _metadataService = metadataService; }
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"); } }
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); } }
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); } }
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); } }
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); } }
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 }
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"); }
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); }
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"); } }
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)); } }
public FidoU2f(CBORObject attStmt, byte[] authenticatorData, byte[] clientDataHash) : base(attStmt, authenticatorData, clientDataHash) { }
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); }
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()); }
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; } }
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"); } } } } }
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); } }
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); } }
public void SetClaim(ClaimID claim, string value) { SetClaim(claim, CBORObject.FromObject(value)); }
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; }
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); } }
#pragma warning restore CA1801 public CBORObject GetJSON(string name) { return(CBORObject.FromJSONString( this.GetString(name))); }
public void AddObject(CBORObject obj) { this.sharedObjects.Add(obj); }
public CBORObject this[CBORObject name] { get { return(m_map[name]); } }
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); } }
public byte[] AsBytes(CBORObject name) { return(m_map[name].GetByteString()); }
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)); } }
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); } }
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); }
public CBORObject ValidateObject(CBORObject obj) { return ConvertToBigNum(obj, false); }
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(); }
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); } }
public Boolean ContainsName(CBORObject key) { return(m_map.ContainsKey(key)); }
#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); } } }
private void AssertNegative(CBORObject obj) { Assert.IsTrue(obj.IsNegative); CBORTestCommon.AssertRoundTrip(obj); }
public Key() { m_map = CBORObject.NewMap(); }
public Key(CBORObject objKey) { m_map = objKey; }
public void Add(CBORObject key, CBORObject value) { m_map.Add(key, value); }
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"); } }
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); } }