Skip to content

Commit 6453bd8

Browse files
divVerentBoringssl LUCI CQ
authored andcommitted
i2d_SSL_SESSION: support operating as allocating i2d function.
Nothing in the documentation says it _cannot_ be used this way, so let's make ``` uint8_t *out = nullptr; i2d_SSL_SESSION(session, &out); ``` work. Found by #Gemini. Change-Id: Ibff50d411a51b51f74db09f087ce24af6a6a6964 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/91008 Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: Rudolf Polzer <rpolzer@google.com>
1 parent 28cf3dd commit 6453bd8

File tree

3 files changed

+34
-43
lines changed

3 files changed

+34
-43
lines changed

crypto/bytestring/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out,
6868
// error, it calls |CBB_cleanup| on |cbb|.
6969
//
7070
// This function may be used to help implement legacy i2d ASN.1 functions.
71-
int CBB_finish_i2d(CBB *cbb, uint8_t **outp);
71+
OPENSSL_EXPORT int CBB_finish_i2d(CBB *cbb, uint8_t **outp);
7272

7373
// CBBAsSpan returns a span containing |cbb|'s contents. It does not flush
7474
// |cbb|. The span is valid until the next operation to |cbb|.

ssl/ssl_asn1.cc

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <openssl/mem.h>
2626
#include <openssl/x509.h>
2727

28+
#include "../crypto/bytestring/internal.h"
2829
#include "../crypto/internal.h"
2930
#include "internal.h"
3031

@@ -355,6 +356,20 @@ static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb,
355356
return CBB_flush(cbb);
356357
}
357358

359+
static int SSL_SESSION_to_bytes_if_not_resumable(const SSL_SESSION *in,
360+
CBB *out, int for_ticket) {
361+
if (in->not_resumable) {
362+
// If the caller has an unresumable session, e.g. if |SSL_get_session|
363+
// were called on a TLS 1.3 or False Started connection, serialize with
364+
// a placeholder value so it is not accidentally deserialized into a
365+
// resumable one.
366+
const auto kNotResumableSession = StringAsBytes("NOT RESUMABLE");
367+
return CBB_add_bytes(out, kNotResumableSession.data(),
368+
kNotResumableSession.size());
369+
}
370+
return SSL_SESSION_to_bytes_full(in, out, for_ticket);
371+
}
372+
358373
// SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING explicitly
359374
// tagged with |tag| from |cbs| and saves it in |*out|. If the element was not
360375
// found, it sets |*out| to NULL. It returns one on success, whether or not the
@@ -717,29 +732,12 @@ using namespace bssl;
717732

718733
int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data,
719734
size_t *out_len) {
720-
if (in->not_resumable) {
721-
// If the caller has an unresumable session, e.g. if |SSL_get_session| were
722-
// called on a TLS 1.3 or False Started connection, serialize with a
723-
// placeholder value so it is not accidentally deserialized into a resumable
724-
// one.
725-
static const char kNotResumableSession[] = "NOT RESUMABLE";
726-
727-
*out_len = strlen(kNotResumableSession);
728-
*out_data = (uint8_t *)OPENSSL_memdup(kNotResumableSession, *out_len);
729-
if (*out_data == nullptr) {
730-
return 0;
731-
}
732-
733-
return 1;
734-
}
735-
736735
ScopedCBB cbb;
737736
if (!CBB_init(cbb.get(), 256) ||
738-
!SSL_SESSION_to_bytes_full(in, cbb.get(), 0) ||
737+
!SSL_SESSION_to_bytes_if_not_resumable(in, cbb.get(), 0) ||
739738
!CBB_finish(cbb.get(), out_data, out_len)) {
740739
return 0;
741740
}
742-
743741
return 1;
744742
}
745743

@@ -751,31 +749,16 @@ int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, uint8_t **out_data,
751749
!CBB_finish(cbb.get(), out_data, out_len)) {
752750
return 0;
753751
}
754-
755752
return 1;
756753
}
757754

758755
int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) {
759-
uint8_t *out;
760-
size_t len;
761-
762-
if (!SSL_SESSION_to_bytes(in, &out, &len)) {
763-
return -1;
764-
}
765-
766-
if (len > INT_MAX) {
767-
OPENSSL_free(out);
768-
OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
769-
return -1;
770-
}
771-
772-
if (pp) {
773-
OPENSSL_memcpy(*pp, out, len);
774-
*pp += len;
756+
ScopedCBB cbb;
757+
if (!CBB_init(cbb.get(), 256) ||
758+
!SSL_SESSION_to_bytes_if_not_resumable(in, cbb.get(), 0)) {
759+
return 0;
775760
}
776-
OPENSSL_free(out);
777-
778-
return len;
761+
return CBB_finish_i2d(cbb.get(), pp);
779762
}
780763

781764
SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len,

ssl/ssl_test.cc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,12 +1279,20 @@ TEST(SSLTest, SessionEncoding) {
12791279
uint8_t *ptr = encoded.get();
12801280
len = i2d_SSL_SESSION(session.get(), &ptr);
12811281
ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
1282-
ASSERT_EQ(static_cast<size_t>(len), input.size())
1283-
<< "i2d_SSL_SESSION(NULL) returned invalid length";
12841282
ASSERT_EQ(ptr, encoded.get() + input.size())
12851283
<< "i2d_SSL_SESSION did not advance ptr correctly";
1286-
EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
1287-
<< "SSL_SESSION_to_bytes did not round-trip";
1284+
EXPECT_EQ(Bytes(encoded.get(), len), Bytes(input))
1285+
<< "i2d_SSL_SESSION did not round-trip";
1286+
1287+
// Verify the SSL_SESSION encoding round-trips via the legacy allocating
1288+
// API.
1289+
uint8_t *aptr = nullptr;
1290+
len = i2d_SSL_SESSION(session.get(), &aptr);
1291+
encoded.reset(aptr);
1292+
ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
1293+
ASSERT_TRUE(aptr != nullptr) << "i2d_SSL_SESSION did not allocate ptr";
1294+
EXPECT_EQ(Bytes(aptr, len), Bytes(input))
1295+
<< "i2d_SSL_SESSION did not round-trip";
12881296
}
12891297

12901298
for (const char *input_b64 : {

0 commit comments

Comments
 (0)