[openssl-commits] [openssl] master update

Dr. Stephen Henson steve at openssl.org
Fri Apr 3 20:43:40 UTC 2015


The branch master has been updated
       via  40cf45456602ae3d7e6c00fdbe0f5eeab24f8afc (commit)
       via  19fcbc8949136032ee8b1888d2834ee45640e11e (commit)
       via  865b55ac8e32e9815d20b55fb05e66b61558cf6d (commit)
       via  a469a6770a769ff88a077f4705134db9c89f653b (commit)
       via  1880790e2ed2474c61bdbd9283ab6fe19c605a9f (commit)
       via  cc5b6a03a320f1bdace59ea8f41c3d525202d38e (commit)
       via  4fb6b0def17df98d6d16418b4b23dfde54a980ae (commit)
      from  22ebaae08c6c10de1e6b0225531c94e5866070d7 (commit)


- Log -----------------------------------------------------------------
commit 40cf45456602ae3d7e6c00fdbe0f5eeab24f8afc
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Mar 30 20:28:52 2015 +0100

    update ordinals
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 19fcbc8949136032ee8b1888d2834ee45640e11e
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Mar 30 20:24:44 2015 +0100

    make depend
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 865b55ac8e32e9815d20b55fb05e66b61558cf6d
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Mar 30 20:11:02 2015 +0100

    remove asn1_mac.h
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit a469a6770a769ff88a077f4705134db9c89f653b
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Mon Mar 30 20:31:34 2015 +0100

    Remove old ASN.1 functions.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 1880790e2ed2474c61bdbd9283ab6fe19c605a9f
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Fri Apr 3 18:28:06 2015 +0100

    Remove unnecessary use of ASN1_const_CTX
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit cc5b6a03a320f1bdace59ea8f41c3d525202d38e
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Sun Mar 29 14:07:06 2015 +0100

    Rewrite ssl_asn1.c using new ASN.1 code.
    
    Complete reimplementation of d2i_SSL_SESSION and i2d_SSL_SESSION using
    new ASN.1 code and eliminating use of old ASN.1 macros.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

commit 4fb6b0def17df98d6d16418b4b23dfde54a980ae
Author: Dr. Stephen Henson <steve at openssl.org>
Date:   Sun Mar 29 17:51:43 2015 +0100

    Add macro to implement static encode functions.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>

-----------------------------------------------------------------------

Summary of changes:
 crypto/asn1/Makefile       |   8 +-
 crypto/asn1/a_d2i_fp.c     |  26 +-
 crypto/asn1/asn1_lib.c     |  61 ----
 include/openssl/asn1.h     |  38 ---
 include/openssl/asn1_mac.h | 579 ------------------------------------
 include/openssl/asn1t.h    |  13 +
 ssl/Makefile               |   2 +-
 ssl/ssl_asn1.c             | 714 +++++++++++++++++----------------------------
 util/libeay.num            |   8 +-
 util/mkdef.pl              |   1 -
 10 files changed, 311 insertions(+), 1139 deletions(-)
 delete mode 100644 include/openssl/asn1_mac.h

diff --git a/crypto/asn1/Makefile b/crypto/asn1/Makefile
index 2187b04..7f3dd0d 100644
--- a/crypto/asn1/Makefile
+++ b/crypto/asn1/Makefile
@@ -314,10 +314,10 @@ asn1_gen.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
 asn1_gen.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
 asn1_gen.o: ../cryptlib.h asn1_gen.c
 asn1_lib.o: ../../e_os.h ../../include/openssl/asn1.h
-asn1_lib.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
-asn1_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-asn1_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-asn1_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+asn1_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+asn1_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+asn1_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+asn1_lib.o: ../../include/openssl/opensslconf.h
 asn1_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 asn1_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 asn1_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h asn1_lib.c
diff --git a/crypto/asn1/a_d2i_fp.c b/crypto/asn1/a_d2i_fp.c
index c0d9e1e..af1f7c6 100644
--- a/crypto/asn1/a_d2i_fp.c
+++ b/crypto/asn1/a_d2i_fp.c
@@ -146,12 +146,15 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
     BUF_MEM *b;
     unsigned char *p;
     int i;
-    ASN1_const_CTX c;
     size_t want = HEADER_SIZE;
     int eos = 0;
     size_t off = 0;
     size_t len = 0;
 
+    const unsigned char *q;
+    long slen;
+    int inf, tag, xclass;
+
     b = BUF_MEM_new();
     if (b == NULL) {
         ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
@@ -183,10 +186,9 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
         /* else data already loaded */
 
         p = (unsigned char *)&(b->data[off]);
-        c.p = p;
-        c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), &(c.xclass),
-                                len - off);
-        if (c.inf & 0x80) {
+        q = p;
+        inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off);
+        if (inf & 0x80) {
             unsigned long e;
 
             e = ERR_GET_REASON(ERR_peek_error());
@@ -195,10 +197,10 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
             else
                 ERR_clear_error(); /* clear error */
         }
-        i = c.p - p;            /* header length */
+        i = q - p;            /* header length */
         off += i;               /* end of data */
 
-        if (c.inf & 1) {
+        if (inf & 1) {
             /* no data body so go round again */
             eos++;
             if (eos < 0) {
@@ -206,7 +208,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
                 goto err;
             }
             want = HEADER_SIZE;
-        } else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) {
+        } else if (eos && (slen == 0) && (tag == V_ASN1_EOC)) {
             /* eos value, so go back and read another header */
             eos--;
             if (eos <= 0)
@@ -214,8 +216,8 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
             else
                 want = HEADER_SIZE;
         } else {
-            /* suck in c.slen bytes of data */
-            want = c.slen;
+            /* suck in slen bytes of data */
+            want = slen;
             if (want > (len - off)) {
                 want -= (len - off);
                 if (want > INT_MAX /* BIO_read takes an int length */  ||
@@ -242,11 +244,11 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
                     want -= i;
                 }
             }
-            if (off + c.slen < off) {
+            if (off + slen < off) {
                 ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
                 goto err;
             }
-            off += c.slen;
+            off += slen;
             if (eos <= 0) {
                 break;
             } else
diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c
index 2e36cff..b29e636 100644
--- a/crypto/asn1/asn1_lib.c
+++ b/crypto/asn1/asn1_lib.c
@@ -60,7 +60,6 @@
 #include <limits.h>
 #include "cryptlib.h"
 #include <openssl/asn1.h>
-#include <openssl/asn1_mac.h>
 
 static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
                            int max);
@@ -279,57 +278,6 @@ int ASN1_object_size(int constructed, int length, int tag)
     return (ret);
 }
 
-static int _asn1_Finish(ASN1_const_CTX *c)
-{
-    if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) {
-        if (!ASN1_const_check_infinite_end(&c->p, c->slen)) {
-            c->error = ERR_R_MISSING_ASN1_EOS;
-            return (0);
-        }
-    }
-    if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) {
-        c->error = ERR_R_ASN1_LENGTH_MISMATCH;
-        return (0);
-    }
-    return (1);
-}
-
-int asn1_Finish(ASN1_CTX *c)
-{
-    return _asn1_Finish((ASN1_const_CTX *)c);
-}
-
-int asn1_const_Finish(ASN1_const_CTX *c)
-{
-    return _asn1_Finish(c);
-}
-
-int asn1_GetSequence(ASN1_const_CTX *c, long *length)
-{
-    const unsigned char *q;
-
-    q = c->p;
-    c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass),
-                             *length);
-    if (c->inf & 0x80) {
-        c->error = ERR_R_BAD_GET_ASN1_OBJECT_CALL;
-        return (0);
-    }
-    if (c->tag != V_ASN1_SEQUENCE) {
-        c->error = ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
-        return (0);
-    }
-    (*length) -= (c->p - q);
-    if (c->max && (*length < 0)) {
-        c->error = ERR_R_ASN1_LENGTH_MISMATCH;
-        return (0);
-    }
-    if (c->inf == (1 | V_ASN1_CONSTRUCTED))
-        c->slen = *length + *(c->pp) - c->p;
-    c->eos = 0;
-    return (1);
-}
-
 int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
 {
     if (str == NULL)
@@ -451,15 +399,6 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
         return (i);
 }
 
-void asn1_add_error(const unsigned char *address, int offset)
-{
-    char buf1[DECIMAL_SIZE(address) + 1], buf2[DECIMAL_SIZE(offset) + 1];
-
-    BIO_snprintf(buf1, sizeof buf1, "%lu", (unsigned long)address);
-    BIO_snprintf(buf2, sizeof buf2, "%d", offset);
-    ERR_add_error_data(4, "address=", buf1, " offset=", buf2);
-}
-
 int ASN1_STRING_length(const ASN1_STRING *x)
 {
     return x->length;
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h
index 30de831..b1bcef7 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/asn1.h
@@ -159,41 +159,6 @@ extern "C" {
     struct X509_algor_st;
 DECLARE_STACK_OF(X509_ALGOR)
 
-/*
- * We MUST make sure that, except for constness, asn1_ctx_st and
- * asn1_const_ctx are exactly the same.  Fortunately, as soon as the old ASN1
- * parsing macros are gone, we can throw this away as well...
- */
-typedef struct asn1_ctx_st {
-    unsigned char *p;           /* work char pointer */
-    int eos;                    /* end of sequence read for indefinite
-                                 * encoding */
-    int error;                  /* error code to use when returning an error */
-    int inf;                    /* constructed if 0x20, indefinite is 0x21 */
-    int tag;                    /* tag from last 'get object' */
-    int xclass;                 /* class from last 'get object' */
-    long slen;                  /* length of last 'get object' */
-    unsigned char *max;         /* largest value of p allowed */
-    unsigned char *q;           /* temporary variable */
-    unsigned char **pp;         /* variable */
-    int line;                   /* used in error processing */
-} ASN1_CTX;
-
-typedef struct asn1_const_ctx_st {
-    const unsigned char *p;     /* work char pointer */
-    int eos;                    /* end of sequence read for indefinite
-                                 * encoding */
-    int error;                  /* error code to use when returning an error */
-    int inf;                    /* constructed if 0x20, indefinite is 0x21 */
-    int tag;                    /* tag from last 'get object' */
-    int xclass;                 /* class from last 'get object' */
-    long slen;                  /* length of last 'get object' */
-    const unsigned char *max;   /* largest value of p allowed */
-    const unsigned char *q;     /* temporary variable */
-    const unsigned char **pp;   /* variable */
-    int line;                   /* used in error processing */
-} ASN1_const_CTX;
-
 # define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */
 /*
  * This indicates that the ASN1_STRING is not a real value but just a place
@@ -727,9 +692,6 @@ BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn);
 int ASN1_PRINTABLE_type(const unsigned char *s, int max);
 
 unsigned long ASN1_tag2bit(int tag);
-/* PARSING */
-int asn1_Finish(ASN1_CTX *c);
-int asn1_const_Finish(ASN1_const_CTX *c);
 
 /* SPECIALS */
 int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
diff --git a/include/openssl/asn1_mac.h b/include/openssl/asn1_mac.h
deleted file mode 100644
index abc6dc3..0000000
--- a/include/openssl/asn1_mac.h
+++ /dev/null
@@ -1,579 +0,0 @@
-/* crypto/asn1/asn1_mac.h */
-/* Copyright (C) 1995-1998 Eric Young (eay at cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay at cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh at cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young (eay at cryptsoft.com)"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed.  i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#ifndef HEADER_ASN1_MAC_H
-# define HEADER_ASN1_MAC_H
-
-# include <openssl/asn1.h>
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-# ifndef ASN1_MAC_ERR_LIB
-#  define ASN1_MAC_ERR_LIB        ERR_LIB_ASN1
-# endif
-
-# define ASN1_MAC_H_err(f,r,line) \
-        ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line))
-
-# define M_ASN1_D2I_vars(a,type,func) \
-        ASN1_const_CTX c; \
-        type ret=NULL; \
-        \
-        c.pp=(const unsigned char **)pp; \
-        c.q= *(const unsigned char **)pp; \
-        c.error=ERR_R_NESTED_ASN1_ERROR; \
-        if ((a == NULL) || ((*a) == NULL)) \
-                { if ((ret=(type)func()) == NULL) \
-                        { c.line=__LINE__; goto err; } } \
-        else    ret=(*a);
-
-# define M_ASN1_D2I_Init() \
-        c.p= *(const unsigned char **)pp; \
-        c.max=(length == 0)?0:(c.p+length);
-
-# define M_ASN1_D2I_Finish_2(a) \
-        if (!asn1_const_Finish(&c)) \
-                { c.line=__LINE__; goto err; } \
-        *(const unsigned char **)pp=c.p; \
-        if (a != NULL) (*a)=ret; \
-        return(ret);
-
-# define M_ASN1_D2I_Finish(a,func,e) \
-        M_ASN1_D2I_Finish_2(a); \
-err:\
-        ASN1_MAC_H_err((e),c.error,c.line); \
-        asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \
-        if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
-        return(NULL)
-
-# define M_ASN1_D2I_start_sequence() \
-        if (!asn1_GetSequence(&c,&length)) \
-                { c.line=__LINE__; goto err; }
-/* Begin reading ASN1 without a surrounding sequence */
-# define M_ASN1_D2I_begin() \
-        c.slen = length;
-
-/* End reading ASN1 with no check on length */
-# define M_ASN1_D2I_Finish_nolen(a, func, e) \
-        *pp=c.p; \
-        if (a != NULL) (*a)=ret; \
-        return(ret); \
-err:\
-        ASN1_MAC_H_err((e),c.error,c.line); \
-        asn1_add_error(*pp,(int)(c.q- *pp)); \
-        if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
-        return(NULL)
-
-# define M_ASN1_D2I_end_sequence() \
-        (((c.inf&1) == 0)?(c.slen <= 0): \
-                (c.eos=ASN1_const_check_infinite_end(&c.p,c.slen)))
-
-/* Don't use this with d2i_ASN1_BOOLEAN() */
-# define M_ASN1_D2I_get(b, func) \
-        c.q=c.p; \
-        if (func(&(b),&c.p,c.slen) == NULL) \
-                {c.line=__LINE__; goto err; } \
-        c.slen-=(c.p-c.q);
-
-/* Don't use this with d2i_ASN1_BOOLEAN() */
-# define M_ASN1_D2I_get_x(type,b,func) \
-        c.q=c.p; \
-        if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \
-                {c.line=__LINE__; goto err; } \
-        c.slen-=(c.p-c.q);
-
-/* use this instead () */
-# define M_ASN1_D2I_get_int(b,func) \
-        c.q=c.p; \
-        if (func(&(b),&c.p,c.slen) < 0) \
-                {c.line=__LINE__; goto err; } \
-        c.slen-=(c.p-c.q);
-
-# define M_ASN1_D2I_get_opt(b,func,type) \
-        if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
-                == (V_ASN1_UNIVERSAL|(type)))) \
-                { \
-                M_ASN1_D2I_get(b,func); \
-                }
-
-# define M_ASN1_D2I_get_int_opt(b,func,type) \
-        if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
-                == (V_ASN1_UNIVERSAL|(type)))) \
-                { \
-                M_ASN1_D2I_get_int(b,func); \
-                }
-
-# define M_ASN1_D2I_get_imp(b,func, type) \
-        M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
-        c.q=c.p; \
-        if (func(&(b),&c.p,c.slen) == NULL) \
-                {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \
-        c.slen-=(c.p-c.q);\
-        M_ASN1_next_prev=_tmp;
-
-# define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \
-        if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \
-                (V_ASN1_CONTEXT_SPECIFIC|(tag)))) \
-                { \
-                unsigned char _tmp = M_ASN1_next; \
-                M_ASN1_D2I_get_imp(b,func, type);\
-                }
-
-# define M_ASN1_D2I_get_set(r,func,free_func) \
-                M_ASN1_D2I_get_imp_set(r,func,free_func, \
-                        V_ASN1_SET,V_ASN1_UNIVERSAL);
-
-# define M_ASN1_D2I_get_set_type(type,r,func,free_func) \
-                M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \
-                        V_ASN1_SET,V_ASN1_UNIVERSAL);
-
-# define M_ASN1_D2I_get_set_opt(r,func,free_func) \
-        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
-                V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
-                { M_ASN1_D2I_get_set(r,func,free_func); }
-
-# define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \
-        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
-                V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
-                { M_ASN1_D2I_get_set_type(type,r,func,free_func); }
-
-# define M_ASN1_I2D_len_SET_opt(a,f) \
-        if ((a != NULL) && (sk_num(a) != 0)) \
-                M_ASN1_I2D_len_SET(a,f);
-
-# define M_ASN1_I2D_put_SET_opt(a,f) \
-        if ((a != NULL) && (sk_num(a) != 0)) \
-                M_ASN1_I2D_put_SET(a,f);
-
-# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
-        if ((a != NULL) && (sk_num(a) != 0)) \
-                M_ASN1_I2D_put_SEQUENCE(a,f);
-
-# define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \
-        if ((a != NULL) && (sk_##type##_num(a) != 0)) \
-                M_ASN1_I2D_put_SEQUENCE_type(type,a,f);
-
-# define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
-        if ((c.slen != 0) && \
-                (M_ASN1_next == \
-                (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
-                { \
-                M_ASN1_D2I_get_imp_set(b,func,free_func,\
-                        tag,V_ASN1_CONTEXT_SPECIFIC); \
-                }
-
-# define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \
-        if ((c.slen != 0) && \
-                (M_ASN1_next == \
-                (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
-                { \
-                M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\
-                        tag,V_ASN1_CONTEXT_SPECIFIC); \
-                }
-
-# define M_ASN1_D2I_get_seq(r,func,free_func) \
-                M_ASN1_D2I_get_imp_set(r,func,free_func,\
-                        V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
-
-# define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \
-                M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
-                                            V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
-
-# define M_ASN1_D2I_get_seq_opt(r,func,free_func) \
-        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
-                V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
-                { M_ASN1_D2I_get_seq(r,func,free_func); }
-
-# define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \
-        if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
-                V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
-                { M_ASN1_D2I_get_seq_type(type,r,func,free_func); }
-
-# define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
-                M_ASN1_D2I_get_imp_set(r,func,free_func,\
-                        x,V_ASN1_CONTEXT_SPECIFIC);
-
-# define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \
-                M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
-                        x,V_ASN1_CONTEXT_SPECIFIC);
-
-# define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \
-        c.q=c.p; \
-        if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\
-                (void (*)())free_func,a,b) == NULL) \
-                { c.line=__LINE__; goto err; } \
-        c.slen-=(c.p-c.q);
-
-# define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \
-        c.q=c.p; \
-        if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\
-                                   free_func,a,b) == NULL) \
-                { c.line=__LINE__; goto err; } \
-        c.slen-=(c.p-c.q);
-
-# define M_ASN1_D2I_get_set_strings(r,func,a,b) \
-        c.q=c.p; \
-        if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \
-                { c.line=__LINE__; goto err; } \
-        c.slen-=(c.p-c.q);
-
-# define M_ASN1_D2I_get_EXP_opt(r,func,tag) \
-        if ((c.slen != 0L) && (M_ASN1_next == \
-                (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
-                { \
-                int Tinf,Ttag,Tclass; \
-                long Tlen; \
-                \
-                c.q=c.p; \
-                Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
-                if (Tinf & 0x80) \
-                        { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
-                        c.line=__LINE__; goto err; } \
-                if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
-                                        Tlen = c.slen - (c.p - c.q) - 2; \
-                if (func(&(r),&c.p,Tlen) == NULL) \
-                        { c.line=__LINE__; goto err; } \
-                if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
-                        Tlen = c.slen - (c.p - c.q); \
-                        if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \
-                                { c.error=ERR_R_MISSING_ASN1_EOS; \
-                                c.line=__LINE__; goto err; } \
-                }\
-                c.slen-=(c.p-c.q); \
-                }
-
-# define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \
-        if ((c.slen != 0) && (M_ASN1_next == \
-                (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
-                { \
-                int Tinf,Ttag,Tclass; \
-                long Tlen; \
-                \
-                c.q=c.p; \
-                Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
-                if (Tinf & 0x80) \
-                        { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
-                        c.line=__LINE__; goto err; } \
-                if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
-                                        Tlen = c.slen - (c.p - c.q) - 2; \
-                if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \
-                        (void (*)())free_func, \
-                        b,V_ASN1_UNIVERSAL) == NULL) \
-                        { c.line=__LINE__; goto err; } \
-                if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
-                        Tlen = c.slen - (c.p - c.q); \
-                        if(!ASN1_check_infinite_end(&c.p, Tlen)) \
-                                { c.error=ERR_R_MISSING_ASN1_EOS; \
-                                c.line=__LINE__; goto err; } \
-                }\
-                c.slen-=(c.p-c.q); \
-                }
-
-# define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \
-        if ((c.slen != 0) && (M_ASN1_next == \
-                (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
-                { \
-                int Tinf,Ttag,Tclass; \
-                long Tlen; \
-                \
-                c.q=c.p; \
-                Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
-                if (Tinf & 0x80) \
-                        { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
-                        c.line=__LINE__; goto err; } \
-                if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
-                                        Tlen = c.slen - (c.p - c.q) - 2; \
-                if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \
-                        free_func,b,V_ASN1_UNIVERSAL) == NULL) \
-                        { c.line=__LINE__; goto err; } \
-                if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
-                        Tlen = c.slen - (c.p - c.q); \
-                        if(!ASN1_check_infinite_end(&c.p, Tlen)) \
-                                { c.error=ERR_R_MISSING_ASN1_EOS; \
-                                c.line=__LINE__; goto err; } \
-                }\
-                c.slen-=(c.p-c.q); \
-                }
-
-/* New macros */
-# define M_ASN1_New_Malloc(ret,type) \
-        if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \
-                { c.line=__LINE__; goto err2; }
-
-# define M_ASN1_New(arg,func) \
-        if (((arg)=func()) == NULL) return(NULL)
-
-# define M_ASN1_New_Error(a) \
-/*-     err:    ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \
-                return(NULL);*/ \
-        err2:   ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \
-                return(NULL)
-
-/*
- * BIG UGLY WARNING! This is so damn ugly I wanna puke.  Unfortunately, some
- * macros that use ASN1_const_CTX still insist on writing in the input
- * stream.  ARGH! ARGH! ARGH! Let's get rid of this macro package. Please? --
- * Richard Levitte
- */
-# define M_ASN1_next             (*((unsigned char *)(c.p)))
-# define M_ASN1_next_prev        (*((unsigned char *)(c.q)))
-
-/*************************************************/
-
-# define M_ASN1_I2D_vars(a)      int r=0,ret=0; \
-                                unsigned char *p; \
-                                if (a == NULL) return(0)
-
-/* Length Macros */
-# define M_ASN1_I2D_len(a,f)     ret+=f(a,NULL)
-# define M_ASN1_I2D_len_IMP_opt(a,f)     if (a != NULL) M_ASN1_I2D_len(a,f)
-
-# define M_ASN1_I2D_len_SET(a,f) \
-                ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
-
-# define M_ASN1_I2D_len_SET_type(type,a,f) \
-                ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \
-                                            V_ASN1_UNIVERSAL,IS_SET);
-
-# define M_ASN1_I2D_len_SEQUENCE(a,f) \
-                ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
-                                  IS_SEQUENCE);
-
-# define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \
-                ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \
-                                            V_ASN1_UNIVERSAL,IS_SEQUENCE)
-
-# define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \
-                if ((a != NULL) && (sk_num(a) != 0)) \
-                        M_ASN1_I2D_len_SEQUENCE(a,f);
-
-# define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \
-                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
-                        M_ASN1_I2D_len_SEQUENCE_type(type,a,f);
-
-# define M_ASN1_I2D_len_IMP_SET(a,f,x) \
-                ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);
-
-# define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \
-                ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
-                                            V_ASN1_CONTEXT_SPECIFIC,IS_SET);
-
-# define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \
-                if ((a != NULL) && (sk_num(a) != 0)) \
-                        ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
-                                          IS_SET);
-
-# define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \
-                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
-                        ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
-                                               V_ASN1_CONTEXT_SPECIFIC,IS_SET);
-
-# define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \
-                ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
-                                  IS_SEQUENCE);
-
-# define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \
-                if ((a != NULL) && (sk_num(a) != 0)) \
-                        ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
-                                          IS_SEQUENCE);
-
-# define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \
-                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
-                        ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
-                                                    V_ASN1_CONTEXT_SPECIFIC, \
-                                                    IS_SEQUENCE);
-
-# define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \
-                if (a != NULL)\
-                        { \
-                        v=f(a,NULL); \
-                        ret+=ASN1_object_size(1,v,mtag); \
-                        }
-
-# define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \
-                if ((a != NULL) && (sk_num(a) != 0))\
-                        { \
-                        v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
-                        ret+=ASN1_object_size(1,v,mtag); \
-                        }
-
-# define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
-                if ((a != NULL) && (sk_num(a) != 0))\
-                        { \
-                        v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \
-                                       IS_SEQUENCE); \
-                        ret+=ASN1_object_size(1,v,mtag); \
-                        }
-
-# define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
-                if ((a != NULL) && (sk_##type##_num(a) != 0))\
-                        { \
-                        v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
-                                                 V_ASN1_UNIVERSAL, \
-                                                 IS_SEQUENCE); \
-                        ret+=ASN1_object_size(1,v,mtag); \
-                        }
-
-/* Put Macros */
-# define M_ASN1_I2D_put(a,f)     f(a,&p)
-
-# define M_ASN1_I2D_put_IMP_opt(a,f,t)   \
-                if (a != NULL) \
-                        { \
-                        unsigned char *q=p; \
-                        f(a,&p); \
-                        *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\
-                        }
-
-# define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\
-                        V_ASN1_UNIVERSAL,IS_SET)
-# define M_ASN1_I2D_put_SET_type(type,a,f) \
-     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET)
-# define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
-                        V_ASN1_CONTEXT_SPECIFIC,IS_SET)
-# define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \
-     i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET)
-# define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
-                        V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE)
-
-# define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
-                                             V_ASN1_UNIVERSAL,IS_SEQUENCE)
-
-# define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \
-     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
-                            IS_SEQUENCE)
-
-# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
-                if ((a != NULL) && (sk_num(a) != 0)) \
-                        M_ASN1_I2D_put_SEQUENCE(a,f);
-
-# define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \
-                if ((a != NULL) && (sk_num(a) != 0)) \
-                        { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
-                                       IS_SET); }
-
-# define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \
-                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
-                        { i2d_ASN1_SET_OF_##type(a,&p,f,x, \
-                                                 V_ASN1_CONTEXT_SPECIFIC, \
-                                                 IS_SET); }
-
-# define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \
-                if ((a != NULL) && (sk_num(a) != 0)) \
-                        { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
-                                       IS_SEQUENCE); }
-
-# define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \
-                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
-                        { i2d_ASN1_SET_OF_##type(a,&p,f,x, \
-                                                 V_ASN1_CONTEXT_SPECIFIC, \
-                                                 IS_SEQUENCE); }
-
-# define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \
-                if (a != NULL) \
-                        { \
-                        ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \
-                        f(a,&p); \
-                        }
-
-# define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \
-                if ((a != NULL) && (sk_num(a) != 0)) \
-                        { \
-                        ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
-                        i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
-                        }
-
-# define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
-                if ((a != NULL) && (sk_num(a) != 0)) \
-                        { \
-                        ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
-                        i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
-                        }
-
-# define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
-                if ((a != NULL) && (sk_##type##_num(a) != 0)) \
-                        { \
-                        ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
-                        i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
-                                               IS_SEQUENCE); \
-                        }
-
-# define M_ASN1_I2D_seq_total() \
-                r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \
-                if (pp == NULL) return(r); \
-                p= *pp; \
-                ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
-
-# define M_ASN1_I2D_INF_seq_start(tag,ctx) \
-                *(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \
-                *(p++)=0x80
-
-# define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00
-
-# define M_ASN1_I2D_finish()     *pp=p; \
-                                return(r);
-
-int asn1_GetSequence(ASN1_const_CTX *c, long *length);
-void asn1_add_error(const unsigned char *address, int offset);
-#ifdef  __cplusplus
-}
-#endif
-
-#endif
diff --git a/include/openssl/asn1t.h b/include/openssl/asn1t.h
index 7a2611e..dfd9dac 100644
--- a/include/openssl/asn1t.h
+++ b/include/openssl/asn1t.h
@@ -825,6 +825,19 @@ typedef struct ASN1_STREAM_ARG_st {
                 return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
         }
 
+# define IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(stname) \
+        static stname *d2i_##stname(stname **a, \
+                                   const unsigned char **in, long len) \
+        { \
+                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, \
+                                               ASN1_ITEM_rptr(stname)); \
+        } \
+        static int i2d_##stname(stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_i2d((ASN1_VALUE *)a, out, \
+                                     ASN1_ITEM_rptr(stname)); \
+        }
+
 /*
  * This includes evil casts to remove const: they will go away when full ASN1
  * constification is done.
diff --git a/ssl/Makefile b/ssl/Makefile
index 07a4f29..ef10a11 100644
--- a/ssl/Makefile
+++ b/ssl/Makefile
@@ -674,7 +674,7 @@ ssl_algs.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
 ssl_algs.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
 ssl_algs.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
 ssl_algs.o: record/record.h ssl_algs.c ssl_locl.h
-ssl_asn1.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/asn1_mac.h
+ssl_asn1.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/asn1t.h
 ssl_asn1.o: ../include/openssl/bio.h ../include/openssl/buffer.h
 ssl_asn1.o: ../include/openssl/comp.h ../include/openssl/crypto.h
 ssl_asn1.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index dd02b41..fb2a495 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -85,537 +85,373 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "ssl_locl.h"
-#include <openssl/asn1_mac.h>
-#include <openssl/objects.h>
+#include <openssl/asn1t.h>
 #include <openssl/x509.h>
 
-typedef struct ssl_session_asn1_st {
-    ASN1_INTEGER version;
-    ASN1_INTEGER ssl_version;
-    ASN1_OCTET_STRING cipher;
-    ASN1_OCTET_STRING comp_id;
-    ASN1_OCTET_STRING master_key;
-    ASN1_OCTET_STRING session_id;
-    ASN1_OCTET_STRING session_id_context;
+typedef struct {
+    long version;
+    long ssl_version;
+    ASN1_OCTET_STRING *cipher;
+    ASN1_OCTET_STRING *comp_id;
+    ASN1_OCTET_STRING *master_key;
+    ASN1_OCTET_STRING *session_id;
 #ifndef OPENSSL_NO_KRB5
-    ASN1_OCTET_STRING krb5_princ;
-#endif                          /* OPENSSL_NO_KRB5 */
-    ASN1_INTEGER time;
-    ASN1_INTEGER timeout;
-    ASN1_INTEGER verify_result;
+    ASN1_OCTET_STRING *krb5_princ;
+#endif
+    ASN1_OCTET_STRING *key_arg;
+    long time;
+    long timeout;
+    X509 *peer;
+    ASN1_OCTET_STRING *session_id_context;
+    long verify_result;
 #ifndef OPENSSL_NO_TLSEXT
-    ASN1_OCTET_STRING tlsext_hostname;
-    ASN1_INTEGER tlsext_tick_lifetime;
-    ASN1_OCTET_STRING tlsext_tick;
-#endif                          /* OPENSSL_NO_TLSEXT */
-#ifndef OPENSSL_NO_PSK
-    ASN1_OCTET_STRING psk_identity_hint;
-    ASN1_OCTET_STRING psk_identity;
-#endif                          /* OPENSSL_NO_PSK */
+    ASN1_OCTET_STRING *tlsext_hostname;
+    long tlsext_tick_lifetime_hint;
+    ASN1_OCTET_STRING *tlsext_tick;
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+    ASN1_OCTET_STRING *psk_identity_hint;
+    ASN1_OCTET_STRING *psk_identity;
+#endif
 #ifndef OPENSSL_NO_SRP
-    ASN1_OCTET_STRING srp_username;
-#endif                          /* OPENSSL_NO_SRP */
-    ASN1_INTEGER flags;
+    ASN1_OCTET_STRING *srp_username;
+#endif
+    long flags;
 } SSL_SESSION_ASN1;
 
+ASN1_SEQUENCE(SSL_SESSION_ASN1) = {
+    ASN1_SIMPLE(SSL_SESSION_ASN1, version, LONG),
+    ASN1_SIMPLE(SSL_SESSION_ASN1, ssl_version, LONG),
+    ASN1_SIMPLE(SSL_SESSION_ASN1, cipher, ASN1_OCTET_STRING),
+    ASN1_SIMPLE(SSL_SESSION_ASN1, session_id, ASN1_OCTET_STRING),
+    ASN1_SIMPLE(SSL_SESSION_ASN1, master_key, ASN1_OCTET_STRING),
+#ifndef OPENSSL_NO_KRB5
+    ASN1_OPT(SSL_SESSION_ASN1, krb5_princ, ASN1_OCTET_STRING),
+#endif
+    ASN1_IMP_OPT(SSL_SESSION_ASN1, key_arg, ASN1_OCTET_STRING, 0),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, time, ZLONG, 1),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, timeout, ZLONG, 2),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, peer, X509, 3),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, session_id_context, ASN1_OCTET_STRING, 4),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, verify_result, ZLONG, 5),
+#ifndef OPENSSL_NO_TLSEXT
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_hostname, ASN1_OCTET_STRING, 6),
+#endif
+#ifndef OPENSSL_NO_PSK
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, psk_identity_hint, ASN1_OCTET_STRING, 7),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, psk_identity, ASN1_OCTET_STRING, 8),
+#endif
+#ifndef OPENSSL_NO_TLSEXT
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_tick_lifetime_hint, ZLONG, 9),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_tick, ASN1_OCTET_STRING, 10),
+#endif
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, comp_id, ASN1_OCTET_STRING, 11),
+#ifndef OPENSSL_NO_SRP
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, srp_username, ASN1_OCTET_STRING, 12),
+#endif
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, flags, ZLONG, 13)
+} ASN1_SEQUENCE_END(SSL_SESSION_ASN1)
+
+IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1)
+
+/* Utility functions for i2d_SSL_SESSION */
+
+/* Initialise OCTET STRING from buffer and length */
+
+static void ssl_session_oinit(ASN1_OCTET_STRING **dest, ASN1_OCTET_STRING *os,
+                              unsigned char *data, size_t len)
+{
+    os->data = data;
+    os->length = len;
+    os->flags = 0;
+    *dest = os;
+}
+
+/* Initialise OCTET STRING from string */
+static void ssl_session_sinit(ASN1_OCTET_STRING **dest, ASN1_OCTET_STRING *os,
+                              char *data)
+{
+    if (data != NULL)
+        ssl_session_oinit(dest, os, (unsigned char *)data, strlen(data));
+    else
+        *dest = NULL;
+}
+
 int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
 {
-#define LSIZE2 (sizeof(long)*2)
-    int v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v7 = 0, v8 = 0;
-    unsigned char buf[4], ibuf1[LSIZE2], ibuf2[LSIZE2];
-    unsigned char ibuf3[LSIZE2], ibuf4[LSIZE2], ibuf5[LSIZE2];
+
+    SSL_SESSION_ASN1 as;
+
+    ASN1_OCTET_STRING cipher;
+    unsigned char cipher_data[2];
+    ASN1_OCTET_STRING master_key, session_id, sid_ctx;
+
+#ifndef OPENSSL_NO_COMP
+    ASN1_OCTET_STRING comp_id;
+    unsigned char comp_id_data;
+#endif
+
 #ifndef OPENSSL_NO_TLSEXT
-    int v6 = 0, v9 = 0, v10 = 0;
-    unsigned char ibuf6[LSIZE2];
+    ASN1_OCTET_STRING tlsext_hostname, tlsext_tick;
 #endif
-#ifndef OPENSSL_NO_COMP
-    unsigned char cbuf;
-    int v11 = 0;
+
+#ifndef OPENSSL_NO_KRB5
+    ASN1_OCTET_STRING krb5_princ;
 #endif
+
 #ifndef OPENSSL_NO_SRP
-    int v12 = 0;
+    ASN1_OCTET_STRING srp_username;
+#endif
+
+#ifndef OPENSSL_NO_PSK
+    ASN1_OCTET_STRING psk_identity, psk_identity_hint;
 #endif
-    unsigned char fbuf[LSIZE2];
-    int v13 = 0;
+
     long l;
-    SSL_SESSION_ASN1 a;
-    M_ASN1_I2D_vars(in);
 
     if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0)))
-        return (0);
-
-    /*
-     * Note that I cheat in the following 2 assignments.  I know that if the
-     * ASN1_INTEGER passed to ASN1_INTEGER_set is > sizeof(long)+1, the
-     * buffer will not be re-OPENSSL_malloc()ed. This is a bit evil but makes
-     * things simple, no dynamic allocation to clean up :-)
-     */
-    a.version.length = LSIZE2;
-    a.version.type = V_ASN1_INTEGER;
-    a.version.data = ibuf1;
-    ASN1_INTEGER_set(&(a.version), SSL_SESSION_ASN1_VERSION);
-
-    a.ssl_version.length = LSIZE2;
-    a.ssl_version.type = V_ASN1_INTEGER;
-    a.ssl_version.data = ibuf2;
-    ASN1_INTEGER_set(&(a.ssl_version), in->ssl_version);
-
-    a.cipher.type = V_ASN1_OCTET_STRING;
-    a.cipher.data = buf;
+        return 0;
+
+    memset(&as, 0, sizeof(as));
+
+    as.version = SSL_SESSION_ASN1_VERSION;
+    as.ssl_version = in->ssl_version;
 
     if (in->cipher == NULL)
         l = in->cipher_id;
     else
         l = in->cipher->id;
-    a.cipher.length = 2;
-    buf[0] = ((unsigned char)(l >> 8L)) & 0xff;
-    buf[1] = ((unsigned char)(l)) & 0xff;
+    cipher_data[0] = ((unsigned char)(l >> 8L)) & 0xff;
+    cipher_data[1] = ((unsigned char)(l)) & 0xff;
+
+    ssl_session_oinit(&as.cipher, &cipher, cipher_data, 2);
 
 #ifndef OPENSSL_NO_COMP
     if (in->compress_meth) {
-        cbuf = (unsigned char)in->compress_meth;
-        a.comp_id.length = 1;
-        a.comp_id.type = V_ASN1_OCTET_STRING;
-        a.comp_id.data = &cbuf;
+        comp_id_data = (unsigned char)in->compress_meth;
+        ssl_session_oinit(&as.comp_id, &comp_id, &comp_id_data, 1);
     }
 #endif
 
-    a.master_key.length = in->master_key_length;
-    a.master_key.type = V_ASN1_OCTET_STRING;
-    a.master_key.data = in->master_key;
-
-    a.session_id.length = in->session_id_length;
-    a.session_id.type = V_ASN1_OCTET_STRING;
-    a.session_id.data = in->session_id;
+    ssl_session_oinit(&as.master_key, &master_key,
+                      in->master_key, in->master_key_length);
 
-    a.session_id_context.length = in->sid_ctx_length;
-    a.session_id_context.type = V_ASN1_OCTET_STRING;
-    a.session_id_context.data = in->sid_ctx;
+    ssl_session_oinit(&as.session_id, &session_id,
+                      in->session_id, in->session_id_length);
 
+    ssl_session_oinit(&as.session_id_context, &sid_ctx,
+                      in->sid_ctx, in->sid_ctx_length);
 #ifndef OPENSSL_NO_KRB5
     if (in->krb5_client_princ_len) {
-        a.krb5_princ.length = in->krb5_client_princ_len;
-        a.krb5_princ.type = V_ASN1_OCTET_STRING;
-        a.krb5_princ.data = in->krb5_client_princ;
+        ssl_session_oinit(&as.krb5_princ, &krb5_princ,
+                          in->krb5_client_princ, in->krb5_client_princ_len);
     }
 #endif                          /* OPENSSL_NO_KRB5 */
 
-    if (in->time != 0L) {
-        a.time.length = LSIZE2;
-        a.time.type = V_ASN1_INTEGER;
-        a.time.data = ibuf3;
-        ASN1_INTEGER_set(&(a.time), in->time);
-    }
+    as.time = in->time;
+    as.timeout = in->timeout;
+    as.verify_result = in->verify_result;
 
-    if (in->timeout != 0L) {
-        a.timeout.length = LSIZE2;
-        a.timeout.type = V_ASN1_INTEGER;
-        a.timeout.data = ibuf4;
-        ASN1_INTEGER_set(&(a.timeout), in->timeout);
-    }
+    as.peer = in->peer;
 
-    if (in->verify_result != X509_V_OK) {
-        a.verify_result.length = LSIZE2;
-        a.verify_result.type = V_ASN1_INTEGER;
-        a.verify_result.data = ibuf5;
-        ASN1_INTEGER_set(&a.verify_result, in->verify_result);
-    }
 #ifndef OPENSSL_NO_TLSEXT
-    if (in->tlsext_hostname) {
-        a.tlsext_hostname.length = strlen(in->tlsext_hostname);
-        a.tlsext_hostname.type = V_ASN1_OCTET_STRING;
-        a.tlsext_hostname.data = (unsigned char *)in->tlsext_hostname;
-    }
+    ssl_session_sinit(&as.tlsext_hostname, &tlsext_hostname,
+                      in->tlsext_hostname);
     if (in->tlsext_tick) {
-        a.tlsext_tick.length = in->tlsext_ticklen;
-        a.tlsext_tick.type = V_ASN1_OCTET_STRING;
-        a.tlsext_tick.data = (unsigned char *)in->tlsext_tick;
-    }
-    if (in->tlsext_tick_lifetime_hint > 0) {
-        a.tlsext_tick_lifetime.length = LSIZE2;
-        a.tlsext_tick_lifetime.type = V_ASN1_INTEGER;
-        a.tlsext_tick_lifetime.data = ibuf6;
-        ASN1_INTEGER_set(&a.tlsext_tick_lifetime,
-                         in->tlsext_tick_lifetime_hint);
+        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
-    if (in->psk_identity_hint) {
-        a.psk_identity_hint.length = strlen(in->psk_identity_hint);
-        a.psk_identity_hint.type = V_ASN1_OCTET_STRING;
-        a.psk_identity_hint.data = (unsigned char *)(in->psk_identity_hint);
-    }
-    if (in->psk_identity) {
-        a.psk_identity.length = strlen(in->psk_identity);
-        a.psk_identity.type = V_ASN1_OCTET_STRING;
-        a.psk_identity.data = (unsigned char *)(in->psk_identity);
-    }
+    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
-    if (in->srp_username) {
-        a.srp_username.length = strlen(in->srp_username);
-        a.srp_username.type = V_ASN1_OCTET_STRING;
-        a.srp_username.data = (unsigned char *)(in->srp_username);
-    }
+    ssl_session_sinit(&as.srp_username, &srp_username, in->srp_username);
 #endif                          /* OPENSSL_NO_SRP */
 
-    if (in->flags) {
-        a.flags.length = LSIZE2;
-        a.flags.type = V_ASN1_INTEGER;
-        a.flags.data = fbuf;
-        ASN1_INTEGER_set(&a.flags, in->flags);
-    }
+    as.flags = in->flags;
 
-    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);
+    return i2d_SSL_SESSION_ASN1(&as, pp);
 
-#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();
+/* Utility functions for d2i_SSL_SESSION */
 
-    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();
+/* 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)
 {
-    int 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_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER);
-    if (ai.data != NULL) {
-        OPENSSL_free(ai.data);
-        ai.data = NULL;
-        ai.length = 0;
-    }
+    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;
 
-    /* we don't care about the version right now :-) */
-    M_ASN1_D2I_get_x(ASN1_INTEGER, 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;
+    if (0) {
+        i2d_SSL_SESSION_ASN1(NULL, NULL);
     }
 
-    os.data = NULL;
-    os.length = 0;
-    M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING);
-    if ((ssl_version >> 8) == SSL3_VERSION_MAJOR
-        || (ssl_version >> 8) == DTLS1_VERSION_MAJOR
-        || ssl_version == DTLS1_BAD_VER) {
-        if (os.length != 2) {
-            c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH;
-            c.line = __LINE__;
+    if (!a || !*a) {
+        ret = SSL_SESSION_new();
+        if (ret == NULL)
             goto err;
-        }
-        id = 0x03000000L |
-            ((unsigned long)os.data[0] << 8L) | (unsigned long)os.data[1];
     } else {
-        c.error = SSL_R_UNKNOWN_SSL_VERSION;
-        c.line = __LINE__;
+        ret = *a;
+    }
+
+    if (as->version != SSL_SESSION_ASN1_VERSION) {
+        SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNKNOWN_SSL_VERSION);
         goto err;
     }
 
-    ret->cipher = NULL;
-    ret->cipher_id = id;
+    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;
+    }
 
-    M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING);
-    i = SSL3_MAX_SSL_SESSION_ID_LENGTH;
+    ret->ssl_version = (int)as->ssl_version;
 
-    if (os.length > i)
-        os.length = i;
-    if (os.length > (int)sizeof(ret->session_id)) /* can't happen */
-        os.length = sizeof(ret->session_id);
+    if (as->cipher->length != 2) {
+        SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_CIPHER_CODE_WRONG_LENGTH);
+        goto err;
+    }
 
-    ret->session_id_length = os.length;
-    OPENSSL_assert(os.length <= (int)sizeof(ret->session_id));
-    memcpy(ret->session_id, os.data, os.length);
+    p = as->cipher->data;
+    id = 0x03000000L | ((unsigned long)p[0] << 8L) | (unsigned long)p[1];
 
-    M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING);
-    if (os.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);
+    ret->cipher = NULL;
+    ret->cipher_id = id;
 
-    os.length = 0;
+    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;
 
 #ifndef OPENSSL_NO_KRB5
-    os.length = 0;
-    M_ASN1_D2I_get_opt(osp, d2i_ASN1_OCTET_STRING, V_ASN1_OCTET_STRING);
-    if (os.data) {
-        if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH)
-            ret->krb5_client_princ_len = 0;
-        else
-            ret->krb5_client_princ_len = os.length;
-        memcpy(ret->krb5_client_princ, os.data, ret->krb5_client_princ_len);
-        OPENSSL_free(os.data);
-        os.data = NULL;
-        os.length = 0;
-    } else
-        ret->krb5_client_princ_len = 0;
+    if (!ssl_session_memcpy(ret->krb5_client_princ, &ret->krb5_client_princ_len,
+                            as->krb5_princ, SSL_MAX_PRINCIPAL_LENGTH))
+        goto err;
 #endif                          /* OPENSSL_NO_KRB5 */
 
-    M_ASN1_D2I_get_IMP_opt(osp, d2i_ASN1_OCTET_STRING, 0,
-                           V_ASN1_OCTET_STRING);
-    if (os.data != NULL)
-        OPENSSL_free(os.data);
-
-    ai.length = 0;
-    M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 1);
-    if (ai.data != NULL) {
-        ret->time = ASN1_INTEGER_get(aip);
-        OPENSSL_free(ai.data);
-        ai.data = NULL;
-        ai.length = 0;
-    } else
+    if (as->time != 0)
+        ret->time = as->time;
+    else
         ret->time = (unsigned long)time(NULL);
 
-    ai.length = 0;
-    M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 2);
-    if (ai.data != NULL) {
-        ret->timeout = ASN1_INTEGER_get(aip);
-        OPENSSL_free(ai.data);
-        ai.data = NULL;
-        ai.length = 0;
-    } else
+    if (as->timeout != 0)
+        ret->timeout = as->timeout;
+    else
         ret->timeout = 3;
 
-    if (ret->peer != NULL) {
-        X509_free(ret->peer);
-        ret->peer = NULL;
-    }
-    M_ASN1_D2I_get_EXP_opt(ret->peer, d2i_X509, 3);
+    X509_free(ret->peer);
+    ret->peer = as->peer;
+    as->peer = NULL;
 
-    os.length = 0;
-    os.data = NULL;
-    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 4);
+    if (!ssl_session_memcpy(ret->sid_ctx, &ret->sid_ctx_length,
+                            as->session_id_context, SSL_MAX_SID_CTX_LENGTH))
+        goto err;
 
-    if (os.data != NULL) {
-        if (os.length > SSL_MAX_SID_CTX_LENGTH) {
-            c.error = SSL_R_BAD_LENGTH;
-            c.line = __LINE__;
-            goto err;
-        } else {
-            ret->sid_ctx_length = os.length;
-            memcpy(ret->sid_ctx, os.data, os.length);
-        }
-        OPENSSL_free(os.data);
-        os.data = NULL;
-        os.length = 0;
-    } else
-        ret->sid_ctx_length = 0;
-
-    ai.length = 0;
-    M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 5);
-    if (ai.data != NULL) {
-        ret->verify_result = ASN1_INTEGER_get(aip);
-        OPENSSL_free(ai.data);
-        ai.data = NULL;
-        ai.length = 0;
-    } else
-        ret->verify_result = X509_V_OK;
+    /* NB: this defaults to zero which is X509_V_OK */
+    ret->verify_result = as->verify_result;
 
 #ifndef OPENSSL_NO_TLSEXT
-    os.length = 0;
-    os.data = NULL;
-    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 6);
-    if (os.data) {
-        ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length);
-        OPENSSL_free(os.data);
-        os.data = NULL;
-        os.length = 0;
-    } else
-        ret->tlsext_hostname = NULL;
+    if (!ssl_session_strndup(&ret->tlsext_hostname, as->tlsext_hostname))
+        goto err;
 #endif                          /* OPENSSL_NO_TLSEXT */
 
 #ifndef OPENSSL_NO_PSK
-    os.length = 0;
-    os.data = NULL;
-    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 7);
-    if (os.data) {
-        ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length);
-        OPENSSL_free(os.data);
-        os.data = NULL;
-        os.length = 0;
-    } else
-        ret->psk_identity_hint = NULL;
-
-    os.length = 0;
-    os.data = NULL;
-    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 8);
-    if (os.data) {
-        ret->psk_identity = BUF_strndup((char *)os.data, os.length);
-        OPENSSL_free(os.data);
-        os.data = NULL;
-        os.length = 0;
-    } else
-        ret->psk_identity = NULL;
-#endif                          /* OPENSSL_NO_PSK */
+    if (!ssl_session_strndup(&ret->psk_identity_hint, as->psk_identity_hint))
+        goto err;
+    if (!ssl_session_strndup(&ret->psk_identity, as->psk_identity))
+        goto err;
+#endif
 
 #ifndef OPENSSL_NO_TLSEXT
-    ai.length = 0;
-    M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 9);
-    if (ai.data != NULL) {
-        ret->tlsext_tick_lifetime_hint = ASN1_INTEGER_get(aip);
-        OPENSSL_free(ai.data);
-        ai.data = NULL;
-        ai.length = 0;
-    } else
-        ret->tlsext_tick_lifetime_hint = 0;
-    os.length = 0;
-    os.data = NULL;
-    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 10);
-    if (os.data) {
-        ret->tlsext_tick = os.data;
-        ret->tlsext_ticklen = os.length;
-        os.data = NULL;
-        os.length = 0;
-    } else
+    ret->tlsext_tick_lifetime_hint = as->tlsext_tick_lifetime_hint;
+    if (as->tlsext_tick) {
+        ret->tlsext_tick = as->tlsext_tick->data;
+        ret->tlsext_ticklen = as->tlsext_tick->length;
+        as->tlsext_tick->data = NULL;
+    } else {
         ret->tlsext_tick = NULL;
+    }
 #endif                          /* OPENSSL_NO_TLSEXT */
 #ifndef OPENSSL_NO_COMP
-    os.length = 0;
-    os.data = NULL;
-    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 11);
-    if (os.data) {
-        ret->compress_meth = os.data[0];
-        OPENSSL_free(os.data);
-        os.data = NULL;
+    if (as->comp_id) {
+        if (as->comp_id->length != 1) {
+            SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_BAD_LENGTH);
+            goto err;
+        }
+        ret->compress_meth = as->comp_id->data[0];
+    } else {
+        ret->compress_meth = 0;
     }
 #endif
 
 #ifndef OPENSSL_NO_SRP
-    os.length = 0;
-    os.data = NULL;
-    M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 12);
-    if (os.data) {
-        ret->srp_username = BUF_strndup((char *)os.data, os.length);
-        OPENSSL_free(os.data);
-        os.data = NULL;
-        os.length = 0;
-    } else
-        ret->srp_username = NULL;
+    if (!ssl_session_strndup(&ret->srp_username, as->srp_username))
+        goto err;
 #endif                          /* OPENSSL_NO_SRP */
-    ai.length = 0;
-    M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 13);
-    if (ai.data != NULL) {
-        ret->flags = ASN1_INTEGER_get(aip);
-        OPENSSL_free(ai.data);
-        ai.data = NULL;
-        ai.length = 0;
-    } else
-        ret->flags = 0;
-
-    M_ASN1_D2I_Finish(a, SSL_SESSION_free, SSL_F_D2I_SSL_SESSION);
+    /* Flags defaults to zero which is fine */
+    ret->flags = as->flags;
+
+    M_ASN1_free_of(as, SSL_SESSION_ASN1);
+
+    if ((a != NULL) && (*a == NULL))
+        *a = ret;
+    *pp = p;
+    return ret;
+
+    err:
+    M_ASN1_free_of(as, SSL_SESSION_ASN1);
+    if ((a == NULL) || (*a != ret))
+        SSL_SESSION_free(ret);
+    return NULL;
 }
diff --git a/util/libeay.num b/util/libeay.num
index 54a4ccc..c5d6ae9 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -692,8 +692,8 @@ _des_crypt                              698	NOEXIST::FUNCTION:
 a2d_ASN1_OBJECT                         699	EXIST::FUNCTION:
 a2i_ASN1_INTEGER                        700	EXIST::FUNCTION:
 a2i_ASN1_STRING                         701	EXIST::FUNCTION:
-asn1_Finish                             702	EXIST::FUNCTION:
-asn1_GetSequence                        703	EXIST::FUNCTION:
+asn1_Finish                             702	NOEXIST::FUNCTION:
+asn1_GetSequence                        703	NOEXIST::FUNCTION:
 bn_div_words                            704	NOEXIST::FUNCTION:
 bn_expand2                              705	NOEXIST::FUNCTION:
 bn_mul_add_words                        706	NOEXIST::FUNCTION:
@@ -1060,7 +1060,7 @@ EVP_rc5_32_12_16_cbc                    1087	EXIST::FUNCTION:RC5
 EVP_rc5_32_12_16_cfb64                  1088	EXIST::FUNCTION:RC5
 EVP_rc5_32_12_16_ecb                    1089	EXIST::FUNCTION:RC5
 EVP_rc5_32_12_16_ofb                    1090	EXIST::FUNCTION:RC5
-asn1_add_error                          1091	EXIST::FUNCTION:
+asn1_add_error                          1091	NOEXIST::FUNCTION:
 d2i_ASN1_BMPSTRING                      1092	EXIST::FUNCTION:
 i2d_ASN1_BMPSTRING                      1093	EXIST::FUNCTION:
 BIO_f_ber                               1094	NOEXIST::FUNCTION:
@@ -3295,7 +3295,7 @@ PEM_write_X509_CERT_PAIR                3696	NOEXIST::FUNCTION:
 BIO_dump_indent_cb                      3697	EXIST::FUNCTION:
 d2i_X509_CERT_PAIR                      3698	NOEXIST::FUNCTION:
 STORE_list_private_key_endp             3699	NOEXIST::FUNCTION:
-asn1_const_Finish                       3700	EXIST::FUNCTION:
+asn1_const_Finish                       3700	NOEXIST::FUNCTION:
 i2d_EC_PUBKEY_fp                        3701	EXIST::FUNCTION:EC,STDIO
 BN_nist_mod_256                         3702	EXIST::FUNCTION:
 X509_VERIFY_PARAM_add0_table            3703	EXIST::FUNCTION:
diff --git a/util/mkdef.pl b/util/mkdef.pl
index 7f1c093..674ad1e 100755
--- a/util/mkdef.pl
+++ b/util/mkdef.pl
@@ -309,7 +309,6 @@ $crypto.=" include/openssl/pem.h";
 #$crypto.=" include/openssl/meth.h";
 $crypto.=" include/openssl/asn1.h";
 $crypto.=" include/openssl/asn1t.h";
-$crypto.=" include/openssl/asn1_mac.h";
 $crypto.=" include/openssl/err.h" ; # unless $no_err;
 $crypto.=" include/openssl/pkcs7.h";
 $crypto.=" include/openssl/pkcs12.h";


More information about the openssl-commits mailing list