public static void ReadFlexibleString_StructHybrid() { const string BmpInputHex = "1E0400480069"; const string Utf8InputHex = "0C024869"; const string Ia5InputHex = "16024869"; var fs1 = AsnSerializer.Deserialize <FlexibleStringStructHybrid>( BmpInputHex.HexToByteArray(), AsnEncodingRules.DER); var fs2 = AsnSerializer.Deserialize <FlexibleStringStructHybrid>( Utf8InputHex.HexToByteArray(), AsnEncodingRules.DER); var fs3 = AsnSerializer.Deserialize <FlexibleStringStructHybrid>( Ia5InputHex.HexToByteArray(), AsnEncodingRules.DER); Assert.Null(fs1.DirectoryString?.Utf8String); Assert.Null(fs1.Ascii); Assert.Null(fs2.DirectoryString?.BmpString); Assert.Null(fs2.Ascii); Assert.Null(fs3.DirectoryString?.BmpString); Assert.Null(fs3.DirectoryString?.Utf8String); Assert.Null(fs3.DirectoryString); Assert.Equal("Hi", fs1.DirectoryString?.BmpString); Assert.Equal("Hi", fs2.DirectoryString?.Utf8String); Assert.Equal("Hi", fs3.Ascii); }
private SignerInfoCollection GetCounterSigners(AttributeAsn[] unsignedAttrs) { // Since each "attribute" can have multiple "attribute values" there's no real // correlation to a predictive size here. List <SignerInfo> signerInfos = new List <SignerInfo>(); foreach (AttributeAsn attributeAsn in unsignedAttrs) { if (attributeAsn.AttrType.Value == Oids.CounterSigner) { AsnReader reader = new AsnReader(attributeAsn.AttrValues, AsnEncodingRules.BER); AsnReader collReader = reader.ReadSetOf(); if (reader.HasData) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } while (collReader.HasData) { SignerInfoAsn parsedData = AsnSerializer.Deserialize <SignerInfoAsn>(collReader.GetEncodedValue(), AsnEncodingRules.BER); SignerInfo signerInfo = new SignerInfo(ref parsedData, _document) { _parentSignerInfo = this }; signerInfos.Add(signerInfo); } } } return(new SignerInfoCollection(signerInfos.ToArray())); }
public static void ReadIndefiniteLengthCustomTaggedStrings() { byte[] inputData = ( // (constructed) SEQUENCE (indefinite) "3080" + // (constructed) CONTEXT-SPECIFIC 0 (indefinite) "A080" + // OCTET STRING (3): 020100 "0403020100" + // EoC ([0]) "0000" + // (constructed) CONTEXT-SPECIFIC 1 (indefinite) "A180" + // BIT STRING (4) (0 unused bits): 010203 "030400010203" + // EoC ([1]) "0000" + // EoC (SEQUENCE) "0000").HexToByteArray(); CustomTaggedBinaryStrings parsed = AsnSerializer.Deserialize <CustomTaggedBinaryStrings>(inputData, AsnEncodingRules.BER); Assert.Equal("020100", parsed.OctetString.ByteArrayToHex()); Assert.Equal("010203", parsed.BitString.ByteArrayToHex()); }
internal Pkcs12SecretBag(Oid secretTypeOid, ReadOnlyMemory <byte> secretValue) : this(EncodeBagValue(secretTypeOid, secretValue)) { _secretTypeOid = new Oid(secretTypeOid); _decoded = AsnSerializer.Deserialize <SecretBagAsn>(EncodedBagValue, AsnEncodingRules.BER); }
public static void ReadEcPublicKey() { const string PublicKeyValue = "04" + "2363DD131DA65E899A2E63E9E05E50C830D4994662FFE883DB2B9A767DCCABA2" + "F07081B5711BE1DEE90DFC8DE17970C2D937A16CD34581F52B8D59C9E9532D13"; const string InputHex = "3059" + "3013" + "06072A8648CE3D0201" + "06082A8648CE3D030107" + "0342" + "00" + PublicKeyValue; byte[] inputData = InputHex.HexToByteArray(); var spki = AsnSerializer.Deserialize <SubjectPublicKeyInfo>( inputData, AsnEncodingRules.DER); Assert.Equal("1.2.840.10045.2.1", spki.AlgorithmIdentifier.Algorithm.Value); Assert.Equal(PublicKeyValue, spki.PublicKey.ByteArrayToHex()); AsnReader reader = new AsnReader(spki.AlgorithmIdentifier.Parameters, AsnEncodingRules.DER); string curveOid = reader.ReadObjectIdentifierAsString(); Assert.False(reader.HasData, "reader.HasData"); Assert.Equal("1.2.840.10045.3.1.7", curveOid); }
private static bool TryDecode( ReadOnlyMemory <byte> source, bool ownsMemory, out Rfc3161TstInfo tstInfo, out int bytesConsumed, out byte[] copiedBytes) { // https://tools.ietf.org/html/rfc3161#section-2.4.2 // The eContent SHALL be the DER-encoded value of TSTInfo. AsnReader reader = new AsnReader(source, AsnEncodingRules.DER); try { ReadOnlyMemory <byte> firstElement = reader.PeekEncodedValue(); if (ownsMemory) { copiedBytes = null; } else { // Copy the data so no ReadOnlyMemory values are pointing back to user data. copiedBytes = firstElement.ToArray(); firstElement = copiedBytes; } Rfc3161TstInfo parsedInfo = AsnSerializer.Deserialize <Rfc3161TstInfo>( firstElement, AsnEncodingRules.DER); // The deserializer doesn't do bounds checks. // Micros and Millis are defined as (1..999) // Seconds doesn't define that it's bounded by 0, // but negative accuracy doesn't make sense. // // (Reminder to readers: a null int? with an inequality operator // has the value false, so if accuracy is missing, or millis or micro is missing, // then the respective checks return false and don't throw). if (parsedInfo.Accuracy?.Micros > 999 || parsedInfo.Accuracy?.Micros < 1 || parsedInfo.Accuracy?.Millis > 999 || parsedInfo.Accuracy?.Millis < 1 || parsedInfo.Accuracy?.Seconds < 0) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } tstInfo = parsedInfo; bytesConsumed = firstElement.Length; return(true); } catch (CryptographicException) { tstInfo = null; bytesConsumed = 0; copiedBytes = null; return(false); } }
private bool ProcessResponse( ReadOnlyMemory <byte> source, out Rfc3161TimestampToken token, out Rfc3161RequestResponseStatus status, out int bytesConsumed, bool shouldThrow) { status = Rfc3161RequestResponseStatus.Unknown; token = null; Rfc3161TimeStampResp resp; try { resp = AsnSerializer.Deserialize <Rfc3161TimeStampResp>(source, AsnEncodingRules.DER, out bytesConsumed); } catch (CryptographicException) when(!shouldThrow) { bytesConsumed = 0; status = Rfc3161RequestResponseStatus.DoesNotParse; return(false); } // bytesRead will be set past this point PkiStatus pkiStatus = (PkiStatus)resp.Status.Status; if (pkiStatus != PkiStatus.Granted && pkiStatus != PkiStatus.GrantedWithMods) { if (shouldThrow) { throw new CryptographicException( SR.Format( SR.Cryptography_TimestampReq_Failure, pkiStatus, resp.Status.FailInfo.GetValueOrDefault())); } status = Rfc3161RequestResponseStatus.RequestFailed; return(false); } if (!Rfc3161TimestampToken.TryDecode(resp.TimeStampToken.GetValueOrDefault(), out token, out _)) { if (shouldThrow) { throw new CryptographicException(SR.Cryptography_TimestampReq_BadResponse); } bytesConsumed = 0; status = Rfc3161RequestResponseStatus.DoesNotParse; return(false); } status = ValidateResponse(token, shouldThrow); return(status == Rfc3161RequestResponseStatus.Accepted); }
public static void ReadMicrosoftDotCom() { byte[] buf = Convert.FromBase64String(MicrosoftDotComBase64); Certificate cert = AsnSerializer.Deserialize <Certificate>( buf, AsnEncodingRules.DER); ref TbsCertificate tbsCertificate = ref cert.TbsCertificate;
public static void DirectoryStringClass_AsNull() { byte[] inputBytes = { 0x05, 0x00 }; DirectoryStringClass ds = AsnSerializer.Deserialize <DirectoryStringClass>( inputBytes, AsnEncodingRules.DER); Assert.Null(ds); }
public static void TooMuchData() { // This is { IA5String("IA5"), UTF8String("UTF8") }, which is the opposite // of the field order of OptionalValues. SO it will see the UTF8String as null, // then the IA5String as present, but then data remains. byte[] inputData = "300B16034941350C0455544638".HexToByteArray(); Assert.Throws <CryptographicException>( () => AsnSerializer.Deserialize <OptionalValues>(inputData, AsnEncodingRules.BER)); }
public override Oid GetEncodedMessageType(byte[] encodedMessage) { AsnReader reader = new AsnReader(encodedMessage, AsnEncodingRules.BER); ContentInfoAsn contentInfo = AsnSerializer.Deserialize <ContentInfoAsn>( reader.GetEncodedValue(), AsnEncodingRules.BER); return(new Oid(contentInfo.ContentType)); }
internal void Decode(ReadOnlyMemory <byte> encodedMessage) { // Windows (and thus NetFx) reads the leading data and ignores extra. // So use the Deserialize overload which doesn't throw on extra data. ContentInfoAsn contentInfo = AsnSerializer.Deserialize <ContentInfoAsn>( encodedMessage, AsnEncodingRules.BER, out int bytesRead); if (contentInfo.ContentType != Oids.Pkcs7Signed) { throw new CryptographicException(SR.Cryptography_Cms_InvalidMessageType); } // Hold a copy of the SignedData memory so we are protected against memory reuse by the caller. _heldData = contentInfo.Content.ToArray(); _signedData = AsnSerializer.Deserialize <SignedDataAsn>(_heldData, AsnEncodingRules.BER); _contentType = _signedData.EncapContentInfo.ContentType; _hasPkcs7Content = false; if (!Detached) { ReadOnlyMemory <byte>?content = _signedData.EncapContentInfo.Content; ReadOnlyMemory <byte> contentValue; if (content.HasValue) { contentValue = GetContent(content.Value, _contentType); // If no OCTET STRING was stripped off, we have PKCS7 interop concerns. _hasPkcs7Content = content.Value.Length == contentValue.Length; } else { contentValue = ReadOnlyMemory <byte> .Empty; } // This is in _heldData, so we don't need a defensive copy. _heldContent = contentValue; // The ContentInfo object/property DOES need a defensive copy, because // a) it is mutable by the user, and // b) it is no longer authoritative // // (and c: it takes a byte[] and we have a ReadOnlyMemory<byte>) ContentInfo = new ContentInfo(new Oid(_contentType), contentValue.ToArray()); } else { // Hold a defensive copy of the content bytes, (Windows/NetFx compat) _heldContent = ContentInfo.Content.CloneByteArray(); } Version = _signedData.Version; _hasData = true; }
public static void Choice_CycleRoot_Throws() { byte[] inputBytes = { 0x01, 0x01, 0x00 }; Assert.Throws <AsnSerializationConstraintException>( () => AsnSerializer.Deserialize <CycleRoot>( inputBytes, AsnEncodingRules.DER) ); }
internal static void Decode(AsnReader reader, out PssParamsAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } ReadOnlyMemory <byte> value = reader.GetEncodedValue(); decoded = AsnSerializer.Deserialize <PssParamsAsn>(value, reader.RuleSet); }
public static void Deserialize_ContextSpecific_Choice() { byte[] inputBytes = { 0x82, 0x00 }; ContextSpecificChoice choice = AsnSerializer.Deserialize <ContextSpecificChoice>( inputBytes, AsnEncodingRules.DER); Assert.Null(choice.Utf8String); Assert.Equal(string.Empty, choice.IA5String); }
public virtual void DecodeX509BasicConstraints2Extension( byte[] encoded, out bool certificateAuthority, out bool hasPathLengthConstraint, out int pathLengthConstraint) { BasicConstraintsAsn constraints = AsnSerializer.Deserialize <BasicConstraintsAsn>(encoded, AsnEncodingRules.BER); certificateAuthority = constraints.CA; hasPathLengthConstraint = constraints.PathLengthConstraint.HasValue; pathLengthConstraint = constraints.PathLengthConstraint.GetValueOrDefault(); }
internal Pkcs12CertBag(X509Certificate2 cert) : base( Oids.Pkcs12CertBag, EncodeBagValue( Oids.Pkcs12X509CertBagType, PkcsPal.Instance.EncodeOctetString(cert.RawData)), skipCopy: true) { _decoded = AsnSerializer.Deserialize <CertBagAsn>( EncodedBagValue, AsnEncodingRules.BER); IsX509Certificate = true; }
public static void ReadNegativeIntegers(PublicEncodingRules ruleSet) { byte[] inputData = ( "3007" + "0201FE" + "0202FEEF").HexToByteArray(); BigIntegers bigIntegers = AsnSerializer.Deserialize <BigIntegers>( inputData, (AsnEncodingRules)ruleSet); Assert.Equal(-2, (int)bigIntegers.First); Assert.Equal("FEEF", bigIntegers.Second.ByteArrayToHex()); }
/// <summary> /// Create a CertBag for a specified certificate type and encoding. /// </summary> /// <param name="certificateType">The identifier for the certificate type</param> /// <param name="encodedCertificate">The encoded value</param> /// <remarks> /// No validation is done to ensure that the <paramref name="encodedCertificate"/> value is /// correct for the indicated <paramref name="certificateType"/>. Note that for X.509 /// public-key certificates the correct encoding for a CertBag value is to wrap the /// DER-encoded certificate in an OCTET STRING. /// </remarks> public Pkcs12CertBag(Oid certificateType, ReadOnlyMemory <byte> encodedCertificate) : base( Oids.Pkcs12CertBag, EncodeBagValue(certificateType, encodedCertificate), skipCopy: true) { _certTypeOid = new Oid(certificateType); _decoded = AsnSerializer.Deserialize <CertBagAsn>( EncodedBagValue, AsnEncodingRules.BER); IsX509Certificate = _decoded.CertId == Oids.Pkcs12X509CertBagType; }
private static SymmetricAlgorithm OpenAlgorithm(AlgorithmIdentifierAsn contentEncryptionAlgorithm) { SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm.Algorithm); if (alg is RC2) { if (contentEncryptionAlgorithm.Parameters == null) { // Windows issues CRYPT_E_BAD_DECODE throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } Rc2CbcParameters rc2Params = AsnSerializer.Deserialize <Rc2CbcParameters>( contentEncryptionAlgorithm.Parameters.Value, AsnEncodingRules.BER); alg.KeySize = rc2Params.GetEffectiveKeyBits(); alg.IV = rc2Params.Iv.ToArray(); } else { if (contentEncryptionAlgorithm.Parameters == null) { // Windows issues CRYPT_E_BAD_DECODE throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } AsnReader reader = new AsnReader(contentEncryptionAlgorithm.Parameters.Value, AsnEncodingRules.BER); if (reader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> primitiveBytes)) { alg.IV = primitiveBytes.ToArray(); } else { byte[] iv = new byte[alg.BlockSize / 8]; if (!reader.TryCopyOctetStringBytes(iv, out int bytesWritten) || bytesWritten != iv.Length) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } alg.IV = iv; } } return(alg); }
public virtual void DecodeX509EnhancedKeyUsageExtension(byte[] encoded, out OidCollection usages) { // https://tools.ietf.org/html/rfc5924#section-4.1 // // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId // // KeyPurposeId ::= OBJECT IDENTIFIER Oid[] keyUsages = AsnSerializer.Deserialize <Oid[]>(encoded, AsnEncodingRules.BER); usages = new OidCollection(); foreach (Oid KeyPurposeId in keyUsages) { usages.Add(KeyPurposeId); } }
public void Decode(byte[] encodedMessage) { if (encodedMessage == null) { throw new ArgumentNullException(nameof(encodedMessage)); } // Windows (and thus NetFx) reads the leading data and ignores extra. // The deserializer will complain if too much data is given, so use the reader // to ask how much we want to deserialize. AsnReader reader = new AsnReader(encodedMessage, AsnEncodingRules.BER); ReadOnlyMemory <byte> cmsSegment = reader.GetEncodedValue(); ContentInfoAsn contentInfo = AsnSerializer.Deserialize <ContentInfoAsn>(cmsSegment, AsnEncodingRules.BER); if (contentInfo.ContentType != Oids.Pkcs7Signed) { throw new CryptographicException(SR.Cryptography_Cms_InvalidMessageType); } // Hold a copy of the SignedData memory so we are protected against memory reuse by the caller. _heldData = contentInfo.Content.ToArray(); _signedData = AsnSerializer.Deserialize <SignedDataAsn>(_heldData, AsnEncodingRules.BER); _contentType = _signedData.EncapContentInfo.ContentType; if (!Detached) { ReadOnlyMemory <byte>?content = _signedData.EncapContentInfo.Content; // This is in _heldData, so we don't need a defensive copy. _heldContent = content ?? ReadOnlyMemory <byte> .Empty; // The ContentInfo object/property DOES need a defensive copy, because // a) it is mutable by the user, and // b) it is no longer authoritative // // (and c: it takes a byte[] and we have a ReadOnlyMemory<byte>) ContentInfo = new ContentInfo(new Oid(_contentType), _heldContent.Value.ToArray()); } else { // Hold a defensive copy of the content bytes, (Windows/NetFx compat) _heldContent = ContentInfo.Content.CloneByteArray(); } Version = _signedData.Version; _hasData = true; }
internal byte[] ToPkcs10Request(X509SignatureGenerator signatureGenerator, HashAlgorithmName hashAlgorithm) { // State validation should be runtime checks if/when this becomes public API Debug.Assert(signatureGenerator != null); Debug.Assert(Subject != null); Debug.Assert(PublicKey != null); byte[] signatureAlgorithm = signatureGenerator.GetSignatureAlgorithmIdentifier(hashAlgorithm); AlgorithmIdentifierAsn signatureAlgorithmAsn; // Deserialization also does validation of the value (except for Parameters, which have to be validated separately). signatureAlgorithmAsn = AsnSerializer.Deserialize <AlgorithmIdentifierAsn>(signatureAlgorithm, AsnEncodingRules.DER); if (signatureAlgorithmAsn.Parameters.HasValue) { Helpers.ValidateDer(signatureAlgorithmAsn.Parameters.Value); } SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn(); spki.Algorithm = new AlgorithmIdentifierAsn { Algorithm = PublicKey.Oid, Parameters = PublicKey.EncodedParameters.RawData }; spki.SubjectPublicKey = PublicKey.EncodedKeyValue.RawData; CertificationRequestInfoAsn requestInfo = new CertificationRequestInfoAsn { Version = 0, Subject = this.Subject.RawData, SubjectPublicKeyInfo = spki, Attributes = Attributes.Select(e => new X501AttributeAsn(e)).ToArray(), }; using (AsnWriter writer = AsnSerializer.Serialize(requestInfo, AsnEncodingRules.DER)) { byte[] encodedRequestInfo = writer.Encode(); CertificationRequestAsn certificationRequest = new CertificationRequestAsn { CertificationRequestInfo = requestInfo, SignatureAlgorithm = signatureAlgorithmAsn, SignatureValue = signatureGenerator.SignData(encodedRequestInfo, hashAlgorithm), }; using (AsnWriter signedWriter = AsnSerializer.Serialize(certificationRequest, AsnEncodingRules.DER)) { return(signedWriter.Encode()); } } }
/// <summary> /// Create a timestamp request using a pre-computed hash value. /// </summary> /// <param name="hash">The pre-computed hash value to be timestamped.</param> /// <param name="hashAlgorithmId"> /// The Object Identifier (OID) for the hash algorithm which produced <paramref name="hash"/>. /// </param> /// <param name="requestedPolicyId"> /// The Object Identifier (OID) for a timestamp policy the Timestamp Authority (TSA) should use, /// or <c>null</c> to express no preference. /// </param> /// <param name="nonce"> /// An optional nonce (number used once) to uniquely identify this request to pair it with the response. /// The value is interpreted as an unsigned big-endian integer and may be normalized to the encoding format. /// </param> /// <param name="requestSignerCertificates"> /// Indicates whether the Timestamp Authority (TSA) must (<c>true</c>) or must not (<c>false</c>) include /// the signing certificate in the issued timestamp token. /// </param> /// <param name="extensions">RFC3161 extensions to present with the request.</param> /// <returns> /// An <see cref="Rfc3161TimestampRequest"/> representing the chosen values. /// </returns> /// <seealso cref="Encode"/> /// <seealso cref="TryEncode"/> public static Rfc3161TimestampRequest CreateFromHash( ReadOnlyMemory <byte> hash, Oid hashAlgorithmId, Oid requestedPolicyId = null, ReadOnlyMemory <byte>?nonce = null, bool requestSignerCertificates = false, X509ExtensionCollection extensions = null) { var req = new Rfc3161TimeStampReq { Version = 1, MessageImprint = new MessageImprint { HashAlgorithm = { Algorithm = hashAlgorithmId, Parameters = AlgorithmIdentifierAsn.ExplicitDerNull, }, HashedMessage = hash, }, ReqPolicy = requestedPolicyId, CertReq = requestSignerCertificates, Nonce = nonce, }; if (extensions != null) { req.Extensions = extensions.OfType <X509Extension>().Select(e => new X509ExtensionAsn(e)).ToArray(); } // The RFC implies DER (see TryParse), and DER is the most widely understood given that // CER isn't specified. const AsnEncodingRules ruleSet = AsnEncodingRules.DER; AsnWriter writer = AsnSerializer.Serialize(req, ruleSet); byte[] encodedBytes = writer.Encode(); // Make sure everything normalizes req = AsnSerializer.Deserialize <Rfc3161TimeStampReq>(encodedBytes, ruleSet); return(new Rfc3161TimestampRequest { _encodedBytes = writer.Encode(), _parsedData = req, }); }
public static void TooMuchDataForValue() { // Two empty sequences, which is more data than one OptionalValues value. byte[] inputData = "30003000".HexToByteArray(); OptionalValues parsed = AsnSerializer.Deserialize <OptionalValues>( inputData, AsnEncodingRules.BER, out int bytesRead); Assert.NotNull(parsed); Assert.Equal(2, bytesRead); Assert.Throws <CryptographicException>( () => AsnSerializer.Deserialize <OptionalValues>(inputData, AsnEncodingRules.BER)); }
internal static unsafe ECParameters FromECPrivateKey(ReadOnlySpan <byte> key, out int bytesRead) { fixed(byte *ptr = &MemoryMarshal.GetReference(key)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, key.Length)) { ECPrivateKey parsedKey = AsnSerializer.Deserialize <ECPrivateKey>(manager.Memory, AsnEncodingRules.BER, out bytesRead); ECParameters ret; AlgorithmIdentifierAsn algId = default; FromECPrivateKey(parsedKey, algId, out ret); return(ret); } } }
public static void Deserialize_NamedBitLists() { const string InputHex = "3080" + "0303000841" + "0000"; byte[] inputBytes = InputHex.HexToByteArray(); var variants = AsnSerializer.Deserialize <NamedBitListModeVariants>( inputBytes, AsnEncodingRules.BER); Assert.Equal( SomeFlagsEnum.BitFour | SomeFlagsEnum.BitNine | SomeFlagsEnum.BitFifteen, variants.DefaultMode); }
public static void Deserialize_UtcTime_WithTwoYearMax() { const string UtcTimeValue = "170D3132303130323233353935395A"; const string InputHex = "3080" + UtcTimeValue + UtcTimeValue + UtcTimeValue + "0000"; byte[] inputBytes = InputHex.HexToByteArray(); UtcTimeTwoDigitYears dates = AsnSerializer.Deserialize <UtcTimeTwoDigitYears>( inputBytes, AsnEncodingRules.BER); Assert.Equal(new DateTimeOffset(1912, 1, 2, 23, 59, 59, TimeSpan.Zero), dates.ErnestoSabatoLifetime); Assert.Equal(new DateTimeOffset(2012, 1, 2, 23, 59, 59, TimeSpan.Zero), dates.MayanPhenomenon); Assert.Equal(new DateTimeOffset(2012, 1, 2, 23, 59, 59, TimeSpan.Zero), dates.ImplicitMax); }
public static void SerializeExplicitDefaultValue(int version, string expectedHex) { ExplicitDefaultAsn data = new ExplicitDefaultAsn { Version = version }; byte[] encoded; using (AsnWriter writer = AsnSerializer.Serialize(data, AsnEncodingRules.DER)) { encoded = writer.Encode(); Assert.Equal(expectedHex, encoded.ByteArrayToHex()); } // Deserialize the data back. data = AsnSerializer.Deserialize <ExplicitDefaultAsn>(encoded, AsnEncodingRules.DER); Assert.Equal(version, data.Version); }
public static void ReadAnyValueWithExpectedTag() { byte[] inputData = "308006010030030101000000".HexToByteArray(); var data = AsnSerializer.Deserialize <AnyWithExpectedTag>( inputData, AsnEncodingRules.BER); Assert.Equal("0.0", data.Id); Assert.Equal(5, data.Data.Length); Assert.True(Unsafe.AreSame(ref data.Data.Span.DangerousGetPinnableReference(), ref inputData[5])); // Change [Constructed] SEQUENCE to [Constructed] Context-Specific 0. inputData[5] = 0xA0; Assert.Throws <CryptographicException>( () => AsnSerializer.Deserialize <AnyWithExpectedTag>(inputData, AsnEncodingRules.BER)); }