Add SSL_SESSION_to_bytes to replace i2d_SSL_SESSION.
Deprecate the old two-pass version of the function. If the ticket is too long,
replace it with a placeholder value but keep the connection working.
Change-Id: Ib9fdea66389b171862143d79b5540ea90a9bd5fb
Reviewed-on: https://boringssl-review.googlesource.com/2011
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index bfa064f..ef7ebdc 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -127,7 +127,7 @@
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2;
static const int kPeerTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3;
-static const int kSessionIDContextTag =
+ static const int kSessionIDContextTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4;
static const int kVerifyResultTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5;
@@ -152,11 +152,10 @@
static const int kExtendedMasterSecretTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17;
-int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) {
+static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
+ size_t *out_len, int for_ticket) {
CBB cbb, session, child, child2;
uint16_t cipher_id;
- uint8_t *out;
- size_t len;
if (in == NULL || (in->cipher == NULL && in->cipher_id == 0)) {
return 0;
@@ -178,7 +177,9 @@
!CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
!CBB_add_u16(&child, cipher_id) ||
!CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
- !CBB_add_bytes(&child, in->session_id, in->session_id_length) ||
+ /* The session ID is irrelevant for a session ticket. */
+ !CBB_add_bytes(&child, in->session_id,
+ for_ticket ? 0 : in->session_id_length) ||
!CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child, in->master_key, in->master_key_length)) {
OPENSSL_PUT_ERROR(SSL, i2d_SSL_SESSION, ERR_R_MALLOC_FAILURE);
@@ -330,10 +331,33 @@
}
}
- if (!CBB_finish(&cbb, &out, &len)) {
+ if (!CBB_finish(&cbb, out_data, out_len)) {
OPENSSL_PUT_ERROR(SSL, i2d_SSL_SESSION, ERR_R_MALLOC_FAILURE);
goto err;
}
+ return 1;
+
+ err:
+ CBB_cleanup(&cbb);
+ return 0;
+}
+
+int SSL_SESSION_to_bytes(SSL_SESSION *in, uint8_t **out_data, size_t *out_len) {
+ return SSL_SESSION_to_bytes_full(in, out_data, out_len, 0);
+}
+
+int SSL_SESSION_to_bytes_for_ticket(SSL_SESSION *in, uint8_t **out_data,
+ size_t *out_len) {
+ return SSL_SESSION_to_bytes_full(in, out_data, out_len, 1);
+}
+
+int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) {
+ uint8_t *out;
+ size_t len;
+
+ if (!SSL_SESSION_to_bytes(in, &out, &len)) {
+ return -1;
+ }
if (len > INT_MAX) {
OPENSSL_free(out);
@@ -341,7 +365,6 @@
return -1;
}
- /* TODO(davidben): Provide a safer API and deprecate this one. */
if (pp) {
memcpy(*pp, out, len);
*pp += len;
@@ -349,10 +372,6 @@
OPENSSL_free(out);
return len;
-
-err:
- CBB_cleanup(&cbb);
- return -1;
}
/* d2i_SSL_SESSION_get_string gets an optional ASN.1 OCTET STRING