public static Certificate Parse(Stream input) { int num = TlsUtilities.ReadUint24(input); if (num == 0) { return(EmptyChain); } byte[] buffer = TlsUtilities.ReadFully(num, input); MemoryStream memoryStream = new MemoryStream(buffer, writable: false); IList list = Platform.CreateArrayList(); while (memoryStream.Position < memoryStream.Length) { byte[] encoding = TlsUtilities.ReadOpaque24(memoryStream); Asn1Object obj = TlsUtilities.ReadDerObject(encoding); list.Add(X509CertificateStructure.GetInstance(obj)); } X509CertificateStructure[] array = new X509CertificateStructure[list.Count]; for (int i = 0; i < list.Count; i++) { array[i] = (X509CertificateStructure)list[i]; } return(new Certificate(array)); }
/** * Parse a {@link Certificate} from a {@link Stream}. * * @param input the {@link Stream} to parse from. * @return a {@link Certificate} object. * @throws IOException */ public static Certificate Parse(Stream input) { int totalLength = TlsUtilities.ReadUint24(input); if (totalLength == 0) { return(EmptyChain); } byte[] certListData = TlsUtilities.ReadFully(totalLength, input); MemoryStream buf = new MemoryStream(certListData, false); IList certificate_list = Platform.CreateArrayList(); while (buf.Position < buf.Length) { byte[] derEncoding = TlsUtilities.ReadOpaque24(buf); Asn1Object asn1Cert = TlsUtilities.ReadDerObject(derEncoding); certificate_list.Add(X509CertificateStructure.GetInstance(asn1Cert)); } X509CertificateStructure[] certificateList = new X509CertificateStructure[certificate_list.Count]; for (int i = 0; i < certificate_list.Count; ++i) { certificateList[i] = (X509CertificateStructure)certificate_list[i]; } return(new Certificate(certificateList)); }
private void ProcessHandshake() { bool flag; do { flag = false; if (mHandshakeQueue.Available < 4) { continue; } byte[] array = new byte[4]; mHandshakeQueue.Read(array, 0, 4, 0); byte b = TlsUtilities.ReadUint8(array, 0); int num = TlsUtilities.ReadUint24(array, 1); if (mHandshakeQueue.Available < num + 4) { continue; } byte[] array2 = mHandshakeQueue.RemoveData(num, 4); CheckReceivedChangeCipherSpec(mConnectionState == 16 || b == 20); if (b != 0) { TlsContext context = Context; if (b == 20 && mExpectedVerifyData == null && context.SecurityParameters.MasterSecret != null) { mExpectedVerifyData = CreateVerifyData(!context.IsServer); } mRecordStream.UpdateHandshakeData(array, 0, 4); mRecordStream.UpdateHandshakeData(array2, 0, num); } HandleHandshakeMessage(b, array2); flag = true; }while (flag); }
private void HandleRetransmittedHandshakeRecord(int epoch, byte[] buf, int off, int len) { /* * TODO Need to handle the case where the previous inbound flight contains * messages from two epochs. */ if (len < 12) { return; } int fragment_length = TlsUtilities.ReadUint24(buf, off + 9); if (len != (fragment_length + 12)) { return; } int seq = TlsUtilities.ReadUint16(buf, off + 4); if (seq >= mNextReceiveSeq) { return; } byte msg_type = TlsUtilities.ReadUint8(buf, off); // TODO This is a hack that only works until we try to support renegotiation int expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0; if (epoch != expectedEpoch) { return; } int length = TlsUtilities.ReadUint24(buf, off + 1); int fragment_offset = TlsUtilities.ReadUint24(buf, off + 6); if (fragment_offset + fragment_length > length) { return; } DtlsReassembler reassembler = (DtlsReassembler)mCurrentInboundFlight[seq]; if (reassembler != null) { reassembler.ContributeFragment(msg_type, length, buf, off + 12, fragment_offset, fragment_length); if (CheckAll(mCurrentInboundFlight)) { ResendOutboundFlight(); ResetAll(mCurrentInboundFlight); } } }
private void HandleRetransmittedHandshakeRecord(int epoch, byte[] buf, int off, int len) { if (len < 12) { return; } int num = TlsUtilities.ReadUint24(buf, off + 9); if (len != num + 12) { return; } int num2 = TlsUtilities.ReadUint16(buf, off + 4); if (num2 >= mNextReceiveSeq) { return; } byte b = TlsUtilities.ReadUint8(buf, off); int num3 = (b == 20) ? 1 : 0; if (epoch != num3) { return; } int num4 = TlsUtilities.ReadUint24(buf, off + 1); int num5 = TlsUtilities.ReadUint24(buf, off + 6); if (num5 + num > num4) { return; } DtlsReassembler dtlsReassembler = (DtlsReassembler)mCurrentInboundFlight[num2]; if (dtlsReassembler != null) { dtlsReassembler.ContributeFragment(b, num4, buf, off + 12, num5, num); if (CheckAll(mCurrentInboundFlight)) { ResendOutboundFlight(); ResetAll(mCurrentInboundFlight); } } }
private bool ProcessRecord(int windowSize, int epoch, byte[] buf, int off, int len) { bool checkPreviousFlight = false; while (len >= MessageHeaderLength) { int fragment_length = TlsUtilities.ReadUint24(buf, off + 9); int message_length = fragment_length + MessageHeaderLength; if (len < message_length) { // NOTE: Truncated message - ignore it break; } int length = TlsUtilities.ReadUint24(buf, off + 1); int fragment_offset = TlsUtilities.ReadUint24(buf, off + 6); if (fragment_offset + fragment_length > length) { // NOTE: Malformed fragment - ignore it and the rest of the record break; } /* * NOTE: This very simple epoch check will only work until we want to support * renegotiation (and we're not likely to do that anyway). */ byte msg_type = TlsUtilities.ReadUint8(buf, off + 0); int expectedEpoch = msg_type == HandshakeType.finished ? 1 : 0; if (epoch != expectedEpoch) { break; } int message_seq = TlsUtilities.ReadUint16(buf, off + 4); if (message_seq >= (mNextReceiveSeq + windowSize)) { // NOTE: Too far ahead - ignore } else if (message_seq >= mNextReceiveSeq) { DtlsReassembler reassembler = (DtlsReassembler)mCurrentInboundFlight[message_seq]; if (reassembler == null) { reassembler = new DtlsReassembler(msg_type, length); mCurrentInboundFlight[message_seq] = reassembler; } reassembler.ContributeFragment(msg_type, length, buf, off + MessageHeaderLength, fragment_offset, fragment_length); } else if (mPreviousInboundFlight != null) { /* * NOTE: If we receive the previous flight of incoming messages in full again, * retransmit our last flight */ DtlsReassembler reassembler = (DtlsReassembler)mPreviousInboundFlight[message_seq]; if (reassembler != null) { reassembler.ContributeFragment(msg_type, length, buf, off + MessageHeaderLength, fragment_offset, fragment_length); checkPreviousFlight = true; } } off += message_length; len -= message_length; } bool result = checkPreviousFlight && CheckAll(mPreviousInboundFlight); if (result) { ResendOutboundFlight(); ResetAll(mPreviousInboundFlight); } return(result); }
internal Message ReceiveMessage() { if (mSending) { mSending = false; PrepareInboundFlight(); } // Check if we already have the next message waiting { DtlsReassembler next = (DtlsReassembler)mCurrentInboundFlight[mNextReceiveSeq]; if (next != null) { byte[] body = next.GetBodyIfComplete(); if (body != null) { mPreviousInboundFlight = null; return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, next.MsgType, body))); } } } byte[] buf = null; // TODO Check the conditions under which we should reset this int readTimeoutMillis = 1000; for (;;) { int receiveLimit = mRecordLayer.GetReceiveLimit(); if (buf == null || buf.Length < receiveLimit) { buf = new byte[receiveLimit]; } // TODO Handle records containing multiple handshake messages try { for (; ;) { int received = mRecordLayer.Receive(buf, 0, receiveLimit, readTimeoutMillis); if (received < 0) { break; } if (received < 12) { continue; } int fragment_length = TlsUtilities.ReadUint24(buf, 9); if (received != (fragment_length + 12)) { continue; } int seq = TlsUtilities.ReadUint16(buf, 4); if (seq > (mNextReceiveSeq + MAX_RECEIVE_AHEAD)) { continue; } byte msg_type = TlsUtilities.ReadUint8(buf, 0); int length = TlsUtilities.ReadUint24(buf, 1); int fragment_offset = TlsUtilities.ReadUint24(buf, 6); if (fragment_offset + fragment_length > length) { continue; } if (seq < mNextReceiveSeq) { /* * NOTE: If we Receive the previous flight of incoming messages in full * again, retransmit our last flight */ if (mPreviousInboundFlight != null) { DtlsReassembler reassembler = (DtlsReassembler)mPreviousInboundFlight[seq]; if (reassembler != null) { reassembler.ContributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); if (CheckAll(mPreviousInboundFlight)) { ResendOutboundFlight(); /* * TODO[DTLS] implementations SHOULD back off handshake packet * size during the retransmit backoff. */ readTimeoutMillis = System.Math.Min(readTimeoutMillis * 2, 60000); ResetAll(mPreviousInboundFlight); } } } } else { DtlsReassembler reassembler = (DtlsReassembler)mCurrentInboundFlight[seq]; if (reassembler == null) { reassembler = new DtlsReassembler(msg_type, length); mCurrentInboundFlight[seq] = reassembler; } reassembler.ContributeFragment(msg_type, length, buf, 12, fragment_offset, fragment_length); if (seq == mNextReceiveSeq) { byte[] body = reassembler.GetBodyIfComplete(); if (body != null) { mPreviousInboundFlight = null; return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, reassembler.MsgType, body))); } } } } } catch (IOException) { // NOTE: Assume this is a timeout for the moment } ResendOutboundFlight(); /* * TODO[DTLS] implementations SHOULD back off handshake packet size during the * retransmit backoff. */ readTimeoutMillis = System.Math.Min(readTimeoutMillis * 2, 60000); } }
internal Message ReceiveMessage() { if (mSending) { mSending = false; PrepareInboundFlight(); } DtlsReassembler dtlsReassembler = (DtlsReassembler)mCurrentInboundFlight[mNextReceiveSeq]; if (dtlsReassembler != null) { byte[] bodyIfComplete = dtlsReassembler.GetBodyIfComplete(); if (bodyIfComplete != null) { mPreviousInboundFlight = null; return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, dtlsReassembler.MsgType, bodyIfComplete))); } } byte[] array = null; int num = 1000; while (true) { int receiveLimit = mRecordLayer.GetReceiveLimit(); if (array == null || array.Length < receiveLimit) { array = new byte[receiveLimit]; } try { while (true) { int num2 = mRecordLayer.Receive(array, 0, receiveLimit, num); if (num2 < 0) { break; } if (num2 >= 12) { int num3 = TlsUtilities.ReadUint24(array, 9); if (num2 == num3 + 12) { int num4 = TlsUtilities.ReadUint16(array, 4); if (num4 <= mNextReceiveSeq + 10) { byte msg_type = TlsUtilities.ReadUint8(array, 0); int num5 = TlsUtilities.ReadUint24(array, 1); int num6 = TlsUtilities.ReadUint24(array, 6); if (num6 + num3 <= num5) { if (num4 < mNextReceiveSeq) { if (mPreviousInboundFlight != null) { DtlsReassembler dtlsReassembler2 = (DtlsReassembler)mPreviousInboundFlight[num4]; if (dtlsReassembler2 != null) { dtlsReassembler2.ContributeFragment(msg_type, num5, array, 12, num6, num3); if (CheckAll(mPreviousInboundFlight)) { ResendOutboundFlight(); num = Math.Min(num * 2, 60000); ResetAll(mPreviousInboundFlight); } } } } else { DtlsReassembler dtlsReassembler3 = (DtlsReassembler)mCurrentInboundFlight[num4]; if (dtlsReassembler3 == null) { dtlsReassembler3 = new DtlsReassembler(msg_type, num5); mCurrentInboundFlight[num4] = dtlsReassembler3; } dtlsReassembler3.ContributeFragment(msg_type, num5, array, 12, num6, num3); if (num4 == mNextReceiveSeq) { byte[] bodyIfComplete2 = dtlsReassembler3.GetBodyIfComplete(); if (bodyIfComplete2 != null) { mPreviousInboundFlight = null; return(UpdateHandshakeMessagesDigest(new Message(mNextReceiveSeq++, dtlsReassembler3.MsgType, bodyIfComplete2))); } } } } } } } } } catch (IOException) { } ResendOutboundFlight(); num = Math.Min(num * 2, 60000); } }