diff options
Diffstat (limited to 'crypto/src/tls/RecordStream.cs')
-rw-r--r-- | crypto/src/tls/RecordStream.cs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/crypto/src/tls/RecordStream.cs b/crypto/src/tls/RecordStream.cs index a97d34698..a5926d05b 100644 --- a/crypto/src/tls/RecordStream.cs +++ b/crypto/src/tls/RecordStream.cs @@ -258,6 +258,9 @@ namespace Org.BouncyCastle.Tls /// <exception cref="IOException"/> internal void WriteRecord(short contentType, byte[] plaintext, int plaintextOffset, int plaintextLength) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + WriteRecord(contentType, plaintext.AsSpan(plaintextOffset, plaintextLength)); +#else // Never send anything until a valid ClientHello has been received if (m_writeVersion == null) return; @@ -298,8 +301,56 @@ namespace Org.BouncyCastle.Tls //} m_output.Flush(); +#endif } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// <exception cref="IOException"/> + internal void WriteRecord(short contentType, ReadOnlySpan<byte> plaintext) + { + // Never send anything until a valid ClientHello has been received + if (m_writeVersion == null) + return; + + /* + * RFC 5246 6.2.1 The length should not exceed 2^14. + */ + CheckLength(plaintext.Length, m_plaintextLimit, AlertDescription.internal_error); + + /* + * RFC 5246 6.2.1 Implementations MUST NOT send zero-length fragments of Handshake, Alert, + * or ChangeCipherSpec content types. + */ + if (plaintext.Length < 1 && contentType != ContentType.application_data) + throw new TlsFatalAlert(AlertDescription.internal_error); + + long seqNo = m_writeSeqNo.NextValue(AlertDescription.internal_error); + ProtocolVersion recordVersion = m_writeVersion; + + TlsEncodeResult encoded = m_writeCipher.EncodePlaintext(seqNo, contentType, recordVersion, + RecordFormat.FragmentOffset, plaintext); + + int ciphertextLength = encoded.len - RecordFormat.FragmentOffset; + TlsUtilities.CheckUint16(ciphertextLength); + + TlsUtilities.WriteUint8(encoded.recordType, encoded.buf, encoded.off + RecordFormat.TypeOffset); + TlsUtilities.WriteVersion(recordVersion, encoded.buf, encoded.off + RecordFormat.VersionOffset); + TlsUtilities.WriteUint16(ciphertextLength, encoded.buf, encoded.off + RecordFormat.LengthOffset); + + // TODO[tls-port] Can we support interrupted IO on .NET? + //try + //{ + m_output.Write(encoded.buf, encoded.off, encoded.len); + //} + //catch (InterruptedIOException e) + //{ + // throw new TlsFatalAlert(AlertDescription.internal_error, e); + //} + + m_output.Flush(); + } +#endif + /// <exception cref="IOException"/> internal void Close() { |