Add bssl::SealRecord and bssl::OpenRecord.
This is a C++ interface for encrypting and decrypting TLS application
data records in-place, wrapping the existing C API in tls_record.cc.
Also add bssl::Span, a non-owning reference to a contiguous array of
elements which can be used as a common interface over contiguous
container types (like std::vector), pointer-length-pairs, arrays, etc.
Change-Id: Iaa2ca4957cde511cb734b997db38f54e103b0d92
Reviewed-on: https://boringssl-review.googlesource.com/18104
Commit-Queue: Martin Kreichgauer <martinkr@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 04ec4b8..993046c 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -149,6 +149,7 @@
#include <openssl/hmac.h>
#include <openssl/lhash.h>
#include <openssl/pem.h>
+#include <openssl/span.h>
#include <openssl/ssl3.h>
#include <openssl/thread.h>
#include <openssl/tls1.h>
@@ -4580,6 +4581,8 @@
#if defined(__cplusplus)
} /* extern C */
+#if !defined(BORINGSSL_NO_CXX)
+
extern "C++" {
namespace bssl {
@@ -4588,10 +4591,62 @@
BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free)
BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free)
+enum class OpenRecordResult {
+ kOK,
+ kDiscard,
+ kIncompleteRecord,
+ kAlertCloseNotify,
+ kAlertFatal,
+ kError,
+};
+
+/* *** EXPERIMENTAL -- DO NOT USE ***
+ *
+ * OpenRecord decrypts the first complete SSL record from |in| in-place, sets
+ * |out| to the decrypted application data, and |out_record_len| to the length
+ * of the encrypted record. Returns:
+ * - kOK if an application-data record was successfully decrypted and verified.
+ * - kDiscard if a record was sucessfully processed, but should be discarded.
+ * - kIncompleteRecord if |in| did not contain a complete record.
+ * - kAlertCloseNotify if a record was successfully processed but is a
+ * close_notify alert.
+ * - kAlertFatal if a record was successfully processed but is a fatal alert.
+ * - kError if an error occurred or the record is invalid. |*out_alert| will be
+ * set to an alert to emit. */
+OPENSSL_EXPORT OpenRecordResult OpenRecord(SSL *ssl, Span<uint8_t> *out,
+ size_t *out_record_len,
+ uint8_t *out_alert,
+ Span<uint8_t> in);
+
+OPENSSL_EXPORT size_t SealRecordPrefixLen(SSL *ssl, size_t plaintext_len);
+OPENSSL_EXPORT size_t SealRecordMaxSuffixLen(SSL *ssl);
+
+/* *** EXPERIMENTAL -- DO NOT USE ***
+ *
+ * SealRecord encrypts the cleartext of |in| and scatters the resulting TLS
+ * application data record between |out_prefix|, |out|, and |out_suffix|. It
+ * returns true on success or false if an error occurred.
+ *
+ * The length of |out_prefix| must equal |SealRecordPrefixLen|. The length of
+ * |out| must equal the length of |in|. The length of |out_suffix| must equal
+ * |MaxSealRecordSuffixLen|. |*out_suffix_len| is set to the actual number of
+ * bytes written to |out_suffix|.
+ *
+ * If enabled, |SealRecord| may perform TLS 1.0 CBC 1/n-1 record splitting.
+ * |SealRecordPrefixLen| accounts for the required overhead if that is the case.
+ *
+ * |out| may equal |in| to encrypt in-place but may not otherwise alias.
+ * |out_prefix| and |out_suffix| may not alias anything. */
+OPENSSL_EXPORT bool SealRecord(SSL *ssl, Span<uint8_t> out_prefix,
+ Span<uint8_t> out, Span<uint8_t> out_suffix,
+ size_t *out_suffix_len, Span<const uint8_t> in);
+
} // namespace bssl
} /* extern C++ */
+#endif // !defined(BORINGSSL_NO_CXX)
+
#endif
#define SSL_R_APP_DATA_IN_HANDSHAKE 100