internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : NegTokenInit, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); // Decode SEQUENCE OF for MechTypes { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <Oid>(); Oid tmpItem; while (collectionReader.HasData) { tmpItem = collectionReader.ReadObjectIdentifier(); tmpList.Add(tmpItem); } decoded.MechTypes = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); if (explicitReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpRequestFlags)) { decoded.RequestFlags = tmpRequestFlags; } else { decoded.RequestFlags = explicitReader.ReadBitString(out _); } explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); if (explicitReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpMechToken)) { decoded.MechToken = tmpMechToken; } else { decoded.MechToken = explicitReader.ReadOctetString(); } explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); if (explicitReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpMechListMic)) { decoded.MechListMic = tmpMechListMic; } else { decoded.MechListMic = explicitReader.ReadOctetString(); } explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
public static void ReadSequenceOf_PreservesOptions(AsnEncodingRules ruleSet) { // [5] (UtcTime) 500102123456Z // UtcTime 120102235959Z // // They're sorted backwards, though. const string PayloadHex = "850D3530303130323132333435365A" + "170D3132303130323233353935395A"; byte[] inputData; // Build the rule-specific form of SEQUENCE { [PRIVATE 9] SEQUENCE { SET-OF { dates }, NULL } } // The outer Set-Of is also invalid, because the NULL should be first. if (ruleSet == AsnEncodingRules.DER) { inputData = ("3024" + "E922" + "A21E" + PayloadHex + "0500").HexToByteArray(); } else { string inputHex = "3080" + "E980" + "A280" + PayloadHex + "0000" + "0500" + "0000" + "0000"; inputData = inputHex.HexToByteArray(); } AsnReaderOptions options = new AsnReaderOptions { SkipSetSortOrderVerification = true, UtcTimeTwoDigitYearMax = 2011, }; AsnReader initial = new AsnReader(inputData, ruleSet, options); AsnReader outer = initial.ReadSequence(); Assert.False(initial.HasData); AsnReader inner = outer.ReadSequence(new Asn1Tag(TagClass.Private, 9)); Assert.False(outer.HasData); Asn1Tag setTag = new Asn1Tag(TagClass.ContextSpecific, 2); if (ruleSet != AsnEncodingRules.BER) { Assert.Throws <AsnContentException>(() => inner.ReadSetOf(false, setTag)); } // This confirms that we've passed SkipSetOrderVerification this far. AsnReader setOf = inner.ReadSetOf(setTag); Assert.True(inner.HasData); Assert.Equal( new DateTimeOffset(1950, 1, 2, 12, 34, 56, TimeSpan.Zero), setOf.ReadUtcTime(new Asn1Tag(TagClass.ContextSpecific, 5))); // This confirms that we've passed UtcTimeTwoDigitYearMax, // the default would call this 2012. Assert.Equal( new DateTimeOffset(1912, 1, 2, 23, 59, 59, TimeSpan.Zero), setOf.ReadUtcTime()); Assert.False(setOf.HasData); inner.ReadNull(); Assert.False(inner.HasData); setOf.ThrowIfNotEmpty(); inner.ThrowIfNotEmpty(); outer.ThrowIfNotEmpty(); initial.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out TbsCertificateAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader defaultReader; AsnReader collectionReader; if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); if (!explicitReader.TryReadInt32(out decoded.Version)) { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); } else { defaultReader = new AsnReader(s_defaultVersion, AsnEncodingRules.DER); if (!defaultReader.TryReadInt32(out decoded.Version)) { defaultReader.ThrowIfNotEmpty(); } } decoded.SerialNumber = sequenceReader.ReadIntegerBytes(); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(sequenceReader, out decoded.SignatureAlgorithm); if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } decoded.Issuer = sequenceReader.ReadEncodedValue(); System.Security.Cryptography.X509Certificates.Asn1.ValidityAsn.Decode(sequenceReader, out decoded.Validity); if (!sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag((UniversalTagNumber)16))) { throw new CryptographicException(); } decoded.Subject = sequenceReader.ReadEncodedValue(); System.Security.Cryptography.Asn1.SubjectPublicKeyInfoAsn.Decode(sequenceReader, out decoded.SubjectPublicKeyInfo); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { if (sequenceReader.TryReadPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 1), out _, out ReadOnlyMemory <byte> tmpIssuerUniqueId)) { decoded.IssuerUniqueId = tmpIssuerUniqueId; } else { decoded.IssuerUniqueId = sequenceReader.ReadBitString(new Asn1Tag(TagClass.ContextSpecific, 1), out _); } } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { if (sequenceReader.TryReadPrimitiveBitStringValue(new Asn1Tag(TagClass.ContextSpecific, 2), out _, out ReadOnlyMemory <byte> tmpSubjectUniqueId)) { decoded.SubjectUniqueId = tmpSubjectUniqueId; } else { decoded.SubjectUniqueId = sequenceReader.ReadBitString(new Asn1Tag(TagClass.ContextSpecific, 2), out _); } } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); // Decode SEQUENCE OF for Extensions { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <System.Security.Cryptography.Asn1.X509ExtensionAsn>(); System.Security.Cryptography.Asn1.X509ExtensionAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.X509ExtensionAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.Extensions = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbCred, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); if (!explicitReader.TryReadInt32(out int tmpProtocolVersionNumber)) { explicitReader.ThrowIfNotEmpty(); } decoded.ProtocolVersionNumber = tmpProtocolVersionNumber; explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); if (!explicitReader.TryReadInt32(out MessageType tmpMessageType)) { explicitReader.ThrowIfNotEmpty(); } decoded.MessageType = tmpMessageType; explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); // Decode SEQUENCE OF for Tickets { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbTicket>(); KrbTicket tmpItem; while (collectionReader.HasData) { KrbTicket.Decode <KrbTicket>(collectionReader, out KrbTicket tmp); tmpItem = tmp; tmpList.Add(tmpItem); } decoded.Tickets = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); KrbEncryptedData.Decode <KrbEncryptedData>(explicitReader, out KrbEncryptedData tmpEncryptedPart); decoded.EncryptedPart = tmpEncryptedPart; explicitReader.ThrowIfNotEmpty(); sequenceReader.ThrowIfNotEmpty(); }
public override RSAParameters ExportParameters(bool includePrivateParameters) { // Apple requires all private keys to be exported encrypted, but since we're trying to export // as parsed structures we will need to decrypt it for the user. const string ExportPassword = "******"; SecKeyPair keys = GetKeys(); if (includePrivateParameters && keys.PrivateKey == null) { throw new CryptographicException(SR.Cryptography_OpenInvalidHandle); } byte[] keyBlob = Interop.AppleCrypto.SecKeyExport( includePrivateParameters ? keys.PrivateKey : keys.PublicKey, exportPrivate: includePrivateParameters, password: ExportPassword); try { if (!includePrivateParameters) { // When exporting a key handle opened from a certificate, it seems to // export as a PKCS#1 blob instead of an X509 SubjectPublicKeyInfo blob. // So, check for that. // NOTE: It doesn't affect macOS Mojave when SecCertificateCopyKey API // is used. RSAParameters key; AsnReader reader = new AsnReader(keyBlob, AsnEncodingRules.BER); AsnReader sequenceReader = reader.ReadSequence(); if (sequenceReader.PeekTag().Equals(Asn1Tag.Integer)) { AlgorithmIdentifierAsn ignored = default; RSAKeyFormatHelper.ReadRsaPublicKey(keyBlob, ignored, out key); } else { RSAKeyFormatHelper.ReadSubjectPublicKeyInfo( keyBlob, out int localRead, out key); Debug.Assert(localRead == keyBlob.Length); } return(key); } else { RSAKeyFormatHelper.ReadEncryptedPkcs8( keyBlob, ExportPassword, out int localRead, out RSAParameters key); return(key); } } finally { CryptographicOperations.ZeroMemory(keyBlob); } }
/// <summary> /// Decode the Tbs of the CRL. /// </summary> /// <param name="tbs">The raw TbsCertList of the CRL.</param> internal void DecodeCrl(byte[] tbs) { try { AsnReader crlReader = new AsnReader(tbs, AsnEncodingRules.DER); var tag = Asn1Tag.Sequence; var seqReader = crlReader.ReadSequence(tag); crlReader.ThrowIfNotEmpty(); if (seqReader != null) { // Version is OPTIONAL uint version = 0; var intTag = new Asn1Tag(UniversalTagNumber.Integer); var peekTag = seqReader.PeekTag(); if (peekTag == intTag) { if (seqReader.TryReadUInt32(out version)) { if (version != 1) { throw new AsnContentException($"The CRL contains an incorrect version {version}"); } } } // Signature Algorithm Identifier var sigReader = seqReader.ReadSequence(); var oid = sigReader.ReadObjectIdentifier(); m_hashAlgorithmName = Oids.GetHashAlgorithmName(oid); if (sigReader.HasData) { sigReader.ReadNull(); } sigReader.ThrowIfNotEmpty(); // Issuer m_issuerName = new X500DistinguishedName(seqReader.ReadEncodedValue().ToArray()); // thisUpdate m_thisUpdate = seqReader.ReadUtcTime().UtcDateTime; // nextUpdate is OPTIONAL var utcTag = new Asn1Tag(UniversalTagNumber.UtcTime); peekTag = seqReader.PeekTag(); if (peekTag == utcTag) { m_nextUpdate = seqReader.ReadUtcTime().UtcDateTime; } var seqTag = new Asn1Tag(UniversalTagNumber.Sequence, true); peekTag = seqReader.PeekTag(); if (peekTag == seqTag) { // revoked certificates var revReader = seqReader.ReadSequence(tag); var revokedCertificates = new List <RevokedCertificate>(); while (revReader.HasData) { var crlEntry = revReader.ReadSequence(); var serial = crlEntry.ReadInteger(); var revokedCertificate = new RevokedCertificate(serial.ToByteArray()); revokedCertificate.RevocationDate = crlEntry.ReadUtcTime().UtcDateTime; if (version == 1 && crlEntry.HasData) { // CRL entry extensions var crlEntryExtensions = crlEntry.ReadSequence(); while (crlEntryExtensions.HasData) { var extension = crlEntryExtensions.ReadExtension(); revokedCertificate.CrlEntryExtensions.Add(extension); } crlEntryExtensions.ThrowIfNotEmpty(); } crlEntry.ThrowIfNotEmpty(); revokedCertificates.Add(revokedCertificate); } revReader.ThrowIfNotEmpty(); m_revokedCertificates = revokedCertificates; } // CRL extensions OPTIONAL if (version == 1 && seqReader.HasData) { var extTag = new Asn1Tag(TagClass.ContextSpecific, 0); var optReader = seqReader.ReadSequence(extTag); var crlExtensionList = new X509ExtensionCollection(); var crlExtensions = optReader.ReadSequence(); while (crlExtensions.HasData) { var extension = crlExtensions.ReadExtension(); crlExtensionList.Add(extension); } m_crlExtensions = crlExtensionList; } seqReader.ThrowIfNotEmpty(); m_decoded = true; return; } throw new CryptographicException("The CRL contains ivalid data."); } catch (AsnContentException ace) { throw new CryptographicException("Failed to decode the CRL.", ace); } }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Rfc3161TstInfo decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader defaultReader; AsnReader collectionReader; if (!sequenceReader.TryReadInt32(out decoded.Version)) { sequenceReader.ThrowIfNotEmpty(); } decoded.Policy = sequenceReader.ReadObjectIdentifier(); System.Security.Cryptography.Pkcs.Asn1.MessageImprint.Decode(sequenceReader, out decoded.MessageImprint); decoded.SerialNumber = sequenceReader.ReadIntegerBytes(); decoded.GenTime = sequenceReader.ReadGeneralizedTime(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Sequence)) { System.Security.Cryptography.Pkcs.Asn1.Rfc3161Accuracy tmpAccuracy; System.Security.Cryptography.Pkcs.Asn1.Rfc3161Accuracy.Decode(sequenceReader, out tmpAccuracy); decoded.Accuracy = tmpAccuracy; } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Boolean)) { decoded.Ordering = sequenceReader.ReadBoolean(); } else { defaultReader = new AsnReader(s_defaultOrdering, AsnEncodingRules.DER); decoded.Ordering = defaultReader.ReadBoolean(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Integer)) { decoded.Nonce = sequenceReader.ReadIntegerBytes(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); System.Security.Cryptography.Asn1.GeneralNameAsn tmpTsa; System.Security.Cryptography.Asn1.GeneralNameAsn.Decode(explicitReader, out tmpTsa); decoded.Tsa = tmpTsa; explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { // Decode SEQUENCE OF for Extensions { collectionReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); var tmpList = new List <System.Security.Cryptography.Asn1.X509ExtensionAsn>(); System.Security.Cryptography.Asn1.X509ExtensionAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.X509ExtensionAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.Extensions = tmpList.ToArray(); } } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbKdcRep, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); if (!explicitReader.TryReadInt32(out decoded.ProtocolVersionNumber)) { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); if (!explicitReader.TryReadInt32(out decoded.MessageType)) { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); // Decode SEQUENCE OF for PaData { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbPaData>(); KrbPaData tmpItem; while (collectionReader.HasData) { KrbPaData.Decode <KrbPaData>(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.PaData = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); decoded.CRealm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString); explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4)); KrbPrincipalName.Decode <KrbPrincipalName>(explicitReader, out decoded.CName); explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 5)); KrbTicket.Decode <KrbTicket>(explicitReader, out decoded.Ticket); explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 6)); KrbEncryptedData.Decode <KrbEncryptedData>(explicitReader, out decoded.EncPart); explicitReader.ThrowIfNotEmpty(); sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbEncKrbCredPart, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); // Decode SEQUENCE OF for TicketInfo { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbCredInfo>(); KrbCredInfo tmpItem; while (collectionReader.HasData) { KrbCredInfo.Decode <KrbCredInfo>(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.TicketInfo = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); if (explicitReader.TryReadInt32(out int tmpNonce)) { decoded.Nonce = tmpNonce; } else { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); decoded.Timestamp = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); if (explicitReader.TryReadInt32(out int tmpUSec)) { decoded.USec = tmpUSec; } else { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 4))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4)); KrbHostAddress tmpSAddress; KrbHostAddress.Decode <KrbHostAddress>(explicitReader, out tmpSAddress); decoded.SAddress = tmpSAddress; explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 5))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 5)); KrbHostAddress tmpRAddress; KrbHostAddress.Decode <KrbHostAddress>(explicitReader, out tmpRAddress); decoded.RAddress = tmpRAddress; explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbKdcReqBody, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); if (explicitReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpKdcOptions)) { decoded.KdcOptions = (KdcOptions)tmpKdcOptions.AsLong(); } else { decoded.KdcOptions = (KdcOptions)explicitReader.ReadBitString(out _).AsLong(); } explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); KrbPrincipalName.Decode <KrbPrincipalName>(explicitReader, out KrbPrincipalName tmpCName); decoded.CName = tmpCName; explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); decoded.Realm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString); explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); KrbPrincipalName.Decode <KrbPrincipalName>(explicitReader, out KrbPrincipalName tmpSName); decoded.SName = tmpSName; explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 4))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4)); decoded.From = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 5)); decoded.Till = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 6)); decoded.RTime = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 7)); if (!explicitReader.TryReadInt32(out int tmpNonce)) { explicitReader.ThrowIfNotEmpty(); } decoded.Nonce = tmpNonce; explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 8)); // Decode SEQUENCE OF for EType { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <EncryptionType>(); EncryptionType tmpItem; while (collectionReader.HasData) { if (!collectionReader.TryReadInt32(out EncryptionType tmp)) { collectionReader.ThrowIfNotEmpty(); } tmpItem = tmp; tmpList.Add(tmpItem); } decoded.EType = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 9))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 9)); // Decode SEQUENCE OF for Addresses { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbHostAddress>(); KrbHostAddress tmpItem; while (collectionReader.HasData) { KrbHostAddress.Decode <KrbHostAddress>(collectionReader, out KrbHostAddress tmp); tmpItem = tmp; tmpList.Add(tmpItem); } decoded.Addresses = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 10))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 10)); KrbEncryptedData.Decode <KrbEncryptedData>(explicitReader, out KrbEncryptedData tmpEncAuthorizationData); decoded.EncAuthorizationData = tmpEncAuthorizationData; explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 11))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 11)); // Decode SEQUENCE OF for AdditionalTickets { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbTicket>(); KrbTicket tmpItem; while (collectionReader.HasData) { KrbTicket.Decode <KrbTicket>(collectionReader, out KrbTicket tmp); tmpItem = tmp; tmpList.Add(tmpItem); } decoded.AdditionalTickets = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbError, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); if (!explicitReader.TryReadInt32(out int tmpProtocolVersionNumber)) { explicitReader.ThrowIfNotEmpty(); } decoded.ProtocolVersionNumber = tmpProtocolVersionNumber; explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); if (!explicitReader.TryReadInt32(out MessageType tmpMessageType)) { explicitReader.ThrowIfNotEmpty(); } decoded.MessageType = tmpMessageType; explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); decoded.CTime = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); if (explicitReader.TryReadInt32(out int tmpCusec)) { decoded.Cusec = tmpCusec; } else { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4)); decoded.STime = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 5)); if (!explicitReader.TryReadInt32(out int tmpSusc)) { explicitReader.ThrowIfNotEmpty(); } decoded.Susc = tmpSusc; explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 6)); if (!explicitReader.TryReadInt32(out KerberosErrorCode tmpErrorCode)) { explicitReader.ThrowIfNotEmpty(); } decoded.ErrorCode = tmpErrorCode; explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 7))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 7)); decoded.CRealm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 8))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 8)); KrbPrincipalName.Decode <KrbPrincipalName>(explicitReader, out KrbPrincipalName tmpCName); decoded.CName = tmpCName; explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 9)); decoded.Realm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString); explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 10)); KrbPrincipalName.Decode <KrbPrincipalName>(explicitReader, out KrbPrincipalName tmpSName); decoded.SName = tmpSName; explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 11))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 11)); decoded.EText = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 12))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 12)); if (explicitReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpEData)) { decoded.EData = tmpEData; } else { decoded.EData = explicitReader.ReadOctetString(); } explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Rfc3161TimeStampReq decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader defaultReader; AsnReader collectionReader; if (!sequenceReader.TryReadInt32(out decoded.Version)) { sequenceReader.ThrowIfNotEmpty(); } System.Security.Cryptography.Pkcs.Asn1.MessageImprint.Decode(sequenceReader, out decoded.MessageImprint); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.ObjectIdentifier)) { decoded.ReqPolicy = sequenceReader.ReadObjectIdentifier(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Integer)) { decoded.Nonce = sequenceReader.GetIntegerBytes(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(Asn1Tag.Boolean)) { decoded.CertReq = sequenceReader.ReadBoolean(); } else { defaultReader = new AsnReader(s_defaultCertReq, AsnEncodingRules.DER); decoded.CertReq = defaultReader.ReadBoolean(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { // Decode SEQUENCE OF for Extensions { collectionReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); var tmpList = new List <System.Security.Cryptography.Asn1.X509ExtensionAsn>(); System.Security.Cryptography.Asn1.X509ExtensionAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.X509ExtensionAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.Extensions = tmpList.ToArray(); } } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : NegTokenResp, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); decoded.State = explicitReader.ReadEnumeratedValue <NegotiateState>(); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); decoded.SupportedMech = explicitReader.ReadObjectIdentifier(); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); if (explicitReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpResponseToken)) { decoded.ResponseToken = tmpResponseToken; } else { decoded.ResponseToken = explicitReader.ReadOctetString(); } explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); if (explicitReader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpMechListMic)) { decoded.MechListMic = tmpMechListMic; } else { decoded.MechListMic = explicitReader.ReadOctetString(); } explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
private static string FindAltNameMatch(byte[] extensionBytes, GeneralNameType matchType, string otherOid) { // If Other, have OID, else, no OID. Debug.Assert( (otherOid == null) == (matchType != GeneralNameType.OtherName), $"otherOid has incorrect nullarity for matchType {matchType}"); Debug.Assert( matchType == GeneralNameType.UniformResourceIdentifier || matchType == GeneralNameType.DnsName || matchType == GeneralNameType.Email || matchType == GeneralNameType.OtherName, $"matchType ({matchType}) is not currently supported"); Debug.Assert( otherOid == null || otherOid == Oids.UserPrincipalName, $"otherOid ({otherOid}) is not supported"); AsnReader reader = new AsnReader(extensionBytes, AsnEncodingRules.DER); AsnReader sequenceReader = reader.ReadSequence(); reader.ThrowIfNotEmpty(); while (sequenceReader.HasData) { GeneralNameAsn.Decode(sequenceReader, out GeneralNameAsn generalName); switch (matchType) { case GeneralNameType.OtherName: // If the OtherName OID didn't match, move to the next entry. if (generalName.OtherName.HasValue && generalName.OtherName.Value.TypeId == otherOid) { // Currently only UPN is supported, which is a UTF8 string per // https://msdn.microsoft.com/en-us/library/ff842518.aspx AsnReader nameReader = new AsnReader(generalName.OtherName.Value.Value, AsnEncodingRules.DER); string udnName = nameReader.GetCharacterString(UniversalTagNumber.UTF8String); nameReader.ThrowIfNotEmpty(); return(udnName); } break; case GeneralNameType.Rfc822Name: if (generalName.Rfc822Name != null) { return(generalName.Rfc822Name); } break; case GeneralNameType.DnsName: if (generalName.DnsName != null) { return(generalName.DnsName); } break; case GeneralNameType.UniformResourceIdentifier: if (generalName.Uri != null) { return(generalName.Uri); } break; } } return(null); }
public unsafe string ProcessNegotiateChallenge(string challengeString) { Console.WriteLine($"ChallengesString {challengeString}"); NegState state = NegState.Unknown; string mech = null; byte[] blob = null; byte[] data = Convert.FromBase64String(challengeString); AsnReader reader = new AsnReader(data, AsnEncodingRules.DER); AsnReader challengeReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp)); // NegTokenResp::= SEQUENCE { // negState[0] ENUMERATED { // accept - completed(0), // accept - incomplete(1), // reject(2), // request - mic(3) // } OPTIONAL, // --REQUIRED in the first reply from the target // supportedMech[1] MechType OPTIONAL, // --present only in the first reply from the target // responseToken[2] OCTET STRING OPTIONAL, // mechListMIC[3] OCTET STRING OPTIONAL, // ... // } challengeReader = challengeReader.ReadSequence(); while (challengeReader.HasData) { Asn1Tag tag = challengeReader.PeekTag(); if (tag.TagClass == TagClass.ContextSpecific) { NegTokenResp dataType = (NegTokenResp)tag.TagValue; AsnReader specificValue = new AsnReader(challengeReader.PeekContentBytes(), AsnEncodingRules.DER); switch (dataType) { case NegTokenResp.NegState: state = specificValue.ReadEnumeratedValue <NegState>(); break; case NegTokenResp.SupportedMech: mech = specificValue.ReadObjectIdentifier(); break; case NegTokenResp.ResponseToken: blob = specificValue.ReadOctetString(); break; default: // Ignore everything else break; } } challengeReader.ReadEncodedValue(); } if (Diag) { Console.WriteLine("Negotiate challenege: {0} - {1} in {2}", challengeString, mech, state); } // Mechanism should be set on first message. That means always // as NTLM has only one challenege message. if (!NtlmOid.Equals(mech)) { throw new NotSupportedException($"'{mech}' mechanism is not supported"); } if (state != NegState.Unknown && state != NegState.AcceptIncomplete) { // If state was set, it should be AcceptIncomplete for us to proseed. return(""); } if (blob?.Length > 0) { // Process decoded NTLM blob. byte[] response = ProcessChallengeMessage(blob); if (response?.Length > 0) { AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp))) { writer.PushSequence(); using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechToken))) { writer.WriteOctetString(response); } writer.PopSequence(); } return("Negotiate " + Convert.ToBase64String(writer.Encode(), Base64FormattingOptions.None)); } } return(""); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out Asn1ExtendedResponse decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new Asn1ExtendedResponse(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; decoded.ResultCode = sequenceReader.GetEnumeratedValue <ResultCode>(); if (sequenceReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpMatchedDN)) { decoded.MatchedDN = tmpMatchedDN; } else { decoded.MatchedDN = sequenceReader.ReadOctetString(); } if (sequenceReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmpDiagnosticMessage)) { decoded.DiagnosticMessage = tmpDiagnosticMessage; } else { decoded.DiagnosticMessage = sequenceReader.ReadOctetString(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { // Decode SEQUENCE OF for Referral { collectionReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); var tmpList = new List <ReadOnlyMemory <byte> >(); ReadOnlyMemory <byte> tmpItem; while (collectionReader.HasData) { if (collectionReader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> tmp)) { tmpItem = tmp; } else { tmpItem = collectionReader.ReadOctetString(); } tmpList.Add(tmpItem); } decoded.Referral = tmpList.ToArray(); } } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 10))) { if (sequenceReader.TryGetPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 10), out ReadOnlyMemory <byte> tmpName)) { decoded.Name = tmpName; } else { decoded.Name = sequenceReader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 10)); } } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 11))) { if (sequenceReader.TryGetPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 11), out ReadOnlyMemory <byte> tmpValue)) { decoded.Value = tmpValue; } else { decoded.Value = sequenceReader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 11)); } } sequenceReader.ThrowIfNotEmpty(); }
private string FormatSubjectAlternativeName(byte[] rawData) { // Because SubjectAlternativeName is a commonly parsed structure, we'll // specifically format this one. And we'll match the OpenSSL format, which // includes not localizing any of the values (or respecting the multiLine boolean) // // The intent here is to be functionally equivalent to OpenSSL GENERAL_NAME_print. try { StringBuilder output = new StringBuilder(); AsnReader reader = new AsnReader(rawData, AsnEncodingRules.DER); AsnReader collectionReader = reader.ReadSequence(); reader.ThrowIfNotEmpty(); while (collectionReader.HasData) { GeneralNameAsn.Decode(collectionReader, out GeneralNameAsn generalName); if (output.Length != 0) { output.Append(", "); } if (generalName.OtherName.HasValue) { output.Append("othername:<unsupported>"); } else if (generalName.Rfc822Name != null) { output.Append("email:"); output.Append(generalName.Rfc822Name); } else if (generalName.DnsName != null) { output.Append("DNS:"); output.Append(generalName.DnsName); } else if (generalName.X400Address != null) { output.Append("X400Name:<unsupported>"); } else if (generalName.DirectoryName != null) { // OpenSSL supports printing one of these, but the logic lives in X509Certificates, // and it isn't very common. So we'll skip this one until someone asks for it. output.Append("DirName:<unsupported>"); } else if (generalName.EdiPartyName != null) { output.Append("EdiPartyName:<unsupported>"); } else if (generalName.Uri != null) { output.Append("URI:"); output.Append(generalName.Uri); } else if (generalName.IPAddress.HasValue) { ReadOnlySpan <byte> ipAddressBytes = generalName.IPAddress.Value.Span; output.Append("IP Address"); if (ipAddressBytes.Length == 4) { // Add the colon and dotted-decimal representation of IPv4. output.Append( $":{ipAddressBytes[0]}.{ipAddressBytes[1]}.{ipAddressBytes[2]}.{ipAddressBytes[3]}"); } else if (ipAddressBytes.Length == 16) { // Print the IP Address value as colon separated UInt16 hex values without leading zeroes. // 20 01 0D B8 AC 10 FE 01 00 00 00 00 00 00 00 00 // // IP Address:2001:DB8:AC10:FE01:0:0:0:0 for (int i = 0; i < ipAddressBytes.Length; i += 2) { output.Append($":{ipAddressBytes[i] << 8 | ipAddressBytes[i + 1]:X}"); } } else { output.Append(":<invalid>"); } } else if (generalName.RegisteredId != null) { output.Append("Registered ID:"); output.Append(generalName.RegisteredId); } else { // A new extension to GeneralName could legitimately hit this, // but it's correct to say that until we know what that is that // the pretty-print has failed, and we should fall back to hex. // // But it could also simply be poorly encoded user data. return(null); } } return(output.ToString()); } catch (CryptographicException) { return(null); } }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbEncKdcRepPart, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); KrbEncryptionKey.Decode <KrbEncryptionKey>(explicitReader, out KrbEncryptionKey tmpKey); decoded.Key = tmpKey; explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); // Decode SEQUENCE OF for LastReq { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbLastReq>(); KrbLastReq tmpItem; while (collectionReader.HasData) { KrbLastReq.Decode <KrbLastReq>(collectionReader, out KrbLastReq tmp); tmpItem = tmp; tmpList.Add(tmpItem); } decoded.LastReq = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); if (!explicitReader.TryReadInt32(out int tmpNonce)) { explicitReader.ThrowIfNotEmpty(); } decoded.Nonce = tmpNonce; explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); decoded.KeyExpiration = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4)); if (explicitReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpFlags)) { decoded.Flags = (TicketFlags)tmpFlags.AsLong(); } else { decoded.Flags = (TicketFlags)explicitReader.ReadBitString(out _).AsLong(); } explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 5)); decoded.AuthTime = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 6)); decoded.StartTime = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 7)); decoded.EndTime = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 8))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 8)); decoded.RenewTill = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 9)); decoded.Realm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString); explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 10)); KrbPrincipalName.Decode <KrbPrincipalName>(explicitReader, out KrbPrincipalName tmpSName); decoded.SName = tmpSName; explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 11))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 11)); // Decode SEQUENCE OF for CAddr { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbHostAddress>(); KrbHostAddress tmpItem; while (collectionReader.HasData) { KrbHostAddress.Decode <KrbHostAddress>(collectionReader, out KrbHostAddress tmp); tmpItem = tmp; tmpList.Add(tmpItem); } decoded.CAddr = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 12))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 12)); KrbMethodData.Decode <KrbMethodData>(explicitReader, out KrbMethodData tmpEncryptedPaData); decoded.EncryptedPaData = tmpEncryptedPaData; explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode(AsnReader reader, out Asn1Filter decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new Asn1Filter(); Asn1Tag tag = reader.PeekTag(); AsnReader explicitReader; AsnReader collectionReader; if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { // Decode SEQUENCE OF for And { collectionReader = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0)); var tmpList = new List <Asn1Filter>(); Asn1Filter tmpItem; while (collectionReader.HasData) { Asn1Filter.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.And = tmpList.ToArray(); } } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { // Decode SEQUENCE OF for Or { collectionReader = reader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1)); var tmpList = new List <Asn1Filter>(); Asn1Filter tmpItem; while (collectionReader.HasData) { Asn1Filter.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.Or = tmpList.ToArray(); } } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { explicitReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); Asn1Filter tmpNot; Asn1Filter.Decode(explicitReader, out tmpNot); decoded.Not = tmpNot; explicitReader.ThrowIfNotEmpty(); } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { Asn1AttributeValueAssertion tmpEqualityMatch; Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 3), out tmpEqualityMatch); decoded.EqualityMatch = tmpEqualityMatch; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 4))) { Asn1SubstringFilter tmpSubstrings; Asn1SubstringFilter.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 4), out tmpSubstrings); decoded.Substrings = tmpSubstrings; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 5))) { Asn1AttributeValueAssertion tmpGreaterOrEqual; Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 5), out tmpGreaterOrEqual); decoded.GreaterOrEqual = tmpGreaterOrEqual; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6))) { Asn1AttributeValueAssertion tmpLessOrEqual; Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 6), out tmpLessOrEqual); decoded.LessOrEqual = tmpLessOrEqual; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 7))) { if (reader.TryGetPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 7), out ReadOnlyMemory <byte> tmpPresent)) { decoded.Present = tmpPresent; } else { decoded.Present = reader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 7)); } } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 8))) { Asn1AttributeValueAssertion tmpApproxMatch; Asn1AttributeValueAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 8), out tmpApproxMatch); decoded.ApproxMatch = tmpApproxMatch; } else if (tag.HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 9))) { Asn1MatchingRuleAssertion tmpExtensibleMatch; Asn1MatchingRuleAssertion.Decode(reader, new Asn1Tag(TagClass.ContextSpecific, 9), out tmpExtensibleMatch); decoded.ExtensibleMatch = tmpExtensibleMatch; } else { throw new CryptographicException(); } }
public static TBSCertificate Decode(AsnReader reader) { // https://tools.ietf.org/html/rfc5280 /* TBSCertificate ::= SEQUENCE { * version [0] EXPLICIT Version DEFAULT v1, * serialNumber CertificateSerialNumber, * signature AlgorithmIdentifier, * issuer Name, * validity Validity, * subject Name, * subjectPublicKeyInfo SubjectPublicKeyInfo, * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, * -- If present, version MUST be v2 or v3 * extensions [3] EXPLICIT Extensions OPTIONAL * -- If present, version MUST be v3 }*/ var sequence = reader.ReadSequence(); // version [0] EXPLICIT Version DEFAULT v1, // Version ::= INTEGER { v1(0), v2(1), v3(2) } if (!sequence.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { throw new CryptographicException(); } // workaround for reading interger with a context-specific tag var versionData = sequence.ReadEncodedValue().Slice(2); // strip outter tag: context-specific#0 var versionReader = new AsnReader(versionData, AsnEncodingRules.BER); if (!versionReader.TryReadInt32(out var version)) { versionReader.ThrowIfNotEmpty(); sequence.ThrowIfNotEmpty(); } // serialNumber CertificateSerialNumber, // CertificateSerialNumber ::= INTEGER var serialNumber = sequence.ReadInteger(); // signature AlgorithmIdentifier, var signature = AlgorithmIdentifier.Decode(sequence); // issuer Name, var issuer = DistinguishedName.Decode(sequence); // validity Validity, var validity = sequence.ReadEncodedValue(); // subject Name, var subject = DistinguishedName.Decode(sequence); // subjectPublicKeyInfo SubjectPublicKeyInfo, // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, // -- If present, version MUST be v2 or v3 // extensions [3] EXPLICIT Extensions OPTIONAL // -- If present, version MUST be v3 } var subjectPublicKeyInfo = sequence.ReadEncodedValue(); var issuerUniqueID = sequence.ReadOptional(1, (x, t) => x.ReadEncodedValue()); var subjectUniqueID = sequence.ReadOptional(2, (x, t) => x.ReadEncodedValue()); // extensions [3] EXPLICIT Extensions OPTIONAL // -- If present, version MUST be v3 } // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension var extensions = sequence.ReadOptional(3, (r, t) => r.ReadSequence(t), r => r.ReadSequenceOf(x => TBSCertificateExtension.Decode(x))); if (sequence.HasData) { sequence.PeekTag(); } sequence.ThrowIfNotEmpty(); return(new() { Version = version, SerialNumber = serialNumber, Signature = signature, Issuer = issuer, Validity = validity, Subject = subject, SubjectPublicKeyInfo = subjectPublicKeyInfo, IssuerUniqueID = issuerUniqueID, SubjectUniqueID = subjectUniqueID, Extensions = extensions, }); }
private static List <Pkcs12SafeBag> ReadBags(ReadOnlyMemory <byte> serialized) { List <SafeBagAsn> serializedBags = new List <SafeBagAsn>(); AsnReader reader = new AsnReader(serialized, AsnEncodingRules.BER); AsnReader sequenceReader = reader.ReadSequence(); reader.ThrowIfNotEmpty(); while (sequenceReader.HasData) { SafeBagAsn.Decode(sequenceReader, out SafeBagAsn serializedBag); serializedBags.Add(serializedBag); } if (serializedBags.Count == 0) { return(new List <Pkcs12SafeBag>(0)); } List <Pkcs12SafeBag> bags = new List <Pkcs12SafeBag>(serializedBags.Count); for (int i = 0; i < serializedBags.Count; i++) { ReadOnlyMemory <byte> bagValue = serializedBags[i].BagValue; Pkcs12SafeBag bag = null; try { switch (serializedBags[i].BagId) { case Oids.Pkcs12KeyBag: bag = new Pkcs12KeyBag(bagValue); break; case Oids.Pkcs12ShroudedKeyBag: bag = new Pkcs12ShroudedKeyBag(bagValue); break; case Oids.Pkcs12CertBag: bag = Pkcs12CertBag.DecodeValue(bagValue); break; case Oids.Pkcs12CrlBag: // Known, but no first-class support currently. break; case Oids.Pkcs12SecretBag: bag = Pkcs12SecretBag.DecodeValue(bagValue); break; case Oids.Pkcs12SafeContentsBag: bag = Pkcs12SafeContentsBag.Decode(bagValue); break; } } catch (CryptographicException) { } if (bag == null) { bag = new Pkcs12SafeBag.UnknownBag(serializedBags[i].BagId, bagValue); } bag.Attributes = SignerInfo.MakeAttributeCollection(serializedBags[i].BagAttributes); bags.Add(bag); } return(bags); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out EnvelopedDataAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; if (!sequenceReader.TryReadInt32(out decoded.Version)) { sequenceReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { System.Security.Cryptography.Pkcs.Asn1.OriginatorInfoAsn tmpOriginatorInfo; System.Security.Cryptography.Pkcs.Asn1.OriginatorInfoAsn.Decode(sequenceReader, new Asn1Tag(TagClass.ContextSpecific, 0), out tmpOriginatorInfo); decoded.OriginatorInfo = tmpOriginatorInfo; } // Decode SEQUENCE OF for RecipientInfos { collectionReader = sequenceReader.ReadSetOf(); var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.RecipientInfoAsn>(); System.Security.Cryptography.Pkcs.Asn1.RecipientInfoAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Pkcs.Asn1.RecipientInfoAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.RecipientInfos = tmpList.ToArray(); } System.Security.Cryptography.Pkcs.Asn1.EncryptedContentInfoAsn.Decode(sequenceReader, out decoded.EncryptedContentInfo); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { // Decode SEQUENCE OF for UnprotectedAttributes { collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1)); var tmpList = new List <System.Security.Cryptography.Asn1.AttributeAsn>(); System.Security.Cryptography.Asn1.AttributeAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.AttributeAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.UnprotectedAttributes = tmpList.ToArray(); } } sequenceReader.ThrowIfNotEmpty(); }
private static string X500DistinguishedNameDecode( byte[] encodedName, bool printOid, bool reverse, bool quoteIfNeeded, string dnSeparator, string multiValueSeparator, bool addTrailingDelimiter) { AsnReader x500NameReader = new AsnReader(encodedName, AsnEncodingRules.DER); AsnReader x500NameSequenceReader = x500NameReader.ReadSequence(); var rdnReaders = new List <AsnReader>(); x500NameReader.ThrowIfNotEmpty(); while (x500NameSequenceReader.HasData) { rdnReaders.Add(x500NameSequenceReader.ReadSetOf()); } // We need to allocate a StringBuilder to hold the data as we're building it, and there's the usual // arbitrary process of choosing a number that's "big enough" to minimize reallocations without wasting // too much space in the average case. // // So, let's look at an example of what our output might be. // // GitHub.com's SSL cert has a "pretty long" subject (partially due to the unknown OIDs): // businessCategory=Private Organization // 1.3.6.1.4.1.311.60.2.1.3=US // 1.3.6.1.4.1.311.60.2.1.2=Delaware // serialNumber=5157550 // street=548 4th Street // postalCode=94107 // C=US // ST=California // L=San Francisco // O=GitHub, Inc. // CN=github.com // // Which comes out to 228 characters using OpenSSL's default pretty-print // (openssl x509 -in github.cer -text -noout) // Throw in some "maybe-I-need-to-quote-this" quotes, and a couple of extra/extra-long O/OU values // and round that up to the next programmer number, and you get that 512 should avoid reallocations // in all but the most dire of cases. StringBuilder decodedName = new StringBuilder(512); int entryCount = rdnReaders.Count; bool printSpacing = false; for (int i = 0; i < entryCount; i++) { int loc = reverse ? entryCount - i - 1 : i; // RelativeDistinguishedName ::= // SET SIZE (1..MAX) OF AttributeTypeAndValue // // AttributeTypeAndValue::= SEQUENCE { // type AttributeType, // value AttributeValue } // // AttributeType::= OBJECT IDENTIFIER // // AttributeValue ::= ANY-- DEFINED BY AttributeType if (printSpacing) { decodedName.Append(dnSeparator); } else { printSpacing = true; } AsnReader rdnReader = rdnReaders[loc]; bool hadValue = false; while (rdnReader.HasData) { AsnReader tavReader = rdnReader.ReadSequence(); string oid = tavReader.ReadObjectIdentifierAsString(); string attributeValue = tavReader.ReadAnyAsnString(); tavReader.ThrowIfNotEmpty(); if (hadValue) { decodedName.Append(multiValueSeparator); } else { hadValue = true; } if (printOid) { AppendOid(decodedName, oid); } bool quote = quoteIfNeeded && NeedsQuoting(attributeValue); if (quote) { decodedName.Append('"'); // If the RDN itself had a quote within it, that quote needs to be escaped // with another quote. attributeValue = attributeValue.Replace("\"", "\"\""); } decodedName.Append(attributeValue); if (quote) { decodedName.Append('"'); } } } if (addTrailingDelimiter && decodedName.Length > 0) { decodedName.Append(dnSeparator); } return(decodedName.ToString()); }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbKdcReq, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); if (!explicitReader.TryReadInt32(out decoded.ProtocolVersionNumber)) { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); if (!explicitReader.TryReadInt32(out decoded.MessageType)) { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); // Decode SEQUENCE OF for PaData { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbPaData>(); KrbPaData tmpItem; while (collectionReader.HasData) { KrbPaData.Decode <KrbPaData>(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.PaData = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4)); KrbKdcReqBody.Decode <KrbKdcReqBody>(explicitReader, out decoded.Body); explicitReader.ThrowIfNotEmpty(); sequenceReader.ThrowIfNotEmpty(); }
public override RSAParameters ExportParameters(bool includePrivateParameters) { SecKeyPair keys = GetKeys(); if (includePrivateParameters && keys.PrivateKey == null) { throw new CryptographicException(SR.Cryptography_OpenInvalidHandle); } bool gotKeyBlob = Interop.AppleCrypto.TrySecKeyCopyExternalRepresentation( includePrivateParameters ? keys.PrivateKey ! : keys.PublicKey, out byte[] keyBlob); if (!gotKeyBlob) { return(ExportParametersFromLegacyKey(keys, includePrivateParameters)); } try { if (!includePrivateParameters) { // When exporting a key handle opened from a certificate, it seems to // export as a PKCS#1 blob instead of an X509 SubjectPublicKeyInfo blob. // So, check for that. // NOTE: It doesn't affect macOS Mojave when SecCertificateCopyKey API // is used. RSAParameters key; AsnReader reader = new AsnReader(keyBlob, AsnEncodingRules.BER); AsnReader sequenceReader = reader.ReadSequence(); if (sequenceReader.PeekTag().Equals(Asn1Tag.Integer)) { AlgorithmIdentifierAsn ignored = default; RSAKeyFormatHelper.ReadRsaPublicKey(keyBlob, ignored, out key); } else { RSAKeyFormatHelper.ReadSubjectPublicKeyInfo( keyBlob, out int localRead, out key); Debug.Assert(localRead == keyBlob.Length); } return(key); } else { AlgorithmIdentifierAsn ignored = default; RSAKeyFormatHelper.FromPkcs1PrivateKey( keyBlob, ignored, out RSAParameters key); return(key); } } finally { CryptographicOperations.ZeroMemory(keyBlob); } }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbCredInfo, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); KrbEncryptionKey.Decode <KrbEncryptionKey>(explicitReader, out decoded.Key); explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); decoded.Realm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); KrbPrincipalName tmpPName; KrbPrincipalName.Decode <KrbPrincipalName>(explicitReader, out tmpPName); decoded.PName = tmpPName; explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); if (explicitReader.TryReadPrimitiveBitStringValue(out _, out ReadOnlyMemory <byte> tmpFlags)) { decoded.Flags = (TicketFlags)tmpFlags.AsLong(); } else { decoded.Flags = (TicketFlags)explicitReader.ReadBitString(out _).AsLong(); } explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 4))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4)); decoded.AuthTime = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 5))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 5)); decoded.StartTime = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 6)); decoded.EndTime = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 7))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 7)); decoded.RenewTill = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 8))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 8)); decoded.SRealm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString); explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 9))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 9)); KrbPrincipalName tmpSName; KrbPrincipalName.Decode <KrbPrincipalName>(explicitReader, out tmpSName); decoded.SName = tmpSName; explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 10))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 10)); // Decode SEQUENCE OF for AuthorizationData { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbAuthorizationData>(); KrbAuthorizationData tmpItem; while (collectionReader.HasData) { KrbAuthorizationData.Decode <KrbAuthorizationData>(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.AuthorizationData = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
public static void ReadMicrosoftComCert() { byte[] bytes = MicrosoftDotComSslCertBytes; AsnReader fileReader = new AsnReader(bytes, AsnEncodingRules.DER); AsnReader certReader = fileReader.ReadSequence(); Assert.False(fileReader.HasData, "fileReader.HasData"); AsnReader tbsCertReader = certReader.ReadSequence(); AsnReader sigAlgReader = certReader.ReadSequence(); Assert.True( certReader.TryReadPrimitiveBitString( out int unusedBitCount, out ReadOnlyMemory <byte> signature), "certReader.TryReadPrimitiveBitStringValue"); Assert.Equal(0, unusedBitCount); AssertRefSame(signature, ref bytes[1176], "Signature is a ref to bytes[1176]"); Assert.False(certReader.HasData, "certReader.HasData"); AsnReader versionExplicitWrapper = tbsCertReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); Assert.True(versionExplicitWrapper.TryReadInt32(out int certVersion)); Assert.Equal(2, certVersion); Assert.False(versionExplicitWrapper.HasData, "versionExplicitWrapper.HasData"); ReadOnlyMemory <byte> serialBytes = tbsCertReader.ReadIntegerBytes(); AssertRefSame(serialBytes, ref bytes[15], "Serial number starts at bytes[15]"); AsnReader tbsSigAlgReader = tbsCertReader.ReadSequence(); Assert.Equal("1.2.840.113549.1.1.11", tbsSigAlgReader.ReadObjectIdentifier()); Assert.True(tbsSigAlgReader.HasData, "tbsSigAlgReader.HasData before ReadNull"); tbsSigAlgReader.ReadNull(); Assert.False(tbsSigAlgReader.HasData, "tbsSigAlgReader.HasData after ReadNull"); AsnReader issuerReader = tbsCertReader.ReadSequence(); Asn1Tag printableString = new Asn1Tag(UniversalTagNumber.PrintableString); AssertRdn(issuerReader, "2.5.4.6", 57, printableString, bytes, "issuer[C]"); AssertRdn(issuerReader, "2.5.4.10", 70, printableString, bytes, "issuer[O]"); AssertRdn(issuerReader, "2.5.4.11", 101, printableString, bytes, "issuer[OU]"); AssertRdn(issuerReader, "2.5.4.3", 134, printableString, bytes, "issuer[CN]"); Assert.False(issuerReader.HasData, "issuerReader.HasData"); AsnReader validityReader = tbsCertReader.ReadSequence(); Assert.Equal(new DateTimeOffset(2014, 10, 15, 0, 0, 0, TimeSpan.Zero), validityReader.ReadUtcTime()); Assert.Equal(new DateTimeOffset(2016, 10, 15, 23, 59, 59, TimeSpan.Zero), validityReader.ReadUtcTime()); Assert.False(validityReader.HasData, "validityReader.HasData"); AsnReader subjectReader = tbsCertReader.ReadSequence(); Asn1Tag utf8String = new Asn1Tag(UniversalTagNumber.UTF8String); AssertRdn(subjectReader, "1.3.6.1.4.1.311.60.2.1.3", 220, printableString, bytes, "subject[EV Country]"); AssertRdn(subjectReader, "1.3.6.1.4.1.311.60.2.1.2", 241, utf8String, bytes, "subject[EV State]", "Washington"); AssertRdn(subjectReader, "2.5.4.15", 262, printableString, bytes, "subject[Business Category]"); AssertRdn(subjectReader, "2.5.4.5", 293, printableString, bytes, "subject[Serial Number]"); AssertRdn(subjectReader, "2.5.4.6", 313, printableString, bytes, "subject[C]"); AssertRdn(subjectReader, "2.5.4.17", 326, utf8String, bytes, "subject[Postal Code]", "98052"); AssertRdn(subjectReader, "2.5.4.8", 342, utf8String, bytes, "subject[ST]", "Washington"); AssertRdn(subjectReader, "2.5.4.7", 363, utf8String, bytes, "subject[L]", "Redmond"); AssertRdn(subjectReader, "2.5.4.9", 381, utf8String, bytes, "subject[Street Address]", "1 Microsoft Way"); AssertRdn(subjectReader, "2.5.4.10", 407, utf8String, bytes, "subject[O]", "Microsoft Corporation"); AssertRdn(subjectReader, "2.5.4.11", 439, utf8String, bytes, "subject[OU]", "MSCOM"); AssertRdn(subjectReader, "2.5.4.3", 455, utf8String, bytes, "subject[CN]", "www.microsoft.com"); Assert.False(subjectReader.HasData, "subjectReader.HasData"); AsnReader subjectPublicKeyInfo = tbsCertReader.ReadSequence(); AsnReader spkiAlgorithm = subjectPublicKeyInfo.ReadSequence(); Assert.Equal("1.2.840.113549.1.1.1", spkiAlgorithm.ReadObjectIdentifier()); spkiAlgorithm.ReadNull(); Assert.False(spkiAlgorithm.HasData, "spkiAlgorithm.HasData"); Assert.True( subjectPublicKeyInfo.TryReadPrimitiveBitString( out unusedBitCount, out ReadOnlyMemory <byte> encodedPublicKey), "subjectPublicKeyInfo.TryReadBitStringBytes"); Assert.Equal(0, unusedBitCount); AssertRefSame(encodedPublicKey, ref bytes[498], "Encoded public key starts at byte 498"); Assert.False(subjectPublicKeyInfo.HasData, "subjectPublicKeyInfo.HasData"); AsnReader publicKeyReader = new AsnReader(encodedPublicKey, AsnEncodingRules.DER); AsnReader rsaPublicKeyReader = publicKeyReader.ReadSequence(); AssertRefSame(rsaPublicKeyReader.ReadIntegerBytes(), ref bytes[506], "RSA Modulus is at bytes[502]"); Assert.True(rsaPublicKeyReader.TryReadInt32(out int rsaExponent)); Assert.Equal(65537, rsaExponent); Assert.False(rsaPublicKeyReader.HasData, "rsaPublicKeyReader.HasData"); Assert.False(publicKeyReader.HasData, "publicKeyReader.HasData"); AsnReader extensionsContainer = tbsCertReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); AsnReader extensions = extensionsContainer.ReadSequence(); Assert.False(extensionsContainer.HasData, "extensionsContainer.HasData"); AsnReader sanExtension = extensions.ReadSequence(); Assert.Equal("2.5.29.17", sanExtension.ReadObjectIdentifier()); Assert.True(sanExtension.TryReadPrimitiveOctetString(out ReadOnlyMemory <byte> sanExtensionBytes)); Assert.False(sanExtension.HasData, "sanExtension.HasData"); AsnReader sanExtensionPayload = new AsnReader(sanExtensionBytes, AsnEncodingRules.DER); AsnReader sanExtensionValue = sanExtensionPayload.ReadSequence(); Assert.False(sanExtensionPayload.HasData, "sanExtensionPayload.HasData"); Asn1Tag dnsName = new Asn1Tag(TagClass.ContextSpecific, 2); Assert.Equal("www.microsoft.com", sanExtensionValue.ReadCharacterString(UniversalTagNumber.IA5String, dnsName)); Assert.Equal("wwwqa.microsoft.com", sanExtensionValue.ReadCharacterString(UniversalTagNumber.IA5String, dnsName)); Assert.False(sanExtensionValue.HasData, "sanExtensionValue.HasData"); AsnReader basicConstraints = extensions.ReadSequence(); Assert.Equal("2.5.29.19", basicConstraints.ReadObjectIdentifier()); Assert.True(basicConstraints.TryReadPrimitiveOctetString(out ReadOnlyMemory <byte> basicConstraintsBytes)); AsnReader basicConstraintsPayload = new AsnReader(basicConstraintsBytes, AsnEncodingRules.DER); AsnReader basicConstraintsValue = basicConstraintsPayload.ReadSequence(); Assert.False(basicConstraintsValue.HasData, "basicConstraintsValue.HasData"); Assert.False(basicConstraintsPayload.HasData, "basicConstraintsPayload.HasData"); AsnReader keyUsageExtension = extensions.ReadSequence(); Assert.Equal("2.5.29.15", keyUsageExtension.ReadObjectIdentifier()); Assert.True(keyUsageExtension.ReadBoolean(), "keyUsageExtension.ReadBoolean() (IsCritical)"); Assert.True(keyUsageExtension.TryReadPrimitiveOctetString(out ReadOnlyMemory <byte> keyUsageBytes)); AsnReader keyUsagePayload = new AsnReader(keyUsageBytes, AsnEncodingRules.DER); Assert.Equal( X509KeyUsageCSharpStyle.DigitalSignature | X509KeyUsageCSharpStyle.KeyEncipherment, keyUsagePayload.ReadNamedBitListValue <X509KeyUsageCSharpStyle>()); Assert.False(keyUsagePayload.HasData, "keyUsagePayload.HasData"); AssertExtension(extensions, "2.5.29.37", false, 863, bytes); AssertExtension(extensions, "2.5.29.32", false, 894, bytes); AssertExtension(extensions, "2.5.29.35", false, 998, bytes); AssertExtension(extensions, "2.5.29.31", false, 1031, bytes); AssertExtension(extensions, "1.3.6.1.5.5.7.1.1", false, 1081, bytes); Assert.False(extensions.HasData, "extensions.HasData"); Assert.Equal("1.2.840.113549.1.1.11", sigAlgReader.ReadObjectIdentifier()); sigAlgReader.ReadNull(); Assert.False(sigAlgReader.HasData); }
internal static void Decode(AsnReader reader, Asn1Tag expectedTag, out SignedDataAsn decoded) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = default; AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader collectionReader; if (!sequenceReader.TryReadInt32(out decoded.Version)) { sequenceReader.ThrowIfNotEmpty(); } // Decode SEQUENCE OF for DigestAlgorithms { collectionReader = sequenceReader.ReadSetOf(); var tmpList = new List <System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn>(); System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Asn1.AlgorithmIdentifierAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.DigestAlgorithms = tmpList.ToArray(); } System.Security.Cryptography.Pkcs.Asn1.EncapsulatedContentInfoAsn.Decode(sequenceReader, out decoded.EncapContentInfo); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 0))) { // Decode SEQUENCE OF for CertificateSet { collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 0)); var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn>(); System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Pkcs.Asn1.CertificateChoiceAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.CertificateSet = tmpList.ToArray(); } } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { // Decode SEQUENCE OF for Crls { collectionReader = sequenceReader.ReadSetOf(new Asn1Tag(TagClass.ContextSpecific, 1)); var tmpList = new List <ReadOnlyMemory <byte> >(); ReadOnlyMemory <byte> tmpItem; while (collectionReader.HasData) { tmpItem = collectionReader.ReadEncodedValue(); tmpList.Add(tmpItem); } decoded.Crls = tmpList.ToArray(); } } // Decode SEQUENCE OF for SignerInfos { collectionReader = sequenceReader.ReadSetOf(); var tmpList = new List <System.Security.Cryptography.Pkcs.Asn1.SignerInfoAsn>(); System.Security.Cryptography.Pkcs.Asn1.SignerInfoAsn tmpItem; while (collectionReader.HasData) { System.Security.Cryptography.Pkcs.Asn1.SignerInfoAsn.Decode(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.SignerInfos = tmpList.ToArray(); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbAuthenticator, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 0)); if (!explicitReader.TryReadInt32(out int tmpAuthenticatorVersionNumber)) { explicitReader.ThrowIfNotEmpty(); } decoded.AuthenticatorVersionNumber = tmpAuthenticatorVersionNumber; explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); decoded.Realm = explicitReader.ReadCharacterString(UniversalTagNumber.GeneralString); explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 2)); KrbPrincipalName.Decode <KrbPrincipalName>(explicitReader, out KrbPrincipalName tmpCName); decoded.CName = tmpCName; explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 3))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 3)); KrbChecksum.Decode <KrbChecksum>(explicitReader, out KrbChecksum tmpChecksum); decoded.Checksum = tmpChecksum; explicitReader.ThrowIfNotEmpty(); } explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 4)); if (!explicitReader.TryReadInt32(out int tmpCuSec)) { explicitReader.ThrowIfNotEmpty(); } decoded.CuSec = tmpCuSec; explicitReader.ThrowIfNotEmpty(); explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 5)); decoded.CTime = explicitReader.ReadGeneralizedTime(); explicitReader.ThrowIfNotEmpty(); if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 6))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 6)); KrbEncryptionKey.Decode <KrbEncryptionKey>(explicitReader, out KrbEncryptionKey tmpSubkey); decoded.Subkey = tmpSubkey; explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 7))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 7)); if (explicitReader.TryReadInt32(out int tmpSequenceNumber)) { decoded.SequenceNumber = tmpSequenceNumber; } else { explicitReader.ThrowIfNotEmpty(); } explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 8))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 8)); // Decode SEQUENCE OF for AuthorizationData { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbAuthorizationData>(); KrbAuthorizationData tmpItem; while (collectionReader.HasData) { KrbAuthorizationData.Decode <KrbAuthorizationData>(collectionReader, out KrbAuthorizationData tmp); tmpItem = tmp; tmpList.Add(tmpItem); } decoded.AuthorizationData = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); } sequenceReader.ThrowIfNotEmpty(); }
internal static void Decode <T>(AsnReader reader, Asn1Tag expectedTag, out T decoded) where T : KrbPaPkAsReq, new() { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } decoded = new T(); AsnReader sequenceReader = reader.ReadSequence(expectedTag); AsnReader explicitReader; AsnReader collectionReader; if (sequenceReader.TryReadPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 0), out ReadOnlyMemory <byte> tmpSignedAuthPack)) { decoded.SignedAuthPack = tmpSignedAuthPack; } else { decoded.SignedAuthPack = sequenceReader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 0)); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 1))) { explicitReader = sequenceReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, 1)); // Decode SEQUENCE OF for TrustedCertifiers { collectionReader = explicitReader.ReadSequence(); var tmpList = new List <KrbExternalPrincipalIdentifier>(); KrbExternalPrincipalIdentifier tmpItem; while (collectionReader.HasData) { KrbExternalPrincipalIdentifier.Decode <KrbExternalPrincipalIdentifier>(collectionReader, out tmpItem); tmpList.Add(tmpItem); } decoded.TrustedCertifiers = tmpList.ToArray(); } explicitReader.ThrowIfNotEmpty(); } if (sequenceReader.HasData && sequenceReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, 2))) { if (sequenceReader.TryReadPrimitiveOctetStringBytes(new Asn1Tag(TagClass.ContextSpecific, 2), out ReadOnlyMemory <byte> tmpKdcPkId)) { decoded.KdcPkId = tmpKdcPkId; } else { decoded.KdcPkId = sequenceReader.ReadOctetString(new Asn1Tag(TagClass.ContextSpecific, 2)); } } sequenceReader.ThrowIfNotEmpty(); }