internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out X509ExtensionAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader defaultReader; decoded.ExtnId = sequenceReader.ReadObjectIdentifier(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Boolean)) { decoded.Critical = sequenceReader.ReadBoolean(); } else { defaultReader = new AsnReader(s_defaultCritical, AsnEncodingRules.DER); decoded.Critical = defaultReader.ReadBoolean(); } if (sequenceReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpExtnValue)) { decoded.ExtnValue = tmpExtnValue; } else { decoded.ExtnValue = sequenceReader.ReadOctetString(); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out EncryptedPrivateKeyInfoAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.EncryptionAlgorithm); if (sequenceReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpEncryptedData)) { decoded.EncryptedData = tmpEncryptedData; } else { decoded.EncryptedData = sequenceReader.ReadOctetString(); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SubjectPublicKeyInfoAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.Algorithm); if (sequenceReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpSubjectPublicKey)) { decoded.SubjectPublicKey = tmpSubjectPublicKey; } else { decoded.SubjectPublicKey = sequenceReader.ReadBitString(out _); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, out GeneralNameAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; Asn1Tag tag = reader.PeekTag(); AsnReader explicitReader; if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { System.Security.Cryptography.Asn1.OtherNameAsn tmpOtherName; System.Security.Cryptography.Asn1.OtherNameAsn.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 0), out tmpOtherName); decoded.OtherName = tmpOtherName; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { decoded.Rfc822Name = reader.GetCharacterString(new Asn1Tag(TagClass.ContextSpecific, 1), UniversalTagNumber.IA5String); } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { decoded.DnsName = reader.GetCharacterString(new Asn1Tag(TagClass.ContextSpecific, 2), UniversalTagNumber.IA5String); } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { decoded.X400Address = reader.GetEncodedValue(); } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 4))) { explicitReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4)); decoded.DirectoryName = explicitReader.GetEncodedValue(); explicitReader.ThrowIfNotEmpty(); } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 5))) { System.Security.Cryptography.Asn1.EdiPartyNameAsn tmpEdiPartyName; System.Security.Cryptography.Asn1.EdiPartyNameAsn.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 5), out tmpEdiPartyName); decoded.EdiPartyName = tmpEdiPartyName; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6))) { decoded.Uri = reader.GetCharacterString(new Asn1Tag(TagClass.ContextSpecific, 6), UniversalTagNumber.IA5String); } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 7))) { if (reader.TryGetPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 7), out ReadOnlyMemory <byte> tmpIPAddress)) { decoded.IPAddress = tmpIPAddress; } else { decoded.IPAddress = reader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 7)); } } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 8))) { decoded.RegisteredId = reader.ReadObjectIdentifierAsString(new Asn1Tag(TagClass.ContextSpecific, 8)); } else { throw new CryptographicException(); } }
private int ProcessConstructedBitString( ReadOnlyMemory <byte> source, Span <byte> destination, BitStringCopyAction copyAction, bool isIndefinite, out int lastUnusedBitCount, out int bytesRead) { lastUnusedBitCount = 0; bytesRead = 0; int lastSegmentLength = MaxCERSegmentSize; AsnReader tmpReader = new AsnReader(source, RuleSet); Stack <(AsnReader, bool, int)> readerStack = null; int totalLength = 0; Asn1Tag tag = Asn1Tag.ConstructedBitString; Span <byte> curDest = destination; do { while (tmpReader.HasData) { tag = tmpReader.ReadTagAndLength(out int?length, out int headerLength); if (tag == Asn1Tag.PrimitiveBitString) { if (lastUnusedBitCount != 0) { // T-REC-X.690-201508 sec 8.6.4, only the last segment may have // a number of bits not a multiple of 8. throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } if (RuleSet == AsnEncodingRules.CER && lastSegmentLength != MaxCERSegmentSize) { // T-REC-X.690-201508 sec 9.2 throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } Debug.Assert(length != null); ReadOnlyMemory <byte> encodedValue = Slice(tmpReader._data, headerLength, length.Value); ParsePrimitiveBitStringContents( encodedValue, out lastUnusedBitCount, out ReadOnlyMemory <byte> contents, out byte normalizedLastByte); int localLen = headerLength + encodedValue.Length; tmpReader._data = tmpReader._data.Slice(localLen); bytesRead += localLen; totalLength += contents.Length; lastSegmentLength = encodedValue.Length; if (copyAction != null) { copyAction(contents, normalizedLastByte, curDest); curDest = curDest.Slice(contents.Length); } } else if (tag == Asn1Tag.EndOfContents && isIndefinite) { ValidateEndOfContents(tag, length, headerLength); bytesRead += headerLength; if (readerStack?.Count > 0) { (AsnReader topReader, bool wasIndefinite, int pushedBytesRead) = readerStack.Pop(); topReader._data = topReader._data.Slice(bytesRead); bytesRead += pushedBytesRead; isIndefinite = wasIndefinite; tmpReader = topReader; } else { // We have matched the EndOfContents that brought us here. break; } } else if (tag == Asn1Tag.ConstructedBitString) { if (RuleSet == AsnEncodingRules.CER) { // T-REC-X.690-201508 sec 9.2 throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } if (readerStack == null) { readerStack = new Stack <(AsnReader, bool, int)>(); } readerStack.Push((tmpReader, isIndefinite, bytesRead)); tmpReader = new AsnReader( Slice(tmpReader._data, headerLength, length), RuleSet); bytesRead = headerLength; isIndefinite = (length == null); } else { // T-REC-X.690-201508 sec 8.6.4.1 (in particular, Note 2) throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } } if (isIndefinite && tag != Asn1Tag.EndOfContents) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } if (readerStack?.Count > 0) { (AsnReader topReader, bool wasIndefinite, int pushedBytesRead) = readerStack.Pop(); tmpReader = topReader; tmpReader._data = tmpReader._data.Slice(bytesRead); isIndefinite = wasIndefinite; bytesRead += pushedBytesRead; } else { tmpReader = null; } } while (tmpReader != null); return(totalLength); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out PssParamsAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader defaultReader; if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(explicitReader, out decoded.HashAlgorithm); explicitReader.ThrowIfNotEmpty(); } else { defaultReader = new AsnReader(s_defaultHashAlgorithm, AsnEncodingRules.DER); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(defaultReader, out decoded.HashAlgorithm); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(explicitReader, out decoded.MaskGenAlgorithm); explicitReader.ThrowIfNotEmpty(); } else { defaultReader = new AsnReader(s_defaultMaskGenAlgorithm, AsnEncodingRules.DER); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(defaultReader, out decoded.MaskGenAlgorithm); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); if (!explicitReader.TryReadInt32(out decoded.SaltLength)) { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); } else { defaultReader = new AsnReader(s_defaultSaltLength, AsnEncodingRules.DER); if (!defaultReader.TryReadInt32(out decoded.SaltLength)) { defaultReader.ThrowIfNotEmpty(); } } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); if (!explicitReader.TryReadInt32(out decoded.TrailerField)) { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); } else { defaultReader = new AsnReader(s_defaultTrailerField, AsnEncodingRules.DER); if (!defaultReader.TryReadInt32(out decoded.TrailerField)) { defaultReader.ThrowIfNotEmpty(); } } sequenceReader.ThrowIfNotEmpty(); }
private int CopyConstructedOctetString( ReadOnlyMemory <byte> source, Span <byte> destination, bool write, bool isIndefinite, out int bytesRead) { bytesRead = 0; int lastSegmentLength = MaxCERSegmentSize; AsnReader tmpReader = new AsnReader(source, RuleSet); Stack <(AsnReader, bool, int)> readerStack = null; int totalLength = 0; Asn1Tag tag = Asn1Tag.ConstructedBitString; Span <byte> curDest = destination; do { while (tmpReader.HasData) { tag = tmpReader.ReadTagAndLength(out int?length, out int headerLength); if (tag == Asn1Tag.PrimitiveOctetString) { if (RuleSet == AsnEncodingRules.CER && lastSegmentLength != MaxCERSegmentSize) { // T-REC-X.690-201508 sec 9.2 throw new CryptographicException(SR.Resource("Cryptography_Der_Invalid_Encoding")); } Debug.Assert(length != null); // The call to Slice here sanity checks the data bounds, length.Value is not // reliable unless this call has succeeded. ReadOnlyMemory <byte> contents = Slice(tmpReader._data, headerLength, length.Value); int localLen = headerLength + contents.Length; tmpReader._data = tmpReader._data.Slice(localLen); bytesRead += localLen; totalLength += contents.Length; lastSegmentLength = contents.Length; if (RuleSet == AsnEncodingRules.CER && lastSegmentLength > MaxCERSegmentSize) { // T-REC-X.690-201508 sec 9.2 throw new CryptographicException(SR.Resource("Cryptography_Der_Invalid_Encoding")); } if (write) { contents.Span.CopyTo(curDest); curDest = curDest.Slice(contents.Length); } } else if (tag == Asn1Tag.EndOfContents && isIndefinite) { ValidateEndOfContents(tag, length, headerLength); bytesRead += headerLength; if (readerStack?.Count > 0) { (AsnReader topReader, bool wasIndefinite, int pushedBytesRead) = readerStack.Pop(); topReader._data = topReader._data.Slice(bytesRead); bytesRead += pushedBytesRead; isIndefinite = wasIndefinite; tmpReader = topReader; } else { // We have matched the EndOfContents that brought us here. break; } } else if (tag == Asn1Tag.ConstructedOctetString) { if (RuleSet == AsnEncodingRules.CER) { // T-REC-X.690-201508 sec 9.2 throw new CryptographicException(SR.Resource("Cryptography_Der_Invalid_Encoding")); } if (readerStack == null) { readerStack = new Stack <(AsnReader, bool, int)>(); } readerStack.Push((tmpReader, isIndefinite, bytesRead)); tmpReader = new AsnReader( Slice(tmpReader._data, headerLength, length), RuleSet); bytesRead = headerLength; isIndefinite = (length == null); } else { // T-REC-X.690-201508 sec 8.6.4.1 (in particular, Note 2) throw new CryptographicException(SR.Resource("Cryptography_Der_Invalid_Encoding")); } } if (isIndefinite && tag != Asn1Tag.EndOfContents) { throw new CryptographicException(SR.Resource("Cryptography_Der_Invalid_Encoding")); } if (readerStack?.Count > 0) { (AsnReader topReader, bool wasIndefinite, int pushedBytesRead) = readerStack.Pop(); tmpReader = topReader; tmpReader._data = tmpReader._data.Slice(bytesRead); isIndefinite = wasIndefinite; bytesRead += pushedBytesRead; } else { tmpReader = null; } } while (tmpReader != null); return(totalLength); }