/* Generated from
 * /jenkins/jobs/oi-userland/workspace/components/library/heimdal/heimdal-7.8.0/lib/hdb/hdb.asn1
 */
/* Do not edit */

#define ASN1_LIB

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <krb5-types.h>
#include "hdb_asn1.h"
#include "hdb_asn1-priv.h"
#include <asn1_err.h>
#include <der.h>
#include <asn1-template.h>

#include <parse_units.h>

int ASN1CALL encode_HDB_extension(unsigned char* p HEIMDAL_UNUSED_ATTRIBUTE,
                                  size_t len HEIMDAL_UNUSED_ATTRIBUTE,
                                  const HDB_extension* data,
                                  size_t* size) {
  size_t ret HEIMDAL_UNUSED_ATTRIBUTE = 0;
  size_t l HEIMDAL_UNUSED_ATTRIBUTE;
  int i HEIMDAL_UNUSED_ATTRIBUTE, e HEIMDAL_UNUSED_ATTRIBUTE;

  /* data */
  {
    size_t Top_tag_oldret HEIMDAL_UNUSED_ATTRIBUTE = ret;
    ret = 0;

    switch ((&(data)->data)->element) {
      case choice_HDB_extension_data_principal_id: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = der_put_integer64(p, len, &((&(data)->data))->u.principal_id, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_Integer,
                                   &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 13, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_policy: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = der_put_utf8string(p, len, &((&(data)->data))->u.policy, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM,
                                   UT_UTF8String, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 12, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_hist_kvno_diff_svc: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = der_put_unsigned(p, len, &((&(data)->data))->u.hist_kvno_diff_svc,
                             &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_Integer,
                                   &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 11, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_hist_kvno_diff_clnt: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = der_put_unsigned(p, len, &((&(data)->data))->u.hist_kvno_diff_clnt,
                             &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_Integer,
                                   &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 10, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_hist_keys: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = encode_HDB_Ext_KeySet(p, len, &((&(data)->data))->u.hist_keys, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 9, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_pkinit_cert: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = encode_HDB_Ext_PKINIT_cert(p, len,
                                       &((&(data)->data))->u.pkinit_cert, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 8, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_last_pw_change: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = encode_KerberosTime(p, len, &((&(data)->data))->u.last_pw_change,
                                &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 7, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_aliases: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = encode_HDB_Ext_Aliases(p, len, &((&(data)->data))->u.aliases, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 6, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_password: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = encode_HDB_Ext_Password(p, len, &((&(data)->data))->u.password, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 5, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_lm_owf: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = encode_HDB_Ext_Lan_Manager_OWF(p, len, &((&(data)->data))->u.lm_owf,
                                           &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 4, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_allowed_to_delegate_to: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = encode_HDB_Ext_Constrained_delegation_acl(
            p, len, &((&(data)->data))->u.allowed_to_delegate_to, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 2, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_pkinit_cert_hash: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = encode_HDB_Ext_PKINIT_hash(
            p, len, &((&(data)->data))->u.pkinit_cert_hash, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_pkinit_acl: {
        size_t data_tag_oldret = ret;
        ret = 0;
        e = encode_HDB_Ext_PKINIT_acl(p, len, &((&(data)->data))->u.pkinit_acl,
                                      &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
        if (e)
          return e;
        p -= l;
        len -= l;
        ret += l;

        ret += data_tag_oldret;
        break;
      }
      case choice_HDB_extension_data_asn1_ellipsis: {
        if (len < (&(data)->data)->u.asn1_ellipsis.length)
          return ASN1_OVERFLOW;
        p -= (&(data)->data)->u.asn1_ellipsis.length;
        ret += (&(data)->data)->u.asn1_ellipsis.length;
        memcpy(p + 1, (&(data)->data)->u.asn1_ellipsis.data,
               (&(data)->data)->u.asn1_ellipsis.length);
        break;
      }
    };
    e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 1, &l);
    if (e)
      return e;
    p -= l;
    len -= l;
    ret += l;

    ret += Top_tag_oldret;
  }
  /* mandatory */
  {
    size_t Top_tag_oldret HEIMDAL_UNUSED_ATTRIBUTE = ret;
    ret = 0;
    e = der_put_boolean(p, len, &(data)->mandatory, &l);
    if (e)
      return e;
    p -= l;
    len -= l;
    ret += l;

    e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, PRIM, UT_Boolean, &l);
    if (e)
      return e;
    p -= l;
    len -= l;
    ret += l;

    e = der_put_length_and_tag(p, len, ret, ASN1_C_CONTEXT, CONS, 0, &l);
    if (e)
      return e;
    p -= l;
    len -= l;
    ret += l;

    ret += Top_tag_oldret;
  }
  e = der_put_length_and_tag(p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);
  if (e)
    return e;
  p -= l;
  len -= l;
  ret += l;

  *size = ret;
  return 0;
}

int ASN1CALL
decode_HDB_extension(const unsigned char* p HEIMDAL_UNUSED_ATTRIBUTE,
                     size_t len HEIMDAL_UNUSED_ATTRIBUTE,
                     HDB_extension* data,
                     size_t* size) {
  size_t ret = 0;
  size_t l HEIMDAL_UNUSED_ATTRIBUTE;
  int e HEIMDAL_UNUSED_ATTRIBUTE;

  memset(data, 0, sizeof(*data));
  {
    size_t Top_datalen, Top_oldlen;
    Der_type Top_type;
    e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &Top_type, UT_Sequence,
                                 &Top_datalen, &l);
    if (e == 0 && Top_type != CONS) {
      e = ASN1_BAD_ID;
    }
    if (e)
      goto fail;
    p += l;
    len -= l;
    ret += l;
    Top_oldlen = len;
    if (Top_datalen > len) {
      e = ASN1_OVERRUN;
      goto fail;
    }
    len = Top_datalen;
    {
      size_t mandatory_datalen, mandatory_oldlen;
      Der_type mandatory_type;
      e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &mandatory_type, 0,
                                   &mandatory_datalen, &l);
      if (e == 0 && mandatory_type != CONS) {
        e = ASN1_BAD_ID;
      }
      if (e)
        goto fail;
      p += l;
      len -= l;
      ret += l;
      mandatory_oldlen = len;
      if (mandatory_datalen > len) {
        e = ASN1_OVERRUN;
        goto fail;
      }
      len = mandatory_datalen;
      {
        size_t mandatory_Tag_datalen, mandatory_Tag_oldlen;
        Der_type mandatory_Tag_type;
        e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &mandatory_Tag_type,
                                     UT_Boolean, &mandatory_Tag_datalen, &l);
        if (e == 0 && mandatory_Tag_type != PRIM) {
          e = ASN1_BAD_ID;
        }
        if (e)
          goto fail;
        p += l;
        len -= l;
        ret += l;
        mandatory_Tag_oldlen = len;
        if (mandatory_Tag_datalen > len) {
          e = ASN1_OVERRUN;
          goto fail;
        }
        len = mandatory_Tag_datalen;
        e = der_get_boolean(p, len, &(data)->mandatory, &l);
        if (e)
          goto fail;
        p += l;
        len -= l;
        ret += l;
        len = mandatory_Tag_oldlen - mandatory_Tag_datalen;
      }
      len = mandatory_oldlen - mandatory_datalen;
    }
    {
      size_t data_datalen, data_oldlen;
      Der_type data_type;
      e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &data_type, 1,
                                   &data_datalen, &l);
      if (e == 0 && data_type != CONS) {
        e = ASN1_BAD_ID;
      }
      if (e)
        goto fail;
      p += l;
      len -= l;
      ret += l;
      data_oldlen = len;
      if (data_datalen > len) {
        e = ASN1_OVERRUN;
        goto fail;
      }
      len = data_datalen;
      if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 0, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_pkinit_acl;
        {
          size_t pkinit_acl_datalen, pkinit_acl_oldlen;
          Der_type pkinit_acl_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &pkinit_acl_type,
                                       0, &pkinit_acl_datalen, &l);
          if (e == 0 && pkinit_acl_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          pkinit_acl_oldlen = len;
          if (pkinit_acl_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = pkinit_acl_datalen;
          e = decode_HDB_Ext_PKINIT_acl(p, len, &(&(data)->data)->u.pkinit_acl,
                                        &l);
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          len = pkinit_acl_oldlen - pkinit_acl_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 1, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_pkinit_cert_hash;
        {
          size_t pkinit_cert_hash_datalen, pkinit_cert_hash_oldlen;
          Der_type pkinit_cert_hash_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT,
                                       &pkinit_cert_hash_type, 1,
                                       &pkinit_cert_hash_datalen, &l);
          if (e == 0 && pkinit_cert_hash_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          pkinit_cert_hash_oldlen = len;
          if (pkinit_cert_hash_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = pkinit_cert_hash_datalen;
          e = decode_HDB_Ext_PKINIT_hash(
              p, len, &(&(data)->data)->u.pkinit_cert_hash, &l);
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          len = pkinit_cert_hash_oldlen - pkinit_cert_hash_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 2, NULL) == 0) {
        (&(data)->data)->element =
            choice_HDB_extension_data_allowed_to_delegate_to;
        {
          size_t allowed_to_delegate_to_datalen, allowed_to_delegate_to_oldlen;
          Der_type allowed_to_delegate_to_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT,
                                       &allowed_to_delegate_to_type, 2,
                                       &allowed_to_delegate_to_datalen, &l);
          if (e == 0 && allowed_to_delegate_to_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          allowed_to_delegate_to_oldlen = len;
          if (allowed_to_delegate_to_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = allowed_to_delegate_to_datalen;
          e = decode_HDB_Ext_Constrained_delegation_acl(
              p, len, &(&(data)->data)->u.allowed_to_delegate_to, &l);
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          len = allowed_to_delegate_to_oldlen - allowed_to_delegate_to_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 4, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_lm_owf;
        {
          size_t lm_owf_datalen, lm_owf_oldlen;
          Der_type lm_owf_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &lm_owf_type, 4,
                                       &lm_owf_datalen, &l);
          if (e == 0 && lm_owf_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          lm_owf_oldlen = len;
          if (lm_owf_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = lm_owf_datalen;
          e = decode_HDB_Ext_Lan_Manager_OWF(p, len, &(&(data)->data)->u.lm_owf,
                                             &l);
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          len = lm_owf_oldlen - lm_owf_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 5, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_password;
        {
          size_t password_datalen, password_oldlen;
          Der_type password_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &password_type,
                                       5, &password_datalen, &l);
          if (e == 0 && password_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          password_oldlen = len;
          if (password_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = password_datalen;
          e = decode_HDB_Ext_Password(p, len, &(&(data)->data)->u.password, &l);
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          len = password_oldlen - password_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 6, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_aliases;
        {
          size_t aliases_datalen, aliases_oldlen;
          Der_type aliases_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &aliases_type, 6,
                                       &aliases_datalen, &l);
          if (e == 0 && aliases_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          aliases_oldlen = len;
          if (aliases_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = aliases_datalen;
          e = decode_HDB_Ext_Aliases(p, len, &(&(data)->data)->u.aliases, &l);
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          len = aliases_oldlen - aliases_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 7, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_last_pw_change;
        {
          size_t last_pw_change_datalen, last_pw_change_oldlen;
          Der_type last_pw_change_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT,
                                       &last_pw_change_type, 7,
                                       &last_pw_change_datalen, &l);
          if (e == 0 && last_pw_change_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          last_pw_change_oldlen = len;
          if (last_pw_change_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = last_pw_change_datalen;
          e = decode_KerberosTime(p, len, &(&(data)->data)->u.last_pw_change,
                                  &l);
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          len = last_pw_change_oldlen - last_pw_change_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 8, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_pkinit_cert;
        {
          size_t pkinit_cert_datalen, pkinit_cert_oldlen;
          Der_type pkinit_cert_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT,
                                       &pkinit_cert_type, 8,
                                       &pkinit_cert_datalen, &l);
          if (e == 0 && pkinit_cert_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          pkinit_cert_oldlen = len;
          if (pkinit_cert_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = pkinit_cert_datalen;
          e = decode_HDB_Ext_PKINIT_cert(p, len,
                                         &(&(data)->data)->u.pkinit_cert, &l);
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          len = pkinit_cert_oldlen - pkinit_cert_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 9, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_hist_keys;
        {
          size_t hist_keys_datalen, hist_keys_oldlen;
          Der_type hist_keys_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &hist_keys_type,
                                       9, &hist_keys_datalen, &l);
          if (e == 0 && hist_keys_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          hist_keys_oldlen = len;
          if (hist_keys_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = hist_keys_datalen;
          e = decode_HDB_Ext_KeySet(p, len, &(&(data)->data)->u.hist_keys, &l);
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          len = hist_keys_oldlen - hist_keys_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 10, NULL) == 0) {
        (&(data)->data)->element =
            choice_HDB_extension_data_hist_kvno_diff_clnt;
        {
          size_t hist_kvno_diff_clnt_datalen, hist_kvno_diff_clnt_oldlen;
          Der_type hist_kvno_diff_clnt_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT,
                                       &hist_kvno_diff_clnt_type, 10,
                                       &hist_kvno_diff_clnt_datalen, &l);
          if (e == 0 && hist_kvno_diff_clnt_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          hist_kvno_diff_clnt_oldlen = len;
          if (hist_kvno_diff_clnt_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = hist_kvno_diff_clnt_datalen;
          {
            size_t hist_kvno_diff_clnt_Tag_datalen,
                hist_kvno_diff_clnt_Tag_oldlen;
            Der_type hist_kvno_diff_clnt_Tag_type;
            e = der_match_tag_and_length(
                p, len, ASN1_C_UNIV, &hist_kvno_diff_clnt_Tag_type, UT_Integer,
                &hist_kvno_diff_clnt_Tag_datalen, &l);
            if (e == 0 && hist_kvno_diff_clnt_Tag_type != PRIM) {
              e = ASN1_BAD_ID;
            }
            if (e)
              goto fail;
            p += l;
            len -= l;
            ret += l;
            hist_kvno_diff_clnt_Tag_oldlen = len;
            if (hist_kvno_diff_clnt_Tag_datalen > len) {
              e = ASN1_OVERRUN;
              goto fail;
            }
            len = hist_kvno_diff_clnt_Tag_datalen;
            e = der_get_unsigned(p, len,
                                 &(&(data)->data)->u.hist_kvno_diff_clnt, &l);
            if (e)
              goto fail;
            p += l;
            len -= l;
            ret += l;
            len = hist_kvno_diff_clnt_Tag_oldlen -
                  hist_kvno_diff_clnt_Tag_datalen;
          }
          len = hist_kvno_diff_clnt_oldlen - hist_kvno_diff_clnt_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 11, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_hist_kvno_diff_svc;
        {
          size_t hist_kvno_diff_svc_datalen, hist_kvno_diff_svc_oldlen;
          Der_type hist_kvno_diff_svc_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT,
                                       &hist_kvno_diff_svc_type, 11,
                                       &hist_kvno_diff_svc_datalen, &l);
          if (e == 0 && hist_kvno_diff_svc_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          hist_kvno_diff_svc_oldlen = len;
          if (hist_kvno_diff_svc_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = hist_kvno_diff_svc_datalen;
          {
            size_t hist_kvno_diff_svc_Tag_datalen,
                hist_kvno_diff_svc_Tag_oldlen;
            Der_type hist_kvno_diff_svc_Tag_type;
            e = der_match_tag_and_length(
                p, len, ASN1_C_UNIV, &hist_kvno_diff_svc_Tag_type, UT_Integer,
                &hist_kvno_diff_svc_Tag_datalen, &l);
            if (e == 0 && hist_kvno_diff_svc_Tag_type != PRIM) {
              e = ASN1_BAD_ID;
            }
            if (e)
              goto fail;
            p += l;
            len -= l;
            ret += l;
            hist_kvno_diff_svc_Tag_oldlen = len;
            if (hist_kvno_diff_svc_Tag_datalen > len) {
              e = ASN1_OVERRUN;
              goto fail;
            }
            len = hist_kvno_diff_svc_Tag_datalen;
            e = der_get_unsigned(p, len, &(&(data)->data)->u.hist_kvno_diff_svc,
                                 &l);
            if (e)
              goto fail;
            p += l;
            len -= l;
            ret += l;
            len =
                hist_kvno_diff_svc_Tag_oldlen - hist_kvno_diff_svc_Tag_datalen;
          }
          len = hist_kvno_diff_svc_oldlen - hist_kvno_diff_svc_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 12, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_policy;
        {
          size_t policy_datalen, policy_oldlen;
          Der_type policy_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT, &policy_type, 12,
                                       &policy_datalen, &l);
          if (e == 0 && policy_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          policy_oldlen = len;
          if (policy_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = policy_datalen;
          {
            size_t policy_Tag_datalen, policy_Tag_oldlen;
            Der_type policy_Tag_type;
            e = der_match_tag_and_length(p, len, ASN1_C_UNIV, &policy_Tag_type,
                                         UT_UTF8String, &policy_Tag_datalen,
                                         &l);
            if (e == 0 && policy_Tag_type != PRIM) {
              e = ASN1_BAD_ID;
            }
            if (e)
              goto fail;
            p += l;
            len -= l;
            ret += l;
            policy_Tag_oldlen = len;
            if (policy_Tag_datalen > len) {
              e = ASN1_OVERRUN;
              goto fail;
            }
            len = policy_Tag_datalen;
            e = der_get_utf8string(p, len, &(&(data)->data)->u.policy, &l);
            if (e)
              goto fail;
            p += l;
            len -= l;
            ret += l;
            len = policy_Tag_oldlen - policy_Tag_datalen;
          }
          len = policy_oldlen - policy_datalen;
        }
      } else if (der_match_tag(p, len, ASN1_C_CONTEXT, CONS, 13, NULL) == 0) {
        (&(data)->data)->element = choice_HDB_extension_data_principal_id;
        {
          size_t principal_id_datalen, principal_id_oldlen;
          Der_type principal_id_type;
          e = der_match_tag_and_length(p, len, ASN1_C_CONTEXT,
                                       &principal_id_type, 13,
                                       &principal_id_datalen, &l);
          if (e == 0 && principal_id_type != CONS) {
            e = ASN1_BAD_ID;
          }
          if (e)
            goto fail;
          p += l;
          len -= l;
          ret += l;
          principal_id_oldlen = len;
          if (principal_id_datalen > len) {
            e = ASN1_OVERRUN;
            goto fail;
          }
          len = principal_id_datalen;
          {
            size_t principal_id_Tag_datalen, principal_id_Tag_oldlen;
            Der_type principal_id_Tag_type;
            e = der_match_tag_and_length(p, len, ASN1_C_UNIV,
                                         &principal_id_Tag_type, UT_Integer,
                                         &principal_id_Tag_datalen, &l);
            if (e == 0 && principal_id_Tag_type != PRIM) {
              e = ASN1_BAD_ID;
            }
            if (e)
              goto fail;
            p += l;
            len -= l;
            ret += l;
            principal_id_Tag_oldlen = len;
            if (principal_id_Tag_datalen > len) {
              e = ASN1_OVERRUN;
              goto fail;
            }
            len = principal_id_Tag_datalen;
            e = der_get_integer64(p, len, &(&(data)->data)->u.principal_id, &l);
            if (e)
              goto fail;
            p += l;
            len -= l;
            ret += l;
            len = principal_id_Tag_oldlen - principal_id_Tag_datalen;
          }
          len = principal_id_oldlen - principal_id_datalen;
        }
      } else {
        (&(data)->data)->element = choice_HDB_extension_data_asn1_ellipsis;
        (&(data)->data)->u.asn1_ellipsis.data = calloc(1, len);
        if ((&(data)->data)->u.asn1_ellipsis.data == NULL) {
          e = ENOMEM;
          goto fail;
        }
        (&(data)->data)->u.asn1_ellipsis.length = len;
        memcpy((&(data)->data)->u.asn1_ellipsis.data, p, len);
        p += len;
        ret += len;
        len = 0;
      }
      len = data_oldlen - data_datalen;
    }
    len = Top_oldlen - Top_datalen;
  }
  if (size)
    *size = ret;
  return 0;
fail:
  free_HDB_extension(data);
  return e;
}

void ASN1CALL free_HDB_extension(HDB_extension* data) {
  *&(data)->mandatory = 0;
  switch ((&(data)->data)->element) {
    case choice_HDB_extension_data_pkinit_acl:
      free_HDB_Ext_PKINIT_acl(&(&(data)->data)->u.pkinit_acl);
      break;
    case choice_HDB_extension_data_pkinit_cert_hash:
      free_HDB_Ext_PKINIT_hash(&(&(data)->data)->u.pkinit_cert_hash);
      break;
    case choice_HDB_extension_data_allowed_to_delegate_to:
      free_HDB_Ext_Constrained_delegation_acl(
          &(&(data)->data)->u.allowed_to_delegate_to);
      break;
    case choice_HDB_extension_data_lm_owf:
      free_HDB_Ext_Lan_Manager_OWF(&(&(data)->data)->u.lm_owf);
      break;
    case choice_HDB_extension_data_password:
      free_HDB_Ext_Password(&(&(data)->data)->u.password);
      break;
    case choice_HDB_extension_data_aliases:
      free_HDB_Ext_Aliases(&(&(data)->data)->u.aliases);
      break;
    case choice_HDB_extension_data_last_pw_change:
      free_KerberosTime(&(&(data)->data)->u.last_pw_change);
      break;
    case choice_HDB_extension_data_pkinit_cert:
      free_HDB_Ext_PKINIT_cert(&(&(data)->data)->u.pkinit_cert);
      break;
    case choice_HDB_extension_data_hist_keys:
      free_HDB_Ext_KeySet(&(&(data)->data)->u.hist_keys);
      break;
    case choice_HDB_extension_data_hist_kvno_diff_clnt:
      *&(&(data)->data)->u.hist_kvno_diff_clnt = 0;
      break;
    case choice_HDB_extension_data_hist_kvno_diff_svc:
      *&(&(data)->data)->u.hist_kvno_diff_svc = 0;
      break;
    case choice_HDB_extension_data_policy:
      der_free_utf8string(&(&(data)->data)->u.policy);
      break;
    case choice_HDB_extension_data_principal_id:
      *&(&(data)->data)->u.principal_id = 0;
      break;
    case choice_HDB_extension_data_asn1_ellipsis:
      der_free_octet_string(&(&(data)->data)->u.asn1_ellipsis);
      break;
  }
}

size_t ASN1CALL length_HDB_extension(const HDB_extension* data) {
  size_t ret = 0;
  {
    size_t Top_tag_oldret = ret;
    ret = 0;
    ret += 1;
    ret += 1 + der_length_len(ret);
    ret += 1 + der_length_len(ret);
    ret += Top_tag_oldret;
  }
  {
    size_t Top_tag_oldret = ret;
    ret = 0;
    switch ((&(data)->data)->element) {
      case choice_HDB_extension_data_pkinit_acl: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += length_HDB_Ext_PKINIT_acl(&(&(data)->data)->u.pkinit_acl);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_pkinit_cert_hash: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += length_HDB_Ext_PKINIT_hash(&(&(data)->data)->u.pkinit_cert_hash);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_allowed_to_delegate_to: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += length_HDB_Ext_Constrained_delegation_acl(
            &(&(data)->data)->u.allowed_to_delegate_to);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_lm_owf: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += length_HDB_Ext_Lan_Manager_OWF(&(&(data)->data)->u.lm_owf);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_password: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += length_HDB_Ext_Password(&(&(data)->data)->u.password);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_aliases: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += length_HDB_Ext_Aliases(&(&(data)->data)->u.aliases);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_last_pw_change: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += length_KerberosTime(&(&(data)->data)->u.last_pw_change);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_pkinit_cert: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += length_HDB_Ext_PKINIT_cert(&(&(data)->data)->u.pkinit_cert);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_hist_keys: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += length_HDB_Ext_KeySet(&(&(data)->data)->u.hist_keys);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_hist_kvno_diff_clnt: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += der_length_unsigned(&(&(data)->data)->u.hist_kvno_diff_clnt);
        ret += 1 + der_length_len(ret);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_hist_kvno_diff_svc: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += der_length_unsigned(&(&(data)->data)->u.hist_kvno_diff_svc);
        ret += 1 + der_length_len(ret);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_policy: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += der_length_utf8string(&(&(data)->data)->u.policy);
        ret += 1 + der_length_len(ret);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_principal_id: {
        size_t data_tag_oldret = ret;
        ret = 0;
        ret += der_length_integer64(&(&(data)->data)->u.principal_id);
        ret += 1 + der_length_len(ret);
        ret += 1 + der_length_len(ret);
        ret += data_tag_oldret;
      } break;
      case choice_HDB_extension_data_asn1_ellipsis:
        ret += (&(data)->data)->u.asn1_ellipsis.length;
        break;
    }
    ret += 1 + der_length_len(ret);
    ret += Top_tag_oldret;
  }
  ret += 1 + der_length_len(ret);
  return ret;
}

int ASN1CALL copy_HDB_extension(const HDB_extension* from, HDB_extension* to) {
  memset(to, 0, sizeof(*to));
  *(&(to)->mandatory) = *(&(from)->mandatory);
  (&(to)->data)->element = (&(from)->data)->element;
  switch ((&(from)->data)->element) {
    case choice_HDB_extension_data_pkinit_acl:
      if (copy_HDB_Ext_PKINIT_acl(&(&(from)->data)->u.pkinit_acl,
                                  &(&(to)->data)->u.pkinit_acl))
        goto fail;
      break;
    case choice_HDB_extension_data_pkinit_cert_hash:
      if (copy_HDB_Ext_PKINIT_hash(&(&(from)->data)->u.pkinit_cert_hash,
                                   &(&(to)->data)->u.pkinit_cert_hash))
        goto fail;
      break;
    case choice_HDB_extension_data_allowed_to_delegate_to:
      if (copy_HDB_Ext_Constrained_delegation_acl(
              &(&(from)->data)->u.allowed_to_delegate_to,
              &(&(to)->data)->u.allowed_to_delegate_to))
        goto fail;
      break;
    case choice_HDB_extension_data_lm_owf:
      if (copy_HDB_Ext_Lan_Manager_OWF(&(&(from)->data)->u.lm_owf,
                                       &(&(to)->data)->u.lm_owf))
        goto fail;
      break;
    case choice_HDB_extension_data_password:
      if (copy_HDB_Ext_Password(&(&(from)->data)->u.password,
                                &(&(to)->data)->u.password))
        goto fail;
      break;
    case choice_HDB_extension_data_aliases:
      if (copy_HDB_Ext_Aliases(&(&(from)->data)->u.aliases,
                               &(&(to)->data)->u.aliases))
        goto fail;
      break;
    case choice_HDB_extension_data_last_pw_change:
      if (copy_KerberosTime(&(&(from)->data)->u.last_pw_change,
                            &(&(to)->data)->u.last_pw_change))
        goto fail;
      break;
    case choice_HDB_extension_data_pkinit_cert:
      if (copy_HDB_Ext_PKINIT_cert(&(&(from)->data)->u.pkinit_cert,
                                   &(&(to)->data)->u.pkinit_cert))
        goto fail;
      break;
    case choice_HDB_extension_data_hist_keys:
      if (copy_HDB_Ext_KeySet(&(&(from)->data)->u.hist_keys,
                              &(&(to)->data)->u.hist_keys))
        goto fail;
      break;
    case choice_HDB_extension_data_hist_kvno_diff_clnt:
      *(&(&(to)->data)->u.hist_kvno_diff_clnt) =
          *(&(&(from)->data)->u.hist_kvno_diff_clnt);
      break;
    case choice_HDB_extension_data_hist_kvno_diff_svc:
      *(&(&(to)->data)->u.hist_kvno_diff_svc) =
          *(&(&(from)->data)->u.hist_kvno_diff_svc);
      break;
    case choice_HDB_extension_data_policy:
      if (der_copy_utf8string(&(&(from)->data)->u.policy,
                              &(&(to)->data)->u.policy))
        goto fail;
      break;
    case choice_HDB_extension_data_principal_id:
      *(&(&(to)->data)->u.principal_id) = *(&(&(from)->data)->u.principal_id);
      break;
    case choice_HDB_extension_data_asn1_ellipsis: {
      int ret;
      ret = der_copy_octet_string(&(&(from)->data)->u.asn1_ellipsis,
                                  &(&(to)->data)->u.asn1_ellipsis);
      if (ret)
        goto fail;
      break;
    }
  }
  return 0;
fail:
  free_HDB_extension(to);
  return ENOMEM;
}
