public static void PeekEncodedValue_Primitive() { const string EncodedContents = "010203040506"; const string EncodedValue = "0406" + EncodedContents; byte[] data = (EncodedValue + "0500").HexToByteArray(); AsnReader reader = new AsnReader(data, AsnEncodingRules.BER); Assert.Equal(EncodedValue, reader.PeekEncodedValue().ByteArrayToHex()); // It's Peek, so it's reproducible. Assert.Equal(EncodedValue, reader.PeekEncodedValue().ByteArrayToHex()); }
public virtual unsafe void ImportRSAPrivateKey(ReadOnlySpan <byte> source, out int bytesRead) { fixed(byte *ptr = &MemoryMarshal.GetReference(source)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length)) { AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER); ReadOnlyMemory <byte> firstValue = reader.PeekEncodedValue(); int localRead = firstValue.Length; AlgorithmIdentifierAsn ignored = default; RSAKeyFormatHelper.FromPkcs1PrivateKey(firstValue, ignored, out RSAParameters rsaParameters); fixed(byte *dPin = rsaParameters.D) fixed(byte *pPin = rsaParameters.P) fixed(byte *qPin = rsaParameters.Q) fixed(byte *dpPin = rsaParameters.DP) fixed(byte *dqPin = rsaParameters.DQ) fixed(byte *qInvPin = rsaParameters.InverseQ) { try { ImportParameters(rsaParameters); } finally { ClearPrivateParameters(rsaParameters); } } bytesRead = localRead; } } }
public static void PeekEncodedValue_ExtremelyNested(bool fullArray) { byte[] dataBytes = new byte[4 * 16384]; // For a full array this will build 2^14 nested indefinite length values. // PeekEncodedValue should return the whole array. int end = dataBytes.Length / 2; int expectedLength = dataBytes.Length; if (!fullArray) { // Use 3/4 of what's available, just to prove we're not counting from the end. // So with "full" being a nesting value 16384 this will use 12288, and // PeekEncodedValue should give us back 48k, not 64k. end = end / 4 * 3; expectedLength = 2 * end; } for (int i = 0; i < end; i += 2) { // Context-Specific 0 [Constructed] dataBytes[i] = 0xA0; // Indefinite length dataBytes[i + 1] = 0x80; } AsnReader reader = new AsnReader(dataBytes, AsnEncodingRules.BER); ReadOnlyMemory <byte> contents = reader.PeekEncodedValue(); Assert.Equal(expectedLength, contents.Length); Assert.True(Unsafe.AreSame(ref dataBytes[0], ref contents.Span.DangerousGetPinnableReference())); }
public override unsafe void ImportRSAPublicKey(ReadOnlySpan <byte> source, out int bytesRead) { ThrowIfDisposed(); fixed(byte *ptr = &MemoryMarshal.GetReference(source)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length)) { AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER); ReadOnlyMemory <byte> firstElement = reader.PeekEncodedValue(); SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn { Algorithm = new AlgorithmIdentifierAsn { Algorithm = new Oid(Oids.Rsa), Parameters = AlgorithmIdentifierAsn.ExplicitDerNull, }, SubjectPublicKey = firstElement, }; using (AsnWriter writer = new AsnWriter(AsnEncodingRules.DER)) { spki.Encode(writer); ImportSubjectPublicKeyInfo(writer.EncodeAsSpan(), out _); } bytesRead = firstElement.Length; } } }
public static ReadOnlyMemory <byte> DecodeOctetStringAsMemory(ReadOnlyMemory <byte> encodedOctetString) { AsnReader reader = new AsnReader(encodedOctetString, AsnEncodingRules.BER); if (reader.PeekEncodedValue().Length != encodedOctetString.Length) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } // Almost everything in X.509 is DER-encoded, which means Octet String values are // encoded as a primitive (non-segmented) // // Even in BER Octet Strings are usually encoded as a primitive. if (reader.TryReadPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> primitiveContents)) { return(primitiveContents); } byte[] tooBig = new byte[encodedOctetString.Length]; if (reader.TryCopyOctetStringBytes(tooBig, out int bytesWritten)) { return(tooBig.AsMemory(0, bytesWritten)); } Debug.Fail("TryCopyOctetStringBytes failed with an over-allocated array"); throw new CryptographicException(); }
public override unsafe void ImportRSAPublicKey(ReadOnlySpan <byte> source, out int bytesRead) { ThrowIfDisposed(); fixed(byte *ptr = &MemoryMarshal.GetReference(source)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length)) { AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER); ReadOnlyMemory <byte> firstElement = reader.PeekEncodedValue(); SafeRsaHandle key = Interop.Crypto.DecodeRsaPublicKey(firstElement.Span); Interop.Crypto.CheckValidOpenSslHandle(key); FreeKey(); _key = new Lazy <SafeRsaHandle>(key); // Use ForceSet instead of the property setter to ensure that LegalKeySizes doesn't interfere // with the already loaded key. ForceSetKeySize(BitsPerByte * Interop.Crypto.RsaSize(key)); bytesRead = firstElement.Length; } } }
private static bool TryDecode( ReadOnlyMemory <byte> source, bool ownsMemory, out Rfc3161TstInfo tstInfo, out int bytesConsumed, out byte[] copiedBytes) { // https://tools.ietf.org/html/rfc3161#section-2.4.2 // The eContent SHALL be the DER-encoded value of TSTInfo. AsnReader reader = new AsnReader(source, AsnEncodingRules.DER); try { ReadOnlyMemory <byte> firstElement = reader.PeekEncodedValue(); if (ownsMemory) { copiedBytes = null; } else { // Copy the data so no ReadOnlyMemory values are pointing back to user data. copiedBytes = firstElement.ToArray(); firstElement = copiedBytes; } Rfc3161TstInfo parsedInfo = AsnSerializer.Deserialize <Rfc3161TstInfo>( firstElement, AsnEncodingRules.DER); // The deserializer doesn't do bounds checks. // Micros and Millis are defined as (1..999) // Seconds doesn't define that it's bounded by 0, // but negative accuracy doesn't make sense. // // (Reminder to readers: a null int? with an inequality operator // has the value false, so if accuracy is missing, or millis or micro is missing, // then the respective checks return false and don't throw). if (parsedInfo.Accuracy?.Micros > 999 || parsedInfo.Accuracy?.Micros < 1 || parsedInfo.Accuracy?.Millis > 999 || parsedInfo.Accuracy?.Millis < 1 || parsedInfo.Accuracy?.Seconds < 0) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } tstInfo = parsedInfo; bytesConsumed = firstElement.Length; return(true); } catch (CryptographicException) { tstInfo = null; bytesConsumed = 0; copiedBytes = null; return(false); } }
public static T Deserialize <T>(ReadOnlyMemory <byte> source, AsnEncodingRules ruleSet, out int bytesRead) { Deserializer deserializer = GetDeserializer(typeof(T), null); AsnReader reader = new AsnReader(source, ruleSet); ReadOnlyMemory <byte> firstElement = reader.PeekEncodedValue(); T t = (T)deserializer(reader); bytesRead = firstElement.Length; return(t); }
public static void PeekContentSpan_Indefinite() { const string EncodedContents = "040101" + "04050203040506"; const string EncodedValue = "2480" + EncodedContents + "0000"; byte[] data = (EncodedValue + "0500").HexToByteArray(); AsnReader reader = new AsnReader(data, AsnEncodingRules.BER); Assert.Equal(EncodedContents, reader.PeekContentBytes().ByteArrayToHex()); // It's Peek, so it's reproducible. Assert.Equal(EncodedValue, reader.PeekEncodedValue().ByteArrayToHex()); }
public override unsafe void ImportRSAPublicKey(ReadOnlySpan <byte> source, out int bytesRead) { ThrowIfDisposed(); fixed(byte *ptr = &MemoryMarshal.GetReference(source)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length)) { ReadOnlyMemory <byte> subjectPublicKey; try { AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER); subjectPublicKey = reader.PeekEncodedValue(); } catch (AsnContentException e) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding, e); } // Decoding the key on Android requires the encoded SubjectPublicKeyInfo, // not just the SubjectPublicKey, so we construct one. SubjectPublicKeyInfoAsn spki = new SubjectPublicKeyInfoAsn { Algorithm = new AlgorithmIdentifierAsn { Algorithm = Oids.Rsa, Parameters = AlgorithmIdentifierAsn.ExplicitDerNull, }, SubjectPublicKey = subjectPublicKey, }; AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); spki.Encode(writer); SafeRsaHandle key = Interop.AndroidCrypto.DecodeRsaSubjectPublicKeyInfo(writer.Encode()); if (key is null || key.IsInvalid) { key?.Dispose(); throw new CryptographicException(); } FreeKey(); _key = new Lazy <SafeRsaHandle>(key); SetKeySizeFromHandle(key); bytesRead = subjectPublicKey.Length; } } }
internal static unsafe ECParameters FromECPrivateKey(ReadOnlySpan <byte> key, out int bytesRead) { fixed(byte *ptr = &MemoryMarshal.GetReference(key)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, key.Length)) { AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER); AlgorithmIdentifierAsn algId = default; ReadOnlyMemory <byte> firstValue = reader.PeekEncodedValue(); FromECPrivateKey(firstValue, algId, out ECParameters ret); bytesRead = firstValue.Length; return(ret); } } }
public static void PeekEncodedValue_Corrupt_Throws() { const string EncodedContents = "040101" + "04050203040506"; // Constructed bit isn't set, so indefinite length is invalid. const string EncodedValue = "0480" + EncodedContents + "0000"; byte[] data = (EncodedValue + "0500").HexToByteArray(); Assert.Throws <CryptographicException>( () => { AsnReader reader = new AsnReader(data, AsnEncodingRules.BER); reader.PeekEncodedValue(); }); }
public virtual unsafe void ImportRSAPublicKey(ReadOnlySpan <byte> source, out int bytesRead) { fixed(byte *ptr = &MemoryMarshal.GetReference(source)) { using (MemoryManager <byte> manager = new PointerMemoryManager <byte>(ptr, source.Length)) { AsnReader reader = new AsnReader(manager.Memory, AsnEncodingRules.BER); ReadOnlyMemory <byte> firstValue = reader.PeekEncodedValue(); int localRead = firstValue.Length; AlgorithmIdentifierAsn ignored = default; RSAKeyFormatHelper.ReadRsaPublicKey(firstValue, ignored, out RSAParameters rsaParameters); ImportParameters(rsaParameters); bytesRead = localRead; } } }
protected void ParsePkcs12(byte[] data) { // RFC7292 specifies BER instead of DER AsnReader reader = new AsnReader(data, AsnEncodingRules.BER); ReadOnlyMemory <byte> encodedData = reader.PeekEncodedValue(); // Windows compatibility: Ignore trailing data. if (encodedData.Length != data.Length) { reader = new AsnReader(encodedData, AsnEncodingRules.BER); } PfxAsn.Decode(reader, out PfxAsn pfxAsn); if (pfxAsn.AuthSafe.ContentType != Oids.Pkcs7Data) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } _pfxAsn = pfxAsn; }
public static void PeekEncodedValue_InvalidLength() { byte[] badLength = "04040203".HexToByteArray(); AsnReader reader = new AsnReader(badLength, AsnEncodingRules.BER); Assert.Throws <CryptographicException>(() => reader.PeekEncodedValue()); Assert.Throws <CryptographicException>(() => reader.ReadEncodedValue()); Assert.Throws <CryptographicException>( () => { AsnValueReader valueReader = new AsnValueReader(badLength, AsnEncodingRules.BER); valueReader.PeekEncodedValue(); }); Assert.Throws <CryptographicException>( () => { AsnValueReader valueReader = new AsnValueReader(badLength, AsnEncodingRules.BER); valueReader.ReadEncodedValue(); }); }
public static void PeekEncodedValue_InvalidLength() { byte[] badLength = "04040203".HexToByteArray(); AsnReader reader = new AsnReader(badLength, AsnEncodingRules.BER); Assert.Throws <AsnContentException>(() => reader.PeekEncodedValue()); Assert.Throws <AsnContentException>(() => reader.ReadEncodedValue()); Assert.False( AsnDecoder.TryReadEncodedValue( badLength, AsnEncodingRules.BER, out Asn1Tag tag, out int contentOffset, out int contentLength, out int bytesConsumed)); Assert.Equal(0, contentOffset); Assert.Equal(0, contentLength); Assert.Equal(0, bytesConsumed); Assert.Equal(default(Asn1Tag), tag); }
public static bool TryDecode( ReadOnlyMemory <byte> encodedBytes, out Rfc3161TimestampRequest request, out int bytesConsumed) { try { // RFC 3161 doesn't have a concise statement that TimeStampReq will // be DER encoded, but under the email protocol (3.1), file protocol (3.2), // socket protocol (3.3) and HTTP protocol (3.4) they all say DER for the // transmission. // // Since nothing says BER, assume DER only. const AsnEncodingRules RuleSet = AsnEncodingRules.DER; AsnReader reader = new AsnReader(encodedBytes, RuleSet); ReadOnlyMemory <byte> firstElement = reader.PeekEncodedValue(); var req = AsnSerializer.Deserialize <Rfc3161TimeStampReq>(firstElement, RuleSet); request = new Rfc3161TimestampRequest { _parsedData = req, _encodedBytes = firstElement.ToArray(), }; bytesConsumed = firstElement.Length; return(true); } catch (CryptographicException) { } request = null; bytesConsumed = 0; return(false); }
public static ReadOnlyMemory <byte> DecodeOctetString(ReadOnlyMemory <byte> encodedOctetString) { AsnReader reader = new AsnReader(encodedOctetString, AsnEncodingRules.BER); if (reader.PeekEncodedValue().Length != encodedOctetString.Length) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } if (reader.TryGetPrimitiveOctetStringBytes(out ReadOnlyMemory <byte> primitiveContents)) { return(primitiveContents); } byte[] tooBig = new byte[encodedOctetString.Length]; if (reader.TryCopyOctetStringBytes(tooBig, out int bytesWritten)) { return(tooBig.AsMemory(0, bytesWritten)); } Debug.Fail("TryCopyOctetStringBytes failed with an over-allocated array"); throw new CryptographicException(); }
public byte[]? GetOutgoingBlob(byte[]?incomingBlob) { if (_spnegoMechList == null && incomingBlob.AsSpan().StartsWith(NtlmHeader)) { _ntlmPassthrough = true; // Windows often sends pure NTLM instead of proper Negotiate, handle that as passthrough byte[]? outgoingBlob = _ntlmServer.GetOutgoingBlob(incomingBlob); IsAuthenticated = _ntlmServer.IsAuthenticated; return(outgoingBlob); } Assert.False(_ntlmPassthrough); AsnReader reader = new AsnReader(incomingBlob, AsnEncodingRules.DER); if (_spnegoMechList == null) { AsnReader initialContextTokenReader = reader.ReadSequence(new Asn1Tag(TagClass.Application, 0)); string spNegoOid = initialContextTokenReader.ReadObjectIdentifier(); Assert.Equal(SpnegoOid, spNegoOid); AsnReader negTokenInitReader = initialContextTokenReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenInit)).ReadSequence(); AsnReader mechTypesOuterReader = negTokenInitReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechTypes)); _spnegoMechList = mechTypesOuterReader.PeekEncodedValue().ToArray(); bool hasNtlm = false; bool isNtlmPreferred = false; bool first = true; AsnReader mechTypesReader = mechTypesOuterReader.ReadSequence(); while (mechTypesReader.HasData) { string mechType = mechTypesReader.ReadObjectIdentifier(); if (mechType == NtlmOid) { hasNtlm = true; isNtlmPreferred = first; } first = false; } // Skip context flags, if present if (negTokenInitReader.HasData && negTokenInitReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.ReqFlags))) { negTokenInitReader.ReadSequence(); } byte[]? mechToken = null; if (negTokenInitReader.HasData && negTokenInitReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechToken))) { AsnReader mechTokenReader = negTokenInitReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechToken)); mechToken = mechTokenReader.ReadOctetString(); Assert.False(mechTokenReader.HasData); } byte[]? mechListMIC = null; if (negTokenInitReader.HasData && negTokenInitReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechListMIC))) { AsnReader mechListMICReader = negTokenInitReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechListMIC)); mechListMIC = mechListMICReader.ReadOctetString(); Assert.False(mechListMICReader.HasData); } Assert.True(hasNtlm); // If the preferred mechanism was NTLM then proceed with the given token byte[]? outgoingBlob = null; if (isNtlmPreferred && mechToken != null) { Assert.Null(mechListMIC); outgoingBlob = _ntlmServer.GetOutgoingBlob(mechToken); } // Generate reply AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp))) { using (writer.PushSequence()) { using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState))) { if (RequestMIC) { writer.WriteEnumeratedValue(NegState.RequestMic); } else { writer.WriteEnumeratedValue(NegState.AcceptIncomplete); } } using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.SupportedMech))) { writer.WriteObjectIdentifier(NtlmOid); } if (outgoingBlob != null) { using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken))) { writer.WriteOctetString(outgoingBlob); } } } } return(writer.Encode()); } else { AsnReader negTokenRespReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp)).ReadSequence(); Assert.True(negTokenRespReader.HasData); NegState?clientState; if (negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState))) { AsnReader valueReader = negTokenRespReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState)); clientState = valueReader.ReadEnumeratedValue <NegState>(); Assert.False(valueReader.HasData); Assert.NotEqual(NegState.Reject, clientState); Assert.NotEqual(NegState.RequestMic, clientState); } // Client should not send mechanism Assert.False(negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.SupportedMech))); byte[]? mechToken = null; if (negTokenRespReader.HasData && negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken))) { AsnReader mechTokenReader = negTokenRespReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken)); mechToken = mechTokenReader.ReadOctetString(); Assert.False(mechTokenReader.HasData); } byte[]? mechListMIC = null; if (negTokenRespReader.HasData && negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.MechListMIC))) { AsnReader mechListMICReader = negTokenRespReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.MechListMIC)); mechListMIC = mechListMICReader.ReadOctetString(); Assert.False(mechListMICReader.HasData); } Assert.NotNull(mechToken); byte[]? outgoingBlob = _ntlmServer.GetOutgoingBlob(mechToken); if (_ntlmServer.IsAuthenticated) { if (RequestMIC) { Assert.NotNull(mechListMIC); } // Validate mechListMIC, if present if (mechListMIC is not null) { _ntlmServer.VerifyMIC(_spnegoMechList, mechListMIC); } } else { Assert.Null(mechListMIC); } // Generate reply AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp))) { using (writer.PushSequence()) { using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState))) { if (_ntlmServer.IsAuthenticated) { writer.WriteEnumeratedValue(NegState.AcceptCompleted); } else if (outgoingBlob != null) { writer.WriteEnumeratedValue(NegState.AcceptIncomplete); } else { writer.WriteEnumeratedValue(NegState.Reject); } } if (outgoingBlob != null) { using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken))) { writer.WriteOctetString(outgoingBlob); } } if (mechListMIC != null) { using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.MechListMIC))) { Span <byte> mic = stackalloc byte[16]; _ntlmServer.GetMIC(_spnegoMechList, mic); writer.WriteOctetString(mic); // MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First Signed Message // specifies that the RC4 sealing keys are reset back to the initial state for the // first message. _ntlmServer.ResetKeys(); } } } } IsAuthenticated = _ntlmServer.IsAuthenticated; return(writer.Encode()); } }
public static Pkcs12Info Decode( ReadOnlyMemory <byte> encodedBytes, out int bytesConsumed, bool skipCopy = false) { AsnReader reader = new AsnReader(encodedBytes, AsnEncodingRules.BER); // Trim it to the first value encodedBytes = reader.PeekEncodedValue(); ReadOnlyMemory <byte> maybeCopy = skipCopy ? encodedBytes : encodedBytes.ToArray(); PfxAsn pfx = PfxAsn.Decode(maybeCopy, AsnEncodingRules.BER); // https://tools.ietf.org/html/rfc7292#section-4 only defines version 3. if (pfx.Version != 3) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } ReadOnlyMemory <byte> authSafeBytes = ReadOnlyMemory <byte> .Empty; Pkcs12IntegrityMode mode = Pkcs12IntegrityMode.Unknown; if (pfx.AuthSafe.ContentType == Oids.Pkcs7Data) { authSafeBytes = PkcsHelpers.DecodeOctetStringAsMemory(pfx.AuthSafe.Content); if (pfx.MacData.HasValue) { mode = Pkcs12IntegrityMode.Password; } else { mode = Pkcs12IntegrityMode.None; } } else if (pfx.AuthSafe.ContentType == Oids.Pkcs7Signed) { SignedDataAsn signedData = SignedDataAsn.Decode(pfx.AuthSafe.Content, AsnEncodingRules.BER); mode = Pkcs12IntegrityMode.PublicKey; if (signedData.EncapContentInfo.ContentType == Oids.Pkcs7Data) { authSafeBytes = signedData.EncapContentInfo.Content.GetValueOrDefault(); } if (pfx.MacData.HasValue) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } } if (mode == Pkcs12IntegrityMode.Unknown) { throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } List <ContentInfoAsn> authSafeData = new List <ContentInfoAsn>(); AsnReader authSafeReader = new AsnReader(authSafeBytes, AsnEncodingRules.BER); AsnReader sequenceReader = authSafeReader.ReadSequence(); authSafeReader.ThrowIfNotEmpty(); while (sequenceReader.HasData) { ContentInfoAsn.Decode(sequenceReader, out ContentInfoAsn contentInfo); authSafeData.Add(contentInfo); } ReadOnlyCollection <Pkcs12SafeContents> authSafe; if (authSafeData.Count == 0) { authSafe = new ReadOnlyCollection <Pkcs12SafeContents>(Array.Empty <Pkcs12SafeContents>()); } else { Pkcs12SafeContents[] contentsArray = new Pkcs12SafeContents[authSafeData.Count]; for (int i = 0; i < contentsArray.Length; i++) { contentsArray[i] = new Pkcs12SafeContents(authSafeData[i]); } authSafe = new ReadOnlyCollection <Pkcs12SafeContents>(contentsArray); } bytesConsumed = encodedBytes.Length; return(new Pkcs12Info { AuthenticatedSafe = authSafe, IntegrityMode = mode, _decoded = pfx, _authSafeContents = authSafeBytes, }); }
private bool ProcessResponse( ReadOnlyMemory <byte> source, out Rfc3161TimestampToken token, out Rfc3161RequestResponseStatus status, out int bytesConsumed, bool shouldThrow) { status = Rfc3161RequestResponseStatus.Unknown; token = null; Rfc3161TimeStampResp resp; try { AsnReader reader = new AsnReader(source, AsnEncodingRules.DER); int localBytesRead = reader.PeekEncodedValue().Length; Rfc3161TimeStampResp.Decode(reader, out resp); bytesConsumed = localBytesRead; } catch (CryptographicException) when(!shouldThrow) { bytesConsumed = 0; status = Rfc3161RequestResponseStatus.DoesNotParse; return(false); } // bytesRead will be set past this point PkiStatus pkiStatus = (PkiStatus)resp.Status.Status; if (pkiStatus != PkiStatus.Granted && pkiStatus != PkiStatus.GrantedWithMods) { if (shouldThrow) { throw new CryptographicException( SR.Format( SR.Cryptography_TimestampReq_Failure, pkiStatus, resp.Status.FailInfo.GetValueOrDefault())); } status = Rfc3161RequestResponseStatus.RequestFailed; return(false); } if (!Rfc3161TimestampToken.TryDecode(resp.TimeStampToken.GetValueOrDefault(), out token, out _)) { if (shouldThrow) { throw new CryptographicException(SR.Cryptography_TimestampReq_BadResponse); } bytesConsumed = 0; status = Rfc3161RequestResponseStatus.DoesNotParse; return(false); } status = ValidateResponse(token, shouldThrow); return(status == Rfc3161RequestResponseStatus.Accepted); }