- if (in->krb5_client_princ_len)
- M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING);
-#endif /* OPENSSL_NO_KRB5 */
- if (in->key_arg_length > 0)
- M_ASN1_I2D_put_IMP_opt(&(a.key_arg),i2d_ASN1_OCTET_STRING,0);
- 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);
- M_ASN1_I2D_finish();
- }
-
-SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, unsigned char **pp,
- long length)
- {
- int version,ssl_version=0,i;
- long id;
- ASN1_INTEGER ai,*aip;
- ASN1_OCTET_STRING os,*osp;
- M_ASN1_D2I_vars(a,SSL_SESSION *,SSL_SESSION_new);
-
- aip= &ai;
- osp= &os;
-
- M_ASN1_D2I_Init();
- M_ASN1_D2I_start_sequence();
-
- ai.data=NULL; ai.length=0;
- M_ASN1_D2I_get(aip,d2i_ASN1_INTEGER);
- version=(int)ASN1_INTEGER_get(aip);
- if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; }
-
- /* we don't care about the version right now :-) */
- M_ASN1_D2I_get(aip,d2i_ASN1_INTEGER);
- ssl_version=(int)ASN1_INTEGER_get(aip);
- ret->ssl_version=ssl_version;
- if (ai.data != NULL) { OPENSSL_free(ai.data); ai.data=NULL; ai.length=0; }
-
- os.data=NULL; os.length=0;
- M_ASN1_D2I_get(osp,d2i_ASN1_OCTET_STRING);
- if (ssl_version == SSL2_VERSION)
- {
- if (os.length != 3)
- {
- c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
- goto err;
- }
- id=0x02000000L|
- ((unsigned long)os.data[0]<<16L)|
- ((unsigned long)os.data[1]<< 8L)|
- (unsigned long)os.data[2];
- }
- else if ((ssl_version>>8) == 3)
- {
- if (os.length != 2)
- {
- c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
- goto err;
- }
- id=0x03000000L|
- ((unsigned long)os.data[0]<<8L)|
- (unsigned long)os.data[1];
- }
- else
- {
- SSLerr(SSL_F_D2I_SSL_SESSION,SSL_R_UNKNOWN_SSL_VERSION);
- return(NULL);
- }
-
- ret->cipher=NULL;
- ret->cipher_id=id;
-
- M_ASN1_D2I_get(osp,d2i_ASN1_OCTET_STRING);
- if ((ssl_version>>8) == SSL3_VERSION)
- i=SSL3_MAX_SSL_SESSION_ID_LENGTH;
- else /* if (ssl_version == SSL2_VERSION) */
- i=SSL2_MAX_SSL_SESSION_ID_LENGTH;
-
- if (os.length > i)
- os.length=i;
-
- ret->session_id_length=os.length;
- memcpy(ret->session_id,os.data,os.length);
-
- M_ASN1_D2I_get(osp,d2i_ASN1_OCTET_STRING);
- if (ret->master_key_length > SSL_MAX_MASTER_KEY_LENGTH)
- ret->master_key_length=SSL_MAX_MASTER_KEY_LENGTH;
- else
- ret->master_key_length=os.length;
- memcpy(ret->master_key,os.data,ret->master_key_length);
-
- os.length=0;
+ if (in->krb5_client_princ_len) {
+ ssl_session_oinit(&as.krb5_princ, &krb5_princ,
+ in->krb5_client_princ, in->krb5_client_princ_len);
+ }
+#endif /* OPENSSL_NO_KRB5 */
+
+ as.time = in->time;
+ as.timeout = in->timeout;
+ as.verify_result = in->verify_result;
+
+ as.peer = in->peer;
+
+#ifndef OPENSSL_NO_TLSEXT
+ ssl_session_sinit(&as.tlsext_hostname, &tlsext_hostname,
+ in->tlsext_hostname);
+ if (in->tlsext_tick) {
+ ssl_session_oinit(&as.tlsext_tick, &tlsext_tick,
+ in->tlsext_tick, in->tlsext_ticklen);
+ }
+ if (in->tlsext_tick_lifetime_hint > 0)
+ as.tlsext_tick_lifetime_hint = in->tlsext_tick_lifetime_hint;
+#endif /* OPENSSL_NO_TLSEXT */
+#ifndef OPENSSL_NO_PSK
+ ssl_session_sinit(&as.psk_identity_hint, &psk_identity_hint,
+ in->psk_identity_hint);
+ ssl_session_sinit(&as.psk_identity, &psk_identity, in->psk_identity);
+#endif /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+ ssl_session_sinit(&as.srp_username, &srp_username, in->srp_username);
+#endif /* OPENSSL_NO_SRP */
+
+ as.flags = in->flags;
+
+ return i2d_SSL_SESSION_ASN1(&as, pp);
+
+}
+
+/* Utility functions for d2i_SSL_SESSION */
+
+/* BUF_strndup an OCTET STRING */
+
+static int ssl_session_strndup(char **pdst, ASN1_OCTET_STRING *src)
+{
+ if (*pdst) {
+ OPENSSL_free(*pdst);
+ *pdst = NULL;
+ }
+ if (src == NULL)
+ return 1;
+ *pdst = BUF_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, unsigned int *pdstlen,
+ ASN1_OCTET_STRING *src, int maxlen)
+{
+ if (src == NULL) {
+ *pdstlen = 0;
+ return 1;
+ }
+ if (src->length > maxlen)
+ return 0;
+ memcpy(dst, src->data, src->length);
+ *pdstlen = src->length;
+ return 1;
+}
+
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
+ long length)
+{
+ long id;
+ unsigned int tmpl;
+ const unsigned char *p = *pp;
+ SSL_SESSION_ASN1 *as = NULL;
+ SSL_SESSION *ret = NULL;
+
+ as = d2i_SSL_SESSION_ASN1(NULL, &p, length);
+ /* ASN.1 code returns suitable error */
+ if (as == NULL)
+ goto err;
+
+ if (0) {
+ i2d_SSL_SESSION_ASN1(NULL, NULL);
+ }
+
+ if (!a || !*a) {
+ ret = SSL_SESSION_new();
+ if (ret == NULL)
+ goto err;
+ } else {
+ ret = *a;
+ }
+
+ if (as->version != SSL_SESSION_ASN1_VERSION) {
+ SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNKNOWN_SSL_VERSION);
+ goto err;
+ }
+
+ if ((as->ssl_version >> 8) != SSL3_VERSION_MAJOR
+ && (as->ssl_version >> 8) != DTLS1_VERSION_MAJOR
+ && as->ssl_version != DTLS1_BAD_VER) {
+ SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION);
+ goto err;
+ }
+
+ ret->ssl_version = (int)as->ssl_version;
+
+ if (as->cipher->length != 2) {
+ SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_CIPHER_CODE_WRONG_LENGTH);
+ goto err;
+ }
+
+ p = as->cipher->data;
+ id = 0x03000000L | ((unsigned long)p[0] << 8L) | (unsigned long)p[1];
+
+ ret->cipher = NULL;
+ ret->cipher_id = id;
+
+ if (!ssl_session_memcpy(ret->session_id, &ret->session_id_length,
+ as->session_id, SSL3_MAX_SSL_SESSION_ID_LENGTH))
+ goto err;
+
+ if (!ssl_session_memcpy(ret->master_key, &tmpl,
+ as->master_key, SSL_MAX_MASTER_KEY_LENGTH))
+ goto err;
+
+ ret->master_key_length = tmpl;