- M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER);
- M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER);
- M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING);
- M_ASN1_I2D_len(&(a.session_id), i2d_ASN1_OCTET_STRING);
- M_ASN1_I2D_len(&(a.master_key), i2d_ASN1_OCTET_STRING);
-#ifndef OPENSSL_NO_KRB5
- if (in->krb5_client_princ_len)
- M_ASN1_I2D_len(&(a.krb5_princ), i2d_ASN1_OCTET_STRING);
-#endif /* OPENSSL_NO_KRB5 */
- if (in->time != 0L)
- M_ASN1_I2D_len_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1);
- if (in->timeout != 0L)
- M_ASN1_I2D_len_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2);
- if (in->peer != NULL)
- M_ASN1_I2D_len_EXP_opt(in->peer, i2d_X509, 3, v3);
- M_ASN1_I2D_len_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4,
- v4);
- if (in->verify_result != X509_V_OK)
- M_ASN1_I2D_len_EXP_opt(&(a.verify_result), i2d_ASN1_INTEGER, 5, v5);
-
-#ifndef OPENSSL_NO_TLSEXT
- if (in->tlsext_tick_lifetime_hint > 0)
- M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9,
- v9);
- if (in->tlsext_tick)
- M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10,
- v10);
- if (in->tlsext_hostname)
- M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6,
- v6);
-# ifndef OPENSSL_NO_COMP
- if (in->compress_meth)
- M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11);
-# endif
-#endif /* OPENSSL_NO_TLSEXT */
-#ifndef OPENSSL_NO_PSK
- if (in->psk_identity_hint)
- M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,
- 7, v7);
- if (in->psk_identity)
- M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING, 8,
- v8);
-#endif /* OPENSSL_NO_PSK */
-#ifndef OPENSSL_NO_SRP
- if (in->srp_username)
- M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING, 12,
- v12);
-#endif /* OPENSSL_NO_SRP */
- if (in->flags)
- M_ASN1_I2D_len_EXP_opt(&(a.flags), i2d_ASN1_INTEGER, 13, v13);
-
- M_ASN1_I2D_seq_total();
-
- M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER);
- M_ASN1_I2D_put(&(a.ssl_version), i2d_ASN1_INTEGER);
- M_ASN1_I2D_put(&(a.cipher), i2d_ASN1_OCTET_STRING);
- M_ASN1_I2D_put(&(a.session_id), i2d_ASN1_OCTET_STRING);
- M_ASN1_I2D_put(&(a.master_key), i2d_ASN1_OCTET_STRING);
-#ifndef OPENSSL_NO_KRB5
- if (in->krb5_client_princ_len)
- M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING);
-#endif /* OPENSSL_NO_KRB5 */
- if (in->time != 0L)
- M_ASN1_I2D_put_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1);
- if (in->timeout != 0L)
- M_ASN1_I2D_put_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2);
- if (in->peer != NULL)
- M_ASN1_I2D_put_EXP_opt(in->peer, i2d_X509, 3, v3);
- M_ASN1_I2D_put_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4,
- v4);
- if (in->verify_result != X509_V_OK)
- M_ASN1_I2D_put_EXP_opt(&a.verify_result, i2d_ASN1_INTEGER, 5, v5);
-#ifndef OPENSSL_NO_TLSEXT
- if (in->tlsext_hostname)
- M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6,
- v6);
-#endif /* OPENSSL_NO_TLSEXT */
-#ifndef OPENSSL_NO_PSK
- if (in->psk_identity_hint)
- M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING,
- 7, v7);
- if (in->psk_identity)
- M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING, 8,
- v8);
-#endif /* OPENSSL_NO_PSK */
-#ifndef OPENSSL_NO_TLSEXT
- if (in->tlsext_tick_lifetime_hint > 0)
- M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9,
- v9);
- if (in->tlsext_tick)
- M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10,
- v10);
-#endif /* OPENSSL_NO_TLSEXT */
-#ifndef OPENSSL_NO_COMP
- if (in->compress_meth)
- M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11);
-#endif
-#ifndef OPENSSL_NO_SRP
- if (in->srp_username)
- M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING, 12,
- v12);
-#endif /* OPENSSL_NO_SRP */
- if (in->flags)
- M_ASN1_I2D_put_EXP_opt(&a.flags, i2d_ASN1_INTEGER, 13, v13);
- M_ASN1_I2D_finish();
+ if (in->ext.alpn_selected == NULL)
+ as.alpn_selected = NULL;
+ else
+ ssl_session_oinit(&as.alpn_selected, &alpn_selected,
+ in->ext.alpn_selected, in->ext.alpn_selected_len);
+
+ as.tlsext_max_fragment_len_mode = in->ext.max_fragment_len_mode;
+
+ if (in->ticket_appdata == NULL)
+ as.ticket_appdata = NULL;
+ else
+ ssl_session_oinit(&as.ticket_appdata, &ticket_appdata,
+ in->ticket_appdata, in->ticket_appdata_len);
+
+ ret = i2d_SSL_SESSION_ASN1(&as, pp);
+ OPENSSL_free(peer_rpk.data);
+ return ret;
+}
+
+/* Utility functions for d2i_SSL_SESSION */
+
+/* OPENSSL_strndup an OCTET STRING */
+
+static int ssl_session_strndup(char **pdst, ASN1_OCTET_STRING *src)
+{
+ OPENSSL_free(*pdst);
+ *pdst = NULL;
+ if (src == NULL)
+ return 1;
+ *pdst = OPENSSL_strndup((char *)src->data, src->length);
+ if (*pdst == NULL)
+ return 0;
+ return 1;
+}
+
+/* Copy an OCTET STRING, return error if it exceeds maximum length */
+
+static int ssl_session_memcpy(unsigned char *dst, size_t *pdstlen,
+ ASN1_OCTET_STRING *src, size_t maxlen)
+{
+ if (src == NULL || src->length == 0) {
+ *pdstlen = 0;
+ return 1;
+ }
+ if (src->length < 0 || src->length > (int)maxlen)
+ return 0;
+ memcpy(dst, src->data, src->length);
+ *pdstlen = src->length;
+ return 1;