r9221: Try to merge Heimdal across from lorikeet-heimdal to samba4.
authorAndrew Bartlett <abartlet@samba.org>
Tue, 9 Aug 2005 03:04:47 +0000 (03:04 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:31:33 +0000 (13:31 -0500)
This is my first attempt at this, so there may be a few rough edges.

Andrew Bartlett
(This used to be commit 9a1d2f2fec67930975da856a2d365345cec46216)

73 files changed:
source4/heimdal/fix-export [new file with mode: 0755]
source4/heimdal/kdc/kerberos5.c
source4/heimdal/kdc/pkinit.c
source4/heimdal/lib/asn1/CMS.asn1 [new file with mode: 0644]
source4/heimdal/lib/asn1/asn1-common.h
source4/heimdal/lib/asn1/asn1_gen.c [new file with mode: 0644]
source4/heimdal/lib/asn1/asn1_queue.h [new file with mode: 0644]
source4/heimdal/lib/asn1/canthandle.asn1 [new file with mode: 0644]
source4/heimdal/lib/asn1/der.c [new file with mode: 0644]
source4/heimdal/lib/asn1/der.h
source4/heimdal/lib/asn1/der_cmp.c
source4/heimdal/lib/asn1/der_copy.c
source4/heimdal/lib/asn1/der_free.c
source4/heimdal/lib/asn1/der_get.c
source4/heimdal/lib/asn1/der_length.c
source4/heimdal/lib/asn1/der_locl.h
source4/heimdal/lib/asn1/der_put.c
source4/heimdal/lib/asn1/extra.c [new file with mode: 0644]
source4/heimdal/lib/asn1/gen.c
source4/heimdal/lib/asn1/gen_copy.c
source4/heimdal/lib/asn1/gen_decode.c
source4/heimdal/lib/asn1/gen_encode.c
source4/heimdal/lib/asn1/gen_free.c
source4/heimdal/lib/asn1/gen_glue.c
source4/heimdal/lib/asn1/gen_length.c
source4/heimdal/lib/asn1/gen_locl.h
source4/heimdal/lib/asn1/hash.c
source4/heimdal/lib/asn1/heim_asn1.h [new file with mode: 0644]
source4/heimdal/lib/asn1/k5.asn1
source4/heimdal/lib/asn1/lex.c
source4/heimdal/lib/asn1/lex.h
source4/heimdal/lib/asn1/lex.l
source4/heimdal/lib/asn1/libasn1.h [new file with mode: 0644]
source4/heimdal/lib/asn1/main.c
source4/heimdal/lib/asn1/parse.c
source4/heimdal/lib/asn1/parse.h
source4/heimdal/lib/asn1/parse.y
source4/heimdal/lib/asn1/pkcs12.asn1 [new file with mode: 0644]
source4/heimdal/lib/asn1/pkcs8.asn1 [new file with mode: 0644]
source4/heimdal/lib/asn1/pkcs9.asn1 [new file with mode: 0644]
source4/heimdal/lib/asn1/symbol.c
source4/heimdal/lib/asn1/symbol.h
source4/heimdal/lib/asn1/test.asn1 [new file with mode: 0644]
source4/heimdal/lib/asn1/test.gen [new file with mode: 0644]
source4/heimdal/lib/com_err/lex.c
source4/heimdal/lib/com_err/parse.c
source4/heimdal/lib/com_err/parse.h
source4/heimdal/lib/des/des.c
source4/heimdal/lib/des/des.h
source4/heimdal/lib/des/rnd_keys.c
source4/heimdal/lib/gssapi/accept_sec_context.c
source4/heimdal/lib/gssapi/init_sec_context.c
source4/heimdal/lib/hdb/hdb-private.h
source4/heimdal/lib/krb5/crypto.c
source4/heimdal/lib/krb5/get_cred.c
source4/heimdal/lib/krb5/keytab.c
source4/heimdal/lib/krb5/keytab_file.c
source4/heimdal/lib/krb5/krb5-private.h
source4/heimdal/lib/krb5/krb5-protos.h
source4/heimdal/lib/krb5/krb5.h
source4/heimdal/lib/krb5/pkinit.c
source4/heimdal/lib/krb5/principal.c
source4/heimdal/lib/krb5/rd_cred.c
source4/heimdal/lib/krb5/test_crypto_wrapping.c [new file with mode: 0644]
source4/heimdal/lib/krb5/test_pkinit_dh2key.c [new file with mode: 0644]
source4/heimdal/lib/roken/base64.c
source4/heimdal/lib/roken/ecalloc.c [new file with mode: 0644]
source4/heimdal/lib/roken/estrdup.c [new file with mode: 0644]
source4/heimdal/lib/roken/gai_strerror.c
source4/heimdal/lib/roken/roken.h
source4/heimdal_build/asn1_deps.pl
source4/heimdal_build/config.mk
source4/heimdal_build/krb5-types.h

diff --git a/source4/heimdal/fix-export b/source4/heimdal/fix-export
new file mode 100755 (executable)
index 0000000..4f25ea0
--- /dev/null
@@ -0,0 +1,82 @@
+#! /bin/sh
+# $Id: fix-export,v 1.38 2005/07/05 14:00:51 lha Exp $
+
+echo "fixing distribution in $1..."
+
+test -d "$1" || { echo not a dir in \$1 ; exit 1 ; }
+cd $1
+
+if test "$DATEDVERSION"; then
+       ed -s configure.in << END
+/AC_INIT/s/AC_INIT(\([^,]*\), [^,]*, \(.*\))/AC_INIT(\1, $DATEDVERSION, \2)/
+w
+q
+END
+
+       error=WARN
+       exitcmd=:
+else
+       error=ERROR
+       exitcmd=exit
+fi
+
+ver=`sed -n 's/AC_INIT([^,]*,\([^,]*\),.*/\1/p' configure.in`
+M="*   This is version $ver.   *"
+echo "$M" | sed -e 's/./*/g'
+echo "$M"
+echo "$M" | sed -e 's/./*/g'
+
+ed -s configure.in << END
+/test -z/s,^,#,
+w
+q
+END
+autoreconf --force --install
+(cd doc && makeinfo heimdal.texi)
+
+find . -name Makefile.am | while read f; do
+       for i in `sed -n -e '/^man_MANS/{
+                       :loop
+                       p
+                       /[^\\]$/b quit
+                       n
+                       b loop
+                       }
+               :quit' $f | sed 's/man_MANS//;s/=//;s/[ \\][    \\]*/ /g'`; do 
+               x=`dirname $f`/$i
+               y=`dirname $f`/`echo $i | sed 's/[0-9]$/cat&/'`
+               echo `grog -Tascii $x` \> $y
+               `grog -Tascii $x` > $y
+               perl -p -e 'exit 1 if (/NetBSD|FreeBSD|OpenBSD|Linux|OSF|Solaris/); exit 0;' $y
+               if [ $? != 0 ] ; then
+                   echo "$error: catfile $y contains operating system"
+                   head -1 $y
+                   $exitcmd
+               fi
+       done
+done
+
+make_proto () {
+       (top=`pwd`
+       cd $1
+       b=`basename $1`
+        if test X"$5" != X ; then
+           e="-E $5";
+       else
+           e=
+       fi
+       perl $top/cf/make-proto.pl $e -o $2 -p $3 `(perl -p -e 's/^(include|if|else|endif)\b/##$1/' Makefile.am; 
+               echo 'print-sources:; @if test "$(proto_opts)"; then echo $(proto_opts); else echo -q -P comment; fi; echo '$4 | sort -u ) | make -f - print-sources `)
+}
+
+make_proto lib/krb5 krb5-protos.h krb5-private.h '$(libkrb5_la_SOURCES)' KRB5_LIB_FUNCTION
+make_proto lib/kadm5 kadm5-protos.h kadm5-private.h '$(libkadm5srv_la_SOURCES) $(libkadm5clnt_la_SOURCES)'
+make_proto lib/hdb hdb-protos.h hdb-private.h '$(libhdb_la_SOURCES)'
+make_proto appl/login login_protos.h /dev/null '$(login_SOURCES)'
+make_proto kcm kcm_protos.h /dev/null '$(kcm_SOURCES)'
+make_proto kdc kdc-protos.h /dev/null '$(libkdc_la_SOURCES)'
+
+rm fix-export make-release make-release.el
+find . -name .cvsignore -print | xargs rm
+find . -name .__afs\* -print | xargs rm
+rm -fr autom4te*.cache
index 122c9ab7807f30e11eb1e0871511461e3355f5d2..e85a269a010673aeee13972a74dc7c6026c6a99c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -189,22 +189,26 @@ log_timestamp(krb5_context context,
              KerberosTime authtime, KerberosTime *starttime, 
              KerberosTime endtime, KerberosTime *renew_till)
 {
-    char atime[100], stime[100], etime[100], rtime[100];
+    char authtime_str[100], starttime_str[100], endtime_str[100], renewtime_str[100];
     
-    krb5_format_time(context, authtime, atime, sizeof(atime), TRUE); 
+    krb5_format_time(context, authtime, 
+                    authtime_str, sizeof(authtime_str), TRUE); 
     if (starttime)
-       krb5_format_time(context, *starttime, stime, sizeof(stime), TRUE); 
+       krb5_format_time(context, *starttime, 
+                        starttime_str, sizeof(starttime_str), TRUE); 
     else
-       strlcpy(stime, "unset", sizeof(stime));
-    krb5_format_time(context, endtime, etime, sizeof(etime), TRUE); 
+       strlcpy(starttime_str, "unset", sizeof(starttime_str));
+    krb5_format_time(context, endtime, 
+                    endtime_str, sizeof(endtime_str), TRUE); 
     if (renew_till)
-       krb5_format_time(context, *renew_till, rtime, sizeof(rtime), TRUE); 
+       krb5_format_time(context, *renew_till, 
+                        renewtime_str, sizeof(renewtime_str), TRUE); 
     else
-       strlcpy(rtime, "unset", sizeof(rtime));
+       strlcpy(renewtime_str, "unset", sizeof(renewtime_str));
     
     kdc_log(context, config, 5,
            "%s authtime: %s starttime: %s endtype: %s renew till: %s",
-           type, atime, stime, etime, rtime);
+           type, authtime_str, starttime_str, endtime_str, renewtime_str);
 }
 
 static krb5_error_code
@@ -578,7 +582,8 @@ get_pa_etype_info2(krb5_context context,
        ret = krb5_unparse_name(context, client->principal, &name);
        if (ret)
            name = "<unparse_name failed>";
-       kdc_log(context, config, 0, "internal error in get_pa_etype_info2(%s): %d != %d", 
+       kdc_log(context, config, 0,
+               "internal error in get_pa_etype_info2(%s): %d != %d", 
                name, n, pa.len);
        if (ret == 0)
            free(name);
@@ -623,24 +628,26 @@ _kdc_check_flags(krb5_context context,
        
        if(!client->flags.client){
            kdc_log(context, config, 0,
-                   "Principal may not act as client -- %s", 
-                   client_name);
+                   "Principal may not act as client -- %s", client_name);
            return KRB5KDC_ERR_POLICY;
        }
        
        if (client->valid_start && *client->valid_start > kdc_time) {
-           kdc_log(context, config, 0, "Client not yet valid -- %s", client_name);
+           kdc_log(context, config, 0,
+                   "Client not yet valid -- %s", client_name);
            return KRB5KDC_ERR_CLIENT_NOTYET;
        }
        
        if (client->valid_end && *client->valid_end < kdc_time) {
-           kdc_log(context, config, 0, "Client expired -- %s", client_name);
+           kdc_log(context, config, 0,
+                   "Client expired -- %s", client_name);
            return KRB5KDC_ERR_NAME_EXP;
        }
        
        if (client->pw_end && *client->pw_end < kdc_time
            && !server->flags.change_pw) {
-           kdc_log(context, config, 0, "Client's key has expired -- %s", client_name);
+           kdc_log(context, config, 0,
+                   "Client's key has expired -- %s", client_name);
            return KRB5KDC_ERR_KEY_EXPIRED;
        }
     }
@@ -649,33 +656,38 @@ _kdc_check_flags(krb5_context context,
     
     if (server != NULL) {
        if (server->flags.invalid) {
-           kdc_log(context, config, 0, "Server has invalid flag set -- %s", server_name);
+           kdc_log(context, config, 0,
+                   "Server has invalid flag set -- %s", server_name);
            return KRB5KDC_ERR_POLICY;
        }
 
        if(!server->flags.server){
-           kdc_log(context, config, 0, "Principal may not act as server -- %s", 
-                   server_name);
+           kdc_log(context, config, 0,
+                   "Principal may not act as server -- %s", server_name);
            return KRB5KDC_ERR_POLICY;
        }
 
        if(!is_as_req && server->flags.initial) {
-           kdc_log(context, config, 0, "AS-REQ is required for server -- %s", server_name);
+           kdc_log(context, config, 0,
+                   "AS-REQ is required for server -- %s", server_name);
            return KRB5KDC_ERR_POLICY;
        }
 
        if (server->valid_start && *server->valid_start > kdc_time) {
-           kdc_log(context, config, 0, "Server not yet valid -- %s", server_name);
+           kdc_log(context, config, 0,
+                   "Server not yet valid -- %s", server_name);
            return KRB5KDC_ERR_SERVICE_NOTYET;
        }
 
        if (server->valid_end && *server->valid_end < kdc_time) {
-           kdc_log(context, config, 0, "Server expired -- %s", server_name);
+           kdc_log(context, config, 0,
+                   "Server expired -- %s", server_name);
            return KRB5KDC_ERR_SERVICE_EXP;
        }
 
        if (server->pw_end && *server->pw_end < kdc_time) {
-           kdc_log(context, config, 0, "Server's key has expired -- %s", server_name);
+           kdc_log(context, config, 0,
+                   "Server's key has expired -- %s", server_name);
            return KRB5KDC_ERR_KEY_EXPIRED;
        }
     }
@@ -868,6 +880,7 @@ _kdc_as_rep(krb5_context context,
            size_t len;
            EncryptedData enc_data;
            Key *pa_key;
+           char *str;
            
            found_pa = 1;
            
@@ -919,14 +932,24 @@ _kdc_as_rep(krb5_context context,
                                              &ts_data);
            krb5_crypto_destroy(context, crypto);
            if(ret){
+               krb5_error_code ret2;
+               ret2 = krb5_enctype_to_string(context, 
+                                            pa_key->key.keytype, &str);
+               if (ret2)
+                   str = NULL;
+               kdc_log(context, config, 5, 
+                       "Failed to decrypt PA-DATA -- %s "
+                       "(enctype %s) error %s",
+                       client_name, str ? str : "unknown enctype", 
+                       krb5_get_err_text(context, ret));
+               free(str);
+
                if(hdb_next_enctype2key(context, client, 
                                        enc_data.etype, &pa_key) == 0)
                    goto try_next_key;
-               free_EncryptedData(&enc_data);
                e_text = "Failed to decrypt PA-DATA";
-               kdc_log(context, config, 
-                       5, "Failed to decrypt PA-DATA -- %s",
-                       client_name);
+
+               free_EncryptedData(&enc_data);
                ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
                continue;
            }
@@ -953,9 +976,15 @@ _kdc_as_rep(krb5_context context,
                goto out;
            }
            et.flags.pre_authent = 1;
+
+           ret = krb5_enctype_to_string(context,pa_key->key.keytype, &str);
+           if (ret)
+               str = NULL;
+
            kdc_log(context, config, 2,
-                   "ENC-TS Pre-authentication succeeded -- %s", 
-                   client_name);
+                   "ENC-TS Pre-authentication succeeded -- %s using %s", 
+                   client_name, str ? str : "unknown enctype");
+           free(str);
            break;
        }
 #ifdef PKINIT
@@ -1877,7 +1906,7 @@ tgs_check_authenticator(krb5_context context,
     free(buf);
     krb5_crypto_destroy(context, crypto);
     if(ret){
-       kdc_log(context, config, 0, "Failed to verify checksum: %s", 
+       kdc_log(context, config, 0, "Failed to verify authenticator checksum: %s", 
                krb5_get_err_text(context, ret));
     }
 out:
@@ -2073,7 +2102,11 @@ tgs_rep2(krb5_context context,
 
     ret = tgs_check_authenticator(context, config, 
                                  ac, b, &e_text, &tgt->key);
-
+    if(ret){
+       krb5_auth_con_free(context, ac);
+       goto out2;
+    }
+    
     if (b->enc_authorization_data) {
        krb5_keyblock *subkey;
        krb5_data ad;
@@ -2134,14 +2167,6 @@ tgs_rep2(krb5_context context,
        }
     }
 
-    krb5_auth_con_free(context, ac);
-
-    if(ret){
-       kdc_log(context, config, 0, "Failed to verify authenticator: %s", 
-               krb5_get_err_text(context, ret));
-       goto out2;
-    }
-    
     {
        PrincipalName *s;
        Realm r;
index d83e1d3b2ea2abf71c8e11ca3cb612c1a55acbc1..f591aa8fc12bac1b2cf7677502efdbb113202da6 100755 (executable)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: pkinit.c,v 1.36 2005/07/01 15:37:24 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.37 2005/07/26 18:37:02 lha Exp $");
 
 #ifdef PKINIT
 
@@ -927,8 +927,10 @@ pk_mk_pa_reply_enckey(krb5_context context,
     enc_alg->parameters->data = params.data;
     enc_alg->parameters->length = params.length;
 
-    if (client_params->type == PKINIT_COMPAT_WIN2K || client_params->type == PKINIT_COMPAT_19 || client_params->type == PKINIT_COMPAT_25) {
-       ReplyKeyPack kp;
+    switch (client_params->type) {
+    case PKINIT_COMPAT_WIN2K:
+    case PKINIT_COMPAT_19: {
+       ReplyKeyPack_19 kp;
        memset(&kp, 0, sizeof(kp));
 
        ret = copy_EncryptionKey(reply_key, &kp.replyKey);
@@ -938,9 +940,25 @@ pk_mk_pa_reply_enckey(krb5_context context,
        }
        kp.nonce = client_params->nonce;
        
+       ASN1_MALLOC_ENCODE(ReplyKeyPack_19, 
+                          buf.data, buf.length,
+                          &kp, &size,ret);
+       free_ReplyKeyPack_19(&kp);
+    }
+    case PKINIT_COMPAT_25: {
+       ReplyKeyPack kp;
+       memset(&kp, 0, sizeof(kp));
+
+       ret = copy_EncryptionKey(reply_key, &kp.replyKey);
+       if (ret) {
+           krb5_clear_error_string(context);
+           goto out;
+       }
+       /* XXX add whatever is the outcome of asChecksum discussion here */
        ASN1_MALLOC_ENCODE(ReplyKeyPack, buf.data, buf.length, &kp, &size,ret);
        free_ReplyKeyPack(&kp);
-    } else {
+    }
+    default:
        krb5_abortx(context, "internal pkinit error");
     }
     if (ret) {
diff --git a/source4/heimdal/lib/asn1/CMS.asn1 b/source4/heimdal/lib/asn1/CMS.asn1
new file mode 100644 (file)
index 0000000..5c8b71d
--- /dev/null
@@ -0,0 +1,151 @@
+-- From RFC 3369 --
+-- $Id: CMS.asn1,v 1.3 2005/07/23 10:37:13 lha Exp $ --
+
+CMS DEFINITIONS ::= BEGIN
+
+IMPORTS CertificateSerialNumber, AlgorithmIdentifier, Name,
+       Attribute, Certificate, Name, SubjectKeyIdentifier FROM rfc2459
+       heim_any, heim_any_set FROM heim;
+
+id-pkcs7 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+         us(840) rsadsi(113549) pkcs(1) pkcs7(7) }
+
+id-pkcs7-data OBJECT IDENTIFIER ::=                    { id-pkcs7 1 }
+id-pkcs7-signedData OBJECT IDENTIFIER ::=              { id-pkcs7 2 }
+id-pkcs7-envelopedData OBJECT IDENTIFIER ::=           { id-pkcs7 3 }
+id-pkcs7-signedAndEnvelopedData OBJECT IDENTIFIER ::=  { id-pkcs7 4 }
+id-pkcs7-digestedData OBJECT IDENTIFIER ::=            { id-pkcs7 5 }
+id-pkcs7-encryptedData OBJECT IDENTIFIER ::=           { id-pkcs7 6 }
+
+CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4) }
+
+DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
+SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
+
+ContentType ::= OBJECT IDENTIFIER
+MessageDigest ::= OCTET STRING
+
+ContentInfo ::= SEQUENCE {
+       contentType ContentType,
+       content [0] EXPLICIT heim_any OPTIONAL --  DEFINED BY contentType 
+}
+
+EncapsulatedContentInfo ::= SEQUENCE {
+       eContentType ContentType,
+       eContent [0] EXPLICIT OCTET STRING OPTIONAL
+}
+
+CertificateSet ::= SET OF heim_any
+
+CertificateList ::= Certificate
+
+CertificateRevocationLists ::= SET OF CertificateList
+
+IssuerAndSerialNumber ::= SEQUENCE {
+       issuer Name,
+       serialNumber CertificateSerialNumber
+}
+
+-- RecipientIdentifier is same as SignerIdentifier, 
+-- lets glue them togheter and save some bytes and share code for them
+
+CMSIdentifier ::= CHOICE {
+       issuerAndSerialNumber IssuerAndSerialNumber,
+       subjectKeyIdentifier [0] SubjectKeyIdentifier
+}
+
+SignerIdentifier ::= CMSIdentifier
+RecipientIdentifier ::= CMSIdentifier
+
+--- CMSAttributes are the combined UnsignedAttributes and SignedAttributes
+--- to store space and share code
+
+CMSAttributes ::= SET OF Attribute             -- SIZE (1..MAX) 
+
+SignatureValue ::= OCTET STRING
+
+SignerInfo ::= SEQUENCE {
+       version CMSVersion,
+       sid SignerIdentifier,
+       digestAlgorithm DigestAlgorithmIdentifier,
+       signedAttrs [0] IMPLICIT -- CMSAttributes --
+               SET OF Attribute OPTIONAL,
+       signatureAlgorithm SignatureAlgorithmIdentifier,
+       signature SignatureValue,
+       unsignedAttrs [1] IMPLICIT -- CMSAttributes -- 
+               SET OF Attribute OPTIONAL
+}
+
+SignerInfos ::= SET OF SignerInfo
+
+SignedData ::= SEQUENCE {
+       version CMSVersion,
+       digestAlgorithms DigestAlgorithmIdentifiers,
+       encapContentInfo EncapsulatedContentInfo,
+       certificates [0] IMPLICIT -- CertificateSet --
+               SET OF heim_any OPTIONAL,
+       crls [1] IMPLICIT -- CertificateRevocationLists --
+               heim_any OPTIONAL,
+       signerInfos SignerInfos
+}
+
+OriginatorInfo ::= SEQUENCE {
+       certs [0] IMPLICIT -- CertificateSet --
+               SET OF heim_any OPTIONAL,
+       crls [1] IMPLICIT --CertificateRevocationLists --
+               heim_any OPTIONAL
+}
+
+KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
+
+EncryptedKey ::= OCTET STRING
+
+KeyTransRecipientInfo ::= SEQUENCE {
+       version CMSVersion,  -- always set to 0 or 2
+       rid RecipientIdentifier,
+       keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
+       encryptedKey EncryptedKey
+}
+
+RecipientInfo ::= KeyTransRecipientInfo
+
+RecipientInfos ::= SET OF RecipientInfo
+
+EncryptedContent ::= OCTET STRING
+
+EncryptedContentInfo ::= SEQUENCE {
+       contentType ContentType,
+       contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+       encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL
+}
+
+UnprotectedAttributes ::= SET OF Attribute     -- SIZE (1..MAX)
+
+CMSEncryptedData ::= SEQUENCE {
+       version CMSVersion,
+       encryptedContentInfo EncryptedContentInfo,
+        unprotectedAttrs [1] IMPLICIT -- UnprotectedAttributes --
+               heim_any OPTIONAL
+}
+
+EnvelopedData ::= SEQUENCE {
+       version CMSVersion,
+       originatorInfo [0] IMPLICIT -- OriginatorInfo -- heim_any OPTIONAL,
+       recipientInfos RecipientInfos,
+       encryptedContentInfo EncryptedContentInfo,
+       unprotectedAttrs [1] IMPLICIT -- UnprotectedAttributes --
+               heim_any OPTIONAL
+}
+
+-- Data ::= OCTET STRING
+
+CMSRC2CBCParameter ::= SEQUENCE {
+       rc2ParameterVersion     INTEGER,
+       iv                      OCTET STRING -- exactly 8 octets
+}
+
+CMSCBCParameter ::= OCTET STRING
+
+END
index 4560b1b29c042b48d89cd0ac6e2bd0d30ef92e50..01411b384a288ddf2c3cf31c13df0b984f62290d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: asn1-common.h,v 1.4 2003/07/15 13:57:31 lha Exp $ */
+/* $Id: asn1-common.h,v 1.5 2005/07/12 06:27:14 lha Exp $ */
 
 #include <stddef.h>
 #include <time.h>
@@ -6,6 +6,12 @@
 #ifndef __asn1_common_definitions__
 #define __asn1_common_definitions__
 
+typedef struct heim_integer {
+    size_t length;
+    void *data;
+    int negative;
+} heim_integer;
+
 typedef struct heim_octet_string {
     size_t length;
     void *data;
@@ -13,10 +19,44 @@ typedef struct heim_octet_string {
 
 typedef char *heim_general_string;
 typedef char *heim_utf8_string;
+typedef char *heim_printable_string;
+typedef char *heim_ia5_string;
+
+typedef struct heim_bmp_string {
+    size_t length;
+    uint16_t *data;
+} heim_bmp_string;
+
+typedef struct heim_universal_string {
+    size_t length;
+    uint32_t *data;
+} heim_universal_string;
+
 
 typedef struct heim_oid {
     size_t length;
     unsigned *components;
 } heim_oid;
 
+typedef struct heim_bit_string {
+    size_t length;
+    void *data;
+} heim_bit_string;
+
+#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R)                  \
+  do {                                                         \
+    (BL) = length_##T((S));                                    \
+    (B) = malloc((BL));                                        \
+    if((B) == NULL) {                                          \
+      (R) = ENOMEM;                                            \
+    } else {                                                   \
+      (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \
+                       (S), (L));                              \
+      if((R) != 0) {                                           \
+        free((B));                                             \
+        (B) = NULL;                                            \
+      }                                                        \
+    }                                                          \
+  } while (0)
+
 #endif
diff --git a/source4/heimdal/lib/asn1/asn1_gen.c b/source4/heimdal/lib/asn1/asn1_gen.c
new file mode 100644 (file)
index 0000000..939fb11
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * 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 above 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. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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. 
+ */
+
+#include "der_locl.h"
+#include <com_err.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <getarg.h>
+#include <hex.h>
+#include <err.h>
+
+RCSID("$Id: asn1_gen.c,v 1.2 2005/07/12 06:27:14 lha Exp $");
+
+static int
+doit(const char *fn)
+{
+    char buf[2048];
+    char *fnout;
+    const char *bname;
+    unsigned long line = 0;
+    FILE *f, *fout;
+    size_t offset = 0;
+
+    f = fopen(fn, "r");
+    if (f == NULL)
+       err(1, "fopen");
+
+    bname = strrchr(fn, '/');
+    if (bname)
+       bname++;
+    else
+       bname = fn;
+
+    asprintf(&fnout, "%s.out", bname);
+    if (fnout == NULL)
+       errx(1, "malloc");
+
+    fout = fopen(fnout, "w");
+    if (fout == NULL)
+       err(1, "fopen: output file");
+
+    while (fgets(buf, sizeof(buf), f) != NULL) {
+       char *ptr, *class, *type, *tag, *length, *data, *foo;
+       int ret, l, c, ty, ta;
+       unsigned char p[6], *pdata;
+       size_t sz;
+
+       line++;
+
+       buf[strcspn(buf, "\r\n")] = '\0';
+       if (buf[0] == '#' || buf[0] == '\0')
+           continue;
+
+       ptr = buf;
+       while (isspace((unsigned char)*ptr))
+              ptr++;
+
+       class = strtok_r(ptr, " \t\n", &foo);
+       if (class == NULL) errx(1, "class missing one line %lu", line);
+       type = strtok_r(NULL, " \t\n", &foo);
+       if (type == NULL) errx(1, "type missing one line %lu", line);
+       tag = strtok_r(NULL, " \t\n", &foo);
+       if (tag == NULL) errx(1, "tag missing one line %lu", line);
+       length = strtok_r(NULL, " \t\n", &foo);
+       if (length == NULL) errx(1, "length missing one line %lu", line);
+       data = strtok_r(NULL, " \t\n", &foo);
+
+       c = der_get_class_num(class);
+       if (c == -1) errx(1, "no valid class on line %lu", line);
+       ty = der_get_type_num(type);
+       if (ty == -1) errx(1, "no valid type on line %lu", line);
+       ta = der_get_tag_num(tag);
+       if (ta == -1)
+           ta = atoi(tag);
+
+       l = atoi(length);
+
+       printf("line: %3lu offset: %3lu class: %d type: %d "
+              "tag: %3d length: %3d %s\n", 
+              line, (unsigned long)offset, c, ty, ta, l, 
+              data ? "<have data>" : "<no data>");
+
+       ret = der_put_length_and_tag(p + sizeof(p) - 1, sizeof(p),
+                                    l,
+                                    c,
+                                    ty,
+                                    ta,
+                                    &sz);
+       if (ret)
+           errx(1, "der_put_length_and_tag: %d", ret);
+       
+       if (fwrite(p + sizeof(p) - sz , sz, 1, fout) != 1)
+           err(1, "fwrite length/tag failed");
+       offset += sz;
+       
+       if (data) {
+           size_t datalen;
+           
+           datalen = strlen(data) / 2;
+           pdata = emalloc(sz);
+           
+           if (hex_decode(data, pdata, datalen) != datalen)
+               errx(1, "failed to decode data");
+           
+           if (fwrite(pdata, datalen, 1, fout) != 1)
+               err(1, "fwrite data failed");
+           offset += datalen;
+           
+           free(pdata);
+       }
+    }
+    printf("line: eof offset: %lu\n", (unsigned long)offset);
+    
+    fclose(fout);
+    fclose(f);
+    return 0;
+}
+
+
+static int version_flag;
+static int help_flag;
+struct getargs args[] = {
+    { "version", 0, arg_flag, &version_flag },
+    { "help", 0, arg_flag, &help_flag }
+};
+int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int code)
+{
+    arg_printusage(args, num_args, NULL, "parse-file");
+    exit(code);
+}
+
+int
+main(int argc, char **argv)
+{
+    int optind = 0;
+
+    setprogname (argv[0]);
+
+    if(getarg(args, num_args, argc, argv, &optind))
+       usage(1);
+    if(help_flag)
+       usage(0);
+    if(version_flag) {
+       print_version(NULL);
+       exit(0);
+    }
+    argv += optind;
+    argc -= optind;
+    if (argc != 1)
+       usage (1);
+
+    return doit (argv[0]);
+}
diff --git a/source4/heimdal/lib/asn1/asn1_queue.h b/source4/heimdal/lib/asn1/asn1_queue.h
new file mode 100644 (file)
index 0000000..2874b35
--- /dev/null
@@ -0,0 +1,167 @@
+/*     $NetBSD: queue.h,v 1.38 2004/04/18 14:12:05 lukem Exp $ */
+/*     $Id: asn1_queue.h,v 1.2 2005/07/12 06:27:15 lha Exp $ */
+
+/*
+ * Copyright (c) 1991, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * 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 above 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. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS 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.
+ *
+ *     @(#)queue.h     8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef        _ASN1_QUEUE_H_
+#define        _ASN1_QUEUE_H_
+
+/*
+ * Tail queue definitions.
+ */
+#define        ASN1_TAILQ_HEAD(name, type)                                     \
+struct name {                                                          \
+       struct type *tqh_first; /* first element */                     \
+       struct type **tqh_last; /* addr of last next element */         \
+}
+
+#define        ASN1_TAILQ_HEAD_INITIALIZER(head)                               \
+       { NULL, &(head).tqh_first }
+#define        ASN1_TAILQ_ENTRY(type)                                          \
+struct {                                                               \
+       struct type *tqe_next;  /* next element */                      \
+       struct type **tqe_prev; /* address of previous next element */  \
+}
+
+/*
+ * Tail queue functions.
+ */
+#if defined(_KERNEL) && defined(QUEUEDEBUG)
+#define        QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD(head, elm, field)             \
+       if ((head)->tqh_first &&                                        \
+           (head)->tqh_first->field.tqe_prev != &(head)->tqh_first)    \
+               panic("ASN1_TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
+#define        QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL(head, elm, field)             \
+       if (*(head)->tqh_last != NULL)                                  \
+               panic("ASN1_TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
+#define        QUEUEDEBUG_ASN1_TAILQ_OP(elm, field)                            \
+       if ((elm)->field.tqe_next &&                                    \
+           (elm)->field.tqe_next->field.tqe_prev !=                    \
+           &(elm)->field.tqe_next)                                     \
+               panic("ASN1_TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
+       if (*(elm)->field.tqe_prev != (elm))                            \
+               panic("ASN1_TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
+#define        QUEUEDEBUG_ASN1_TAILQ_PREREMOVE(head, elm, field)               \
+       if ((elm)->field.tqe_next == NULL &&                            \
+           (head)->tqh_last != &(elm)->field.tqe_next)                 \
+               panic("ASN1_TAILQ_PREREMOVE head %p elm %p %s:%d",      \
+                     (head), (elm), __FILE__, __LINE__);
+#define        QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE(elm, field)                    \
+       (elm)->field.tqe_next = (void *)1L;                             \
+       (elm)->field.tqe_prev = (void *)1L;
+#else
+#define        QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD(head, elm, field)
+#define        QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL(head, elm, field)
+#define        QUEUEDEBUG_ASN1_TAILQ_OP(elm, field)
+#define        QUEUEDEBUG_ASN1_TAILQ_PREREMOVE(head, elm, field)
+#define        QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE(elm, field)
+#endif
+
+#define        ASN1_TAILQ_INIT(head) do {                                      \
+       (head)->tqh_first = NULL;                                       \
+       (head)->tqh_last = &(head)->tqh_first;                          \
+} while (/*CONSTCOND*/0)
+
+#define        ASN1_TAILQ_INSERT_HEAD(head, elm, field) do {                   \
+       QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD((head), (elm), field)         \
+       if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
+               (head)->tqh_first->field.tqe_prev =                     \
+                   &(elm)->field.tqe_next;                             \
+       else                                                            \
+               (head)->tqh_last = &(elm)->field.tqe_next;              \
+       (head)->tqh_first = (elm);                                      \
+       (elm)->field.tqe_prev = &(head)->tqh_first;                     \
+} while (/*CONSTCOND*/0)
+
+#define        ASN1_TAILQ_INSERT_TAIL(head, elm, field) do {                   \
+       QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL((head), (elm), field)         \
+       (elm)->field.tqe_next = NULL;                                   \
+       (elm)->field.tqe_prev = (head)->tqh_last;                       \
+       *(head)->tqh_last = (elm);                                      \
+       (head)->tqh_last = &(elm)->field.tqe_next;                      \
+} while (/*CONSTCOND*/0)
+
+#define        ASN1_TAILQ_INSERT_AFTER(head, listelm, elm, field) do {         \
+       QUEUEDEBUG_ASN1_TAILQ_OP((listelm), field)                      \
+       if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
+               (elm)->field.tqe_next->field.tqe_prev =                 \
+                   &(elm)->field.tqe_next;                             \
+       else                                                            \
+               (head)->tqh_last = &(elm)->field.tqe_next;              \
+       (listelm)->field.tqe_next = (elm);                              \
+       (elm)->field.tqe_prev = &(listelm)->field.tqe_next;             \
+} while (/*CONSTCOND*/0)
+
+#define        ASN1_TAILQ_INSERT_BEFORE(listelm, elm, field) do {              \
+       QUEUEDEBUG_ASN1_TAILQ_OP((listelm), field)                      \
+       (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
+       (elm)->field.tqe_next = (listelm);                              \
+       *(listelm)->field.tqe_prev = (elm);                             \
+       (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
+} while (/*CONSTCOND*/0)
+
+#define        ASN1_TAILQ_REMOVE(head, elm, field) do {                        \
+       QUEUEDEBUG_ASN1_TAILQ_PREREMOVE((head), (elm), field)           \
+       QUEUEDEBUG_ASN1_TAILQ_OP((elm), field)                          \
+       if (((elm)->field.tqe_next) != NULL)                            \
+               (elm)->field.tqe_next->field.tqe_prev =                 \
+                   (elm)->field.tqe_prev;                              \
+       else                                                            \
+               (head)->tqh_last = (elm)->field.tqe_prev;               \
+       *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
+       QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE((elm), field);                 \
+} while (/*CONSTCOND*/0)
+
+#define        ASN1_TAILQ_FOREACH(var, head, field)                            \
+       for ((var) = ((head)->tqh_first);                               \
+               (var);                                                  \
+               (var) = ((var)->field.tqe_next))
+
+#define        ASN1_TAILQ_FOREACH_REVERSE(var, head, headname, field)          \
+       for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
+               (var);                                                  \
+               (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+
+/*
+ * Tail queue access methods.
+ */
+#define        ASN1_TAILQ_EMPTY(head)          ((head)->tqh_first == NULL)
+#define        ASN1_TAILQ_FIRST(head)          ((head)->tqh_first)
+#define        ASN1_TAILQ_NEXT(elm, field)             ((elm)->field.tqe_next)
+
+#define        ASN1_TAILQ_LAST(head, headname) \
+       (*(((struct headname *)((head)->tqh_last))->tqh_last))
+#define        ASN1_TAILQ_PREV(elm, headname, field) \
+       (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+
+#endif /* !_ASN1_QUEUE_H_ */
diff --git a/source4/heimdal/lib/asn1/canthandle.asn1 b/source4/heimdal/lib/asn1/canthandle.asn1
new file mode 100644 (file)
index 0000000..55ba4d1
--- /dev/null
@@ -0,0 +1,34 @@
+-- $Id: canthandle.asn1,v 1.4 2005/07/21 20:49:15 lha Exp $ --
+
+CANTHANDLE DEFINITIONS ::= BEGIN
+
+-- Code the tag [1] but not the [ CONTEXT CONS UT_Sequence ] for Kaka2
+-- Workaround: use inline the structure directly
+-- Code the tag [2] but it should be primitive since KAKA3 is
+-- Workaround: use the INTEGER type directly
+
+Kaka2  ::= SEQUENCE { 
+        kaka2-1 [0] INTEGER
+}
+
+Kaka3  ::= INTEGER
+
+Foo ::= SEQUENCE {
+        kaka1 [0] IMPLICIT INTEGER OPTIONAL,
+        kaka2 [1] IMPLICIT Kaka2 OPTIONAL,
+        kaka3 [2] IMPLICIT Kaka3 OPTIONAL
+}
+
+-- Don't code kaka if its 1
+-- Workaround is to use OPTIONAL and check for in the encoder stubs
+
+Bar ::= SEQUENCE {
+        kaka [0] INTEGER DEFAULT 1
+}
+
+--  Can't handle primitives in SET OF
+--  Workaround is to define a type that is only an integer and use that
+
+Baz ::= SET OF INTEGER
+
+END
diff --git a/source4/heimdal/lib/asn1/der.c b/source4/heimdal/lib/asn1/der.c
new file mode 100644 (file)
index 0000000..687b381
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * 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 above 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. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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. 
+ */
+
+#include "der_locl.h"
+#include <com_err.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <getarg.h>
+#include <err.h>
+
+RCSID("$Id: der.c,v 1.2 2005/07/12 06:27:19 lha Exp $");
+
+
+static const char *class_names[] = {
+    "UNIV",                    /* 0 */
+    "APPL",                    /* 1 */
+    "CONTEXT",                 /* 2 */
+    "PRIVATE"                  /* 3 */
+};
+
+static const char *type_names[] = {
+    "PRIM",                    /* 0 */
+    "CONS"                     /* 1 */
+};
+
+static const char *tag_names[] = {
+    "EndOfContent",            /* 0 */
+    "Boolean",                 /* 1 */
+    "Integer",                 /* 2 */
+    "BitString",               /* 3 */
+    "OctetString",             /* 4 */
+    "Null",                    /* 5 */
+    "ObjectID",                        /* 6 */
+    NULL,                      /* 7 */
+    NULL,                      /* 8 */
+    NULL,                      /* 9 */
+    "Enumerated",              /* 10 */
+    NULL,                      /* 11 */
+    NULL,                      /* 12 */
+    NULL,                      /* 13 */
+    NULL,                      /* 14 */
+    NULL,                      /* 15 */
+    "Sequence",                        /* 16 */
+    "Set",                     /* 17 */
+    NULL,                      /* 18 */
+    "PrintableString",         /* 19 */
+    NULL,                      /* 20 */
+    NULL,                      /* 21 */
+    "IA5String",               /* 22 */
+    "UTCTime",                 /* 23 */
+    "GeneralizedTime",         /* 24 */
+    NULL,                      /* 25 */
+    "VisibleString",           /* 26 */
+    "GeneralString",           /* 27 */
+    NULL,                      /* 28 */
+    NULL,                      /* 29 */
+    "BMPString"                        /* 30 */
+};
+
+static int
+get_type(const char *name, const char *list[], unsigned len)
+{
+    unsigned i;
+    for (i = 0; i < len; i++)
+       if (list[i] && strcasecmp(list[i], name) == 0)
+           return i;
+    return -1;
+}
+
+#define SIZEOF_ARRAY(a) (sizeof((a))/sizeof((a)[0]))
+
+const char *
+der_get_class_name(unsigned num)
+{
+    if (num >= SIZEOF_ARRAY(class_names))
+       return NULL;
+    return class_names[num];
+}
+
+int
+der_get_class_num(const char *name)
+{
+    return get_type(name, class_names, SIZEOF_ARRAY(class_names));
+}
+
+const char *
+der_get_type_name(unsigned num)
+{
+    if (num >= SIZEOF_ARRAY(type_names))
+       return NULL;
+    return type_names[num];
+}
+
+int
+der_get_type_num(const char *name)
+{
+    return get_type(name, type_names, SIZEOF_ARRAY(type_names));
+}
+
+const char *
+der_get_tag_name(unsigned num)
+{
+    if (num >= SIZEOF_ARRAY(tag_names))
+       return NULL;
+    return tag_names[num];
+}
+
+int
+der_get_tag_num(const char *name)
+{
+    return get_type(name, tag_names, SIZEOF_ARRAY(tag_names));
+}
index 6c80842ff807c70ec3bcd90668afcee0050ae6bd..a66a3908c64d29ce48bd2aea21939517b60dcee7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
  * SUCH DAMAGE. 
  */
 
-/* $Id: der.h,v 1.28 2005/05/29 14:23:00 lha Exp $ */
+/* $Id: der.h,v 1.29 2005/07/12 06:27:19 lha Exp $ */
 
 #ifndef __DER_H__
 #define __DER_H__
 
-#include <time.h>
-
 typedef enum {
     ASN1_C_UNIV = 0,
     ASN1_C_APPL = 1,
-    ASN1_C_CONTEXT = 2 ,
+    ASN1_C_CONTEXT = 2,
     ASN1_C_PRIVATE = 3
 } Der_class;
 
 typedef enum {PRIM = 0, CONS = 1} Der_type;
 
+#define MAKE_TAG(CLASS, TYPE, TAG)  (((CLASS) << 6) | ((TYPE) << 5) | (TAG))
+
 /* Universal tags */
 
 enum {
-     UT_Boolean                = 1,
-     UT_Integer                = 2,
-     UT_BitString      = 3,
-     UT_OctetString    = 4,
-     UT_Null           = 5,
-     UT_OID            = 6,
-     UT_Enumerated     = 10,
-     UT_UTF8String     = 12,
-     UT_Sequence       = 16,
-     UT_Set            = 17,
-     UT_PrintableString        = 19,
-     UT_IA5String      = 22,
-     UT_UTCTime                = 23,
-     UT_GeneralizedTime        = 24,
-     UT_VisibleString  = 26,
-     UT_GeneralString  = 27
+    UT_EndOfContent    = 0,
+    UT_Boolean         = 1,
+    UT_Integer         = 2,    
+    UT_BitString       = 3,
+    UT_OctetString     = 4,
+    UT_Null            = 5,
+    UT_OID             = 6,
+    UT_Enumerated      = 10,
+    UT_UTF8String      = 12,
+    UT_Sequence                = 16,
+    UT_Set             = 17,
+    UT_PrintableString = 19,
+    UT_IA5String       = 22,
+    UT_UTCTime         = 23,
+    UT_GeneralizedTime = 24,
+    UT_VisibleString   = 26,
+    UT_GeneralString   = 27,
+    /* unsupported types */
+    UT_ObjectDescriptor = 7,
+    UT_External                = 8,
+    UT_Real            = 9,
+    UT_EmbeddedPDV     = 11,
+    UT_RelativeOID     = 13,
+    UT_NumericString   = 18,
+    UT_TeletexString   = 20,
+    UT_VideotexString  = 21,
+    UT_GraphicString   = 25,
+    UT_UniversalString = 25,
+    UT_BMPString       = 30,
 };
 
 #define ASN1_INDEFINITE 0xdce0deed
 
-#ifndef HAVE_TIMEGM
-time_t timegm (struct tm *);
-#endif
-
-int time2generalizedtime (time_t t, heim_octet_string *s);
-
-int der_get_int (const unsigned char *p, size_t len, int *ret, size_t *size);
+typedef struct asn1_der_time_t {
+    time_t dt_sec;
+    unsigned long dt_nsec;
+} asn1_der_time_t;
+
+typedef struct asn1_ber_time_t {
+    time_t bt_sec;
+    unsigned bt_nsec;
+    int bt_zone;
+} asn1_ber_time_t;
+
+int der_get_unsigned (const unsigned char *p, size_t len,
+                     unsigned *ret, size_t *size);
+int der_get_integer (const unsigned char *p, size_t len,
+                    int *ret, size_t *size);
+int der_get_heim_integer (const unsigned char *p, size_t len,
+                         heim_integer *ret, size_t *size);
+int der_get_boolean(const unsigned char *p, size_t len,
+                   int *data, size_t *size);
 int der_get_length (const unsigned char *p, size_t len,
                    size_t *val, size_t *size);
-int der_get_boolean (const unsigned char *p, size_t len,
-                    int *data, size_t *size);
 int der_get_general_string (const unsigned char *p, size_t len, 
                            heim_general_string *str, size_t *size);
+int der_get_utf8string (const unsigned char *p, size_t len, 
+                           heim_utf8_string *str, size_t *size);
+int der_get_universal_string (const unsigned char *p, size_t len, 
+                            heim_universal_string *str, size_t *size);
+int der_get_bmp_string (const unsigned char *p, size_t len, 
+                       heim_bmp_string *str, size_t *size);
+int der_get_printable_string (const unsigned char *p, size_t len, 
+                           heim_printable_string *str, size_t *size);
+int der_get_ia5_string (const unsigned char *p, size_t len,
+                       heim_ia5_string *str, size_t *size);
 int der_get_octet_string (const unsigned char *p, size_t len, 
                          heim_octet_string *data, size_t *size);
+int der_get_generalized_time (const unsigned char *p, size_t len, 
+                             time_t *data, size_t *size);
+int der_get_generalized_time_der (const unsigned char *p, size_t len, 
+                                 asn1_der_time_t *data, size_t *size);
+int der_get_generalized_time_ber (const unsigned char *p, size_t len, 
+                                 asn1_ber_time_t *data, size_t *size);
+int der_get_utctime (const unsigned char *p, size_t len, 
+                    time_t *data, size_t *size);
 int der_get_oid (const unsigned char *p, size_t len,
                 heim_oid *data, size_t *size);
+int der_get_bit_string (const unsigned char *p, size_t len,
+                       heim_bit_string *data, size_t *size);
 int der_get_tag (const unsigned char *p, size_t len, 
                 Der_class *class, Der_type *type,
-                int *tag, size_t *size);
+                unsigned int *tag, size_t *size);
 
 int der_match_tag (const unsigned char *p, size_t len, 
                   Der_class class, Der_type type,
-                  int tag, size_t *size);
+                  unsigned int tag, size_t *size);
 int der_match_tag_and_length (const unsigned char *p, size_t len,
-                             Der_class class, Der_type type, int tag,
+                             Der_class class, Der_type type, unsigned int tag,
                              size_t *length_ret, size_t *size);
 
-int decode_boolean (const unsigned char*, size_t, int*, size_t*);
-int decode_integer (const unsigned char*, size_t, int*, size_t*);
-int decode_unsigned (const unsigned char*, size_t, unsigned*, size_t*);
-int decode_enumerated (const unsigned char*, size_t, unsigned*, size_t*);
-int decode_general_string (const unsigned char*, size_t,
-                          heim_general_string*, size_t*);
-int decode_oid (const unsigned char *p, size_t len, 
-               heim_oid *k, size_t *size);
-int decode_octet_string (const unsigned char*, size_t, 
-                        heim_octet_string*, size_t*);
-int decode_generalized_time (const unsigned char*, size_t, time_t*, size_t*);
-int decode_nulltype (const unsigned char*, size_t, size_t*);
-int decode_utf8string (const unsigned char*, size_t, 
-                      heim_utf8_string*, size_t*);
-
-int der_put_int (unsigned char *p, size_t len, int val, size_t*);
+int der_put_unsigned (unsigned char *p, size_t len, const unsigned *val, size_t*);
+int der_put_integer (unsigned char *p, size_t len, const int *val, size_t*);
+int der_put_heim_integer (unsigned char *p, size_t len, 
+                         const heim_integer *val, size_t*);
+int der_put_boolean (unsigned char *p, size_t len, const int *val, size_t*);
+
 int der_put_length (unsigned char *p, size_t len, size_t val, size_t*);
-int der_put_boolean (unsigned char *p, size_t len, const int *data, size_t*);
 int der_put_general_string (unsigned char *p, size_t len,
                            const heim_general_string *str, size_t*);
+int der_put_utf8string (unsigned char *p, size_t len,
+                       const heim_utf8_string *str, size_t*);
+int der_put_universal_string (unsigned char *p, size_t len,
+                             const heim_universal_string *str, size_t*);
+int der_put_bmp_string (unsigned char *p, size_t len,
+                           const heim_bmp_string *str, size_t*);
+int der_put_printable_string (unsigned char *p, size_t len,
+                           const heim_printable_string *str, size_t*);
+int der_put_ia5_string (unsigned char *p, size_t len,
+                       const heim_ia5_string *str, size_t*);
 int der_put_octet_string (unsigned char *p, size_t len,
                          const heim_octet_string *data, size_t*);
+int der_put_generalized_time (unsigned char *p, size_t len, 
+                             const time_t *data, size_t *size);
+int der_put_utctime (unsigned char *p, size_t len, 
+                    const time_t *data, size_t *size);
 int der_put_oid (unsigned char *p, size_t len,
                 const heim_oid *data, size_t *size);
+int der_put_bit_string (unsigned char *p, size_t len,
+                       const heim_bit_string *data, size_t *size);
 int der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
-                int tag, size_t*);
+                unsigned int tag, size_t*);
 int der_put_length_and_tag (unsigned char*, size_t, size_t, 
-                           Der_class, Der_type, int, size_t*);
-
-int encode_boolean (unsigned char *p, size_t len,
-                   const int *data, size_t*);
-int encode_integer (unsigned char *p, size_t len,
-                   const int *data, size_t*);
-int encode_unsigned (unsigned char *p, size_t len,
-                    const unsigned *data, size_t*);
-int encode_enumerated (unsigned char *p, size_t len,
-                      const unsigned *data, size_t*);
-int encode_general_string (unsigned char *p, size_t len, 
-                          const heim_general_string *data, size_t*);
-int encode_octet_string (unsigned char *p, size_t len,
-                        const heim_octet_string *k, size_t*);
-int encode_oid (unsigned char *p, size_t len,
-               const heim_oid *k, size_t*);
-int encode_generalized_time (unsigned char *p, size_t len,
-                            const time_t *t, size_t*);
-int encode_nulltype (unsigned char*, size_t, size_t*);
-int encode_utf8string (unsigned char*, size_t, 
-                      const heim_utf8_string*, size_t*);
+                           Der_class, Der_type, unsigned int, size_t*);
 
 void free_integer (int *num);
+void free_heim_integer (heim_integer *num);
+void free_octet_string (heim_octet_string *k);
 void free_general_string (heim_general_string *str);
 void free_octet_string (heim_octet_string *k);
 void free_oid (heim_oid *k);
+void free_bit_string (heim_bit_string *k);
 void free_generalized_time (time_t *t);
+void free_utctime (time_t *t);
 void free_utf8string (heim_utf8_string*);
+void free_printable_string (heim_printable_string*);
+void free_ia5_string (heim_ia5_string*);
+void free_universal_string (heim_universal_string*);
+void free_bmp_string (heim_bmp_string*);
 
 size_t length_len (size_t len);
-size_t length_boolean (const int *data);
 size_t length_integer (const int *data);
+size_t length_heim_integer (const heim_integer *data);
 size_t length_unsigned (const unsigned *data);
 size_t length_enumerated (const unsigned *data);
 size_t length_general_string (const heim_general_string *data);
 size_t length_octet_string (const heim_octet_string *k);
 size_t length_oid (const heim_oid *k);
+size_t length_bit_string (const heim_bit_string *k);
 size_t length_generalized_time (const time_t *t);
-size_t length_nulltype (void);
+size_t length_utctime (const time_t *t);
 size_t length_utf8string (const heim_utf8_string*);
+size_t length_printable_string (const heim_printable_string*);
+size_t length_ia5_string (const heim_ia5_string*);
+size_t length_bmp_string (const heim_bmp_string*);
+size_t length_universal_string (const heim_universal_string*);
+size_t length_boolean (const int*);
 
+int copy_heim_integer (const heim_integer *, heim_integer *);
 int copy_general_string (const heim_general_string *, heim_general_string *);
 int copy_octet_string (const heim_octet_string *, heim_octet_string *);
 int copy_oid (const heim_oid *from, heim_oid *to);
-int copy_nulltype (void *, void *);
+int copy_bit_string (const heim_bit_string *from, heim_bit_string *to);
 int copy_utf8string (const heim_utf8_string*, heim_utf8_string*);
+int copy_printable_string (const heim_printable_string*,heim_printable_string*);
+int copy_ia5_string (const heim_ia5_string*,heim_ia5_string*);
+int copy_universal_string(const heim_universal_string*,heim_universal_string*);
+int copy_bmp_string (const heim_bmp_string*,heim_bmp_string*);
 
 int heim_oid_cmp(const heim_oid *, const heim_oid *);
 int heim_octet_string_cmp(const heim_octet_string *,const heim_octet_string *);
-
-int fix_dce(size_t reallen, size_t *len);
+int heim_bit_string_cmp(const heim_bit_string *, const heim_bit_string *);
+int heim_integer_cmp(const heim_integer *, const heim_integer *);
+int heim_bmp_string_cmp(const heim_bmp_string *, const heim_bmp_string *);
+int heim_universal_string_cmp(const heim_universal_string *, 
+                             const heim_universal_string *);
+
+int der_parse_oid(const char *, heim_oid *);
+
+int _heim_fix_dce(size_t reallen, size_t *len);
+int _heim_der_set_sort(const void *, const void *);
+int _heim_time2generalizedtime (time_t, heim_octet_string *, int);
+
+const char *   der_get_class_name(unsigned);
+int            der_get_class_num(const char *);
+const char *   der_get_type_name(unsigned);
+int            der_get_type_num(const char *);
+const char *   der_get_tag_name(unsigned);
+int            der_get_tag_num(const char *);
 
 #endif /* __DER_H__ */
index a5ed7ff2b32960c8b9c63298754cb5f9853abfe3..306fcbdf5790bb1dc39040ff2e6ce0693e237f54 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 2003-2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,8 +33,6 @@
 
 #include "der_locl.h"
 
-RCSID("$Id: der_cmp.c,v 1.2 2004/04/26 20:54:02 lha Exp $");
-
 int
 heim_oid_cmp(const heim_oid *p, const heim_oid *q)
 {
@@ -52,3 +50,50 @@ heim_octet_string_cmp(const heim_octet_string *p, const heim_octet_string *q)
        return p->length - q->length;
     return memcmp(p->data, q->data, p->length);
 }
+
+int
+heim_bit_string_cmp(const heim_bit_string *p, const heim_bit_string *q)
+{
+    int i, r1, r2;
+    if (p->length != q->length)
+       return p->length - q->length;
+    i = memcmp(p->data, q->data, p->length / 8);
+    if (i)
+       return i;
+    if ((p->length % 8) == 0)
+       return 0;
+    i = (p->length / 8);
+    r1 = ((unsigned char *)p->data)[i];
+    r2 = ((unsigned char *)q->data)[i];
+    i = 8 - (p->length % 8);
+    r1 = r1 >> i;
+    r2 = r2 >> i;
+    return r1 - r2;
+}
+
+int
+heim_integer_cmp(const heim_integer *p, const heim_integer *q)
+{
+    if (p->length != q->length)
+       return p->length - q->length;
+    if (p->negative != q->negative)
+       return p->negative - q->negative;
+    return memcmp(p->data, q->data, p->length);
+}
+
+int
+heim_bmp_string_cmp(const heim_bmp_string *p, const heim_bmp_string *q)
+{
+    if (p->length != q->length)
+       return p->length - q->length;
+    return memcmp(p->data, q->data, q->length * sizeof(q->data[0]));
+}
+
+int
+heim_universal_string_cmp(const heim_universal_string *p, 
+                         const heim_universal_string *q)
+{
+    if (p->length != q->length)
+       return p->length - q->length;
+    return memcmp(p->data, q->data, q->length * sizeof(q->data[0]));
+}
index 936691120aa9199139a8c77e0e57d9914c9bfd1e..a3c9026cbf5e656e394569fffdebe897d8d1f791 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "der_locl.h"
 
-RCSID("$Id: der_copy.c,v 1.12 2003/11/07 07:39:43 lha Exp $");
+RCSID("$Id: der_copy.c,v 1.13 2005/07/12 06:27:20 lha Exp $");
 
 int
 copy_general_string (const heim_general_string *from, heim_general_string *to)
@@ -44,6 +44,49 @@ copy_general_string (const heim_general_string *from, heim_general_string *to)
     return 0;
 }
 
+int
+copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to)
+{
+    return copy_general_string(from, to);
+}
+
+int
+copy_printable_string (const heim_printable_string *from, 
+                      heim_printable_string *to)
+{
+    return copy_general_string(from, to);
+}
+
+int
+copy_ia5_string (const heim_printable_string *from, 
+                      heim_printable_string *to)
+{
+    return copy_general_string(from, to);
+}
+
+int
+copy_bmp_string (const heim_bmp_string *from, heim_bmp_string *to)
+{
+    to->length = from->length;
+    to->data   = malloc(to->length * sizeof(to->data[0]));
+    if(to->length != 0 && to->data == NULL)
+       return ENOMEM;
+    memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
+    return 0;
+}
+
+int
+copy_universal_string (const heim_universal_string *from,
+                      heim_universal_string *to)
+{
+    to->length = from->length;
+    to->data   = malloc(to->length * sizeof(to->data[0]));
+    if(to->length != 0 && to->data == NULL)
+       return ENOMEM;
+    memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
+    return 0;
+}
+
 int
 copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
 {
@@ -55,6 +98,17 @@ copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
     return 0;
 }
 
+int
+copy_heim_integer (const heim_integer *from, heim_integer *to)
+{
+    to->length = from->length;
+    to->data   = malloc(to->length);
+    if(to->length != 0 && to->data == NULL)
+       return ENOMEM;
+    memcpy(to->data, from->data, to->length);
+    return 0;
+}
+
 int
 copy_oid (const heim_oid *from, heim_oid *to)
 {
@@ -66,3 +120,17 @@ copy_oid (const heim_oid *from, heim_oid *to)
           to->length * sizeof(*to->components));
     return 0;
 }
+
+int
+copy_bit_string (const heim_bit_string *from, heim_bit_string *to)
+{
+    size_t len;
+
+    len = (from->length + 7) / 8;
+    to->length = from->length;
+    to->data   = malloc(len);
+    if(len != 0 && to->data == NULL)
+       return ENOMEM;
+    memcpy(to->data, from->data, len);
+    return 0;
+}
index bec41b1ee106932316524eb170cf6f9494381361..8959c3b1c3b9521bdb799af3cfe45b118b6122a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "der_locl.h"
 
-RCSID("$Id: der_free.c,v 1.10 2003/08/20 16:18:49 joda Exp $");
+RCSID("$Id: der_free.c,v 1.11 2005/07/12 06:27:21 lha Exp $");
 
 void
 free_general_string (heim_general_string *str)
@@ -42,11 +42,56 @@ free_general_string (heim_general_string *str)
     *str = NULL;
 }
 
+void
+free_utf8string (heim_utf8_string *str)
+{
+    free(*str);
+    *str = NULL;
+}
+
+void
+free_printable_string (heim_printable_string *str)
+{
+    free(*str);
+    *str = NULL;
+}
+
+void
+free_ia5_string (heim_ia5_string *str)
+{
+    free_general_string(str);
+}
+
+void
+free_bmp_string (heim_bmp_string *k)
+{
+    free(k->data);
+    k->data = NULL;
+    k->length = 0;
+}
+
+void
+free_universal_string (heim_universal_string *k)
+{
+    free(k->data);
+    k->data = NULL;
+    k->length = 0;
+}
+
 void
 free_octet_string (heim_octet_string *k)
 {
     free(k->data);
     k->data = NULL;
+    k->length = 0;
+}
+
+void
+free_heim_integer (heim_integer *k)
+{
+    free(k->data);
+    k->data = NULL;
+    k->length = 0;
 }
 
 void
@@ -54,4 +99,13 @@ free_oid (heim_oid *k)
 {
     free(k->components);
     k->components = NULL;
+    k->length = 0;
+}
+
+void
+free_bit_string (heim_bit_string *k)
+{
+    free(k->data);
+    k->data = NULL;
+    k->length = 0;
 }
index d33d3ca9ef50cb24b43ad38f378f794fe3f27550..403f5ab1ba3d18622d29dcf25cc1cc6ac9897694 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "der_locl.h"
 
-RCSID("$Id: der_get.c,v 1.39 2005/05/29 14:23:00 lha Exp $");
+RCSID("$Id: der_get.c,v 1.44 2005/07/19 18:04:00 lha Exp $");
 
 #include <version.h>
 
@@ -45,13 +45,18 @@ RCSID("$Id: der_get.c,v 1.39 2005/05/29 14:23:00 lha Exp $");
  * Either 0 or an error code is returned.
  */
 
-static int
+int
 der_get_unsigned (const unsigned char *p, size_t len,
                  unsigned *ret, size_t *size)
 {
     unsigned val = 0;
     size_t oldlen = len;
 
+    if (len == sizeof(unsigned) + 1 && p[0] == 0)
+       ;
+    else if (len > sizeof(unsigned))
+       return ASN1_OVERRUN;
+
     while (len--)
        val = val * 256 + *p++;
     *ret = val;
@@ -60,12 +65,15 @@ der_get_unsigned (const unsigned char *p, size_t len,
 }
 
 int
-der_get_int (const unsigned char *p, size_t len,
-            int *ret, size_t *size)
+der_get_integer (const unsigned char *p, size_t len,
+                int *ret, size_t *size)
 {
     int val = 0;
     size_t oldlen = len;
 
+    if (len > sizeof(int))
+       return ASN1_OVERRUN;
+
     if (len > 0) {
        val = (signed char)*p++;
        while (--len)
@@ -76,19 +84,6 @@ der_get_int (const unsigned char *p, size_t len,
     return 0;
 }
 
-int
-der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
-{
-    if(len < 1)
-       return ASN1_OVERRUN;
-    if(*p != 0)
-       *data = 1;
-    else
-       *data = 0;
-    *size = 1;
-    return 0;
-}
-
 int
 der_get_length (const unsigned char *p, size_t len,
                size_t *val, size_t *size)
@@ -123,12 +118,28 @@ der_get_length (const unsigned char *p, size_t len,
     return 0;
 }
 
+int
+der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
+{
+    if(len < 1)
+       return ASN1_OVERRUN;
+    if(*p != 0)
+       *data = 1;
+    else
+       *data = 0;
+    *size = 1;
+    return 0;
+}
+
 int
 der_get_general_string (const unsigned char *p, size_t len, 
                        heim_general_string *str, size_t *size)
 {
     char *s;
 
+    if (len > len + 1)
+       return ASN1_BAD_LENGTH;
+
     s = malloc (len + 1);
     if (s == NULL)
        return ENOMEM;
@@ -139,6 +150,70 @@ der_get_general_string (const unsigned char *p, size_t len,
     return 0;
 }
 
+int
+der_get_utf8string (const unsigned char *p, size_t len, 
+                   heim_utf8_string *str, size_t *size)
+{
+    return der_get_general_string(p, len, str, size);
+}
+
+int
+der_get_printable_string (const unsigned char *p, size_t len, 
+                         heim_printable_string *str, size_t *size)
+{
+    return der_get_general_string(p, len, str, size);
+}
+
+int
+der_get_ia5_string (const unsigned char *p, size_t len, 
+                   heim_ia5_string *str, size_t *size)
+{
+    return der_get_general_string(p, len, str, size);
+}
+
+int
+der_get_bmp_string (const unsigned char *p, size_t len, 
+                   heim_bmp_string *data, size_t *size)
+{
+    size_t i;
+
+    if (len & 1)
+       return ASN1_BAD_FORMAT;
+    data->length = len / 2;
+    data->data = malloc(data->length * sizeof(data->data[0]));
+    if (data->data == NULL && data->length != 0)
+       return ENOMEM;
+
+    for (i = 0; i < data->length; i++) {
+       data->data[i] = (p[0] << 8) | p[1];
+       p += 2;
+    }
+    if (size) *size = len;
+
+    return 0;
+}
+
+int
+der_get_universal_string (const unsigned char *p, size_t len, 
+                         heim_universal_string *data, size_t *size)
+{
+    size_t i;
+
+    if (len & 3)
+       return ASN1_BAD_FORMAT;
+    data->length = len / 4;
+    data->data = malloc(data->length * sizeof(data->data[0]));
+    if (data->data == NULL && data->length != 0)
+       return ENOMEM;
+
+    for (i = 0; i < data->length; i++) {
+       data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+       p += 4;
+    }
+    if (size) *size = len;
+    return 0;
+}
+
 int
 der_get_octet_string (const unsigned char *p, size_t len, 
                      heim_octet_string *data, size_t *size)
@@ -152,6 +227,108 @@ der_get_octet_string (const unsigned char *p, size_t len,
     return 0;
 }
 
+int
+der_get_heim_integer (const unsigned char *p, size_t len, 
+                     heim_integer *data, size_t *size)
+{
+    data->length = 0;
+    data->negative = 0;
+    data->data = NULL;
+
+    if (len == 0) {
+       if (size)
+           *size = 0;
+       return 0;
+    }
+    if (p[0] & 0x80) {
+       data->negative = 1;
+
+       return ASN1_OVERRUN;
+    } else {
+       data->negative = 0;
+       data->length = len;
+
+       if (p[0] == 0 && data->length != 1) {
+           p++;
+           data->length--;
+       }
+       data->data = malloc(data->length);
+       if (data->data == NULL) {
+           data->length = 0;
+           return ENOMEM;
+       }
+       memcpy(data->data, p, data->length);
+    }
+    if (size)
+       *size = len;
+    return 0;
+}
+
+static int
+generalizedtime2time (const char *s, time_t *t)
+{
+    struct tm tm;
+
+    memset(&tm, 0, sizeof(tm));
+    if (sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
+               &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
+               &tm.tm_min, &tm.tm_sec) != 6) {
+       if (sscanf (s, "%02d%02d%02d%02d%02d%02dZ",
+                   &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
+                   &tm.tm_min, &tm.tm_sec) != 6)
+           return ASN1_BAD_TIMEFORMAT;
+       if (tm.tm_year < 50)
+           tm.tm_year += 2000;
+       else
+           tm.tm_year += 1900;
+    }
+    tm.tm_year -= 1900;
+    tm.tm_mon -= 1;
+    *t = timegm (&tm);
+    return 0;
+}
+
+static int
+der_get_time (const unsigned char *p, size_t len, 
+             time_t *data, size_t *size)
+{
+    heim_octet_string k;
+    char *times;
+    size_t ret = 0;
+    size_t l;
+    int e;
+
+    e = der_get_octet_string (p, len, &k, &l);
+    if (e) return e;
+    p += l;
+    len -= l;
+    ret += l;
+    times = realloc(k.data, k.length + 1);
+    if (times == NULL){
+       free(k.data);
+       return ENOMEM;
+    }
+    times[k.length] = 0;
+    e = generalizedtime2time(times, data);
+    free (times);
+    if(size) *size = ret;
+    return e;
+}
+
+int
+der_get_generalized_time (const unsigned char *p, size_t len, 
+                         time_t *data, size_t *size)
+{
+    return der_get_time(p, len, data, size);
+}
+
+int
+der_get_utctime (const unsigned char *p, size_t len, 
+                         time_t *data, size_t *size)
+{
+    return der_get_time(p, len, data, size);
+}
+
 int
 der_get_oid (const unsigned char *p, size_t len,
             heim_oid *data, size_t *size)
@@ -162,6 +339,9 @@ der_get_oid (const unsigned char *p, size_t len,
     if (len < 1)
        return ASN1_OVERRUN;
 
+    if (len > len + 1)
+       return ASN1_BAD_LENGTH;
+
     data->components = malloc((len + 1) * sizeof(*data->components));
     if (data->components == NULL)
        return ENOMEM;
@@ -170,15 +350,21 @@ der_get_oid (const unsigned char *p, size_t len,
     --len;
     ++p;
     for (n = 2; len > 0; ++n) {
-       unsigned u = 0;
-
+       unsigned u = 0, u1;
+       
        do {
            --len;
-           u = u * 128 + (*p++ % 128);
+           u1 = u * 128 + (*p++ % 128);
+           /* check that we don't overflow the element */
+           if (u1 < u) {
+               free_oid(data);
+               return ASN1_OVERRUN;
+           }
+           u = u1;
        } while (len > 0 && p[-1] & 0x80);
        data->components[n] = u;
     }
-    if (len > 0 && p[-1] & 0x80) {
+    if (n > 2 && p[-1] & 0x80) {
        free_oid (data);
        return ASN1_OVERRUN;
     }
@@ -191,26 +377,44 @@ der_get_oid (const unsigned char *p, size_t len,
 int
 der_get_tag (const unsigned char *p, size_t len,
             Der_class *class, Der_type *type,
-            int *tag, size_t *size)
+            unsigned int *tag, size_t *size)
 {
+    size_t ret = 0;
     if (len < 1)
        return ASN1_OVERRUN;
     *class = (Der_class)(((*p) >> 6) & 0x03);
     *type = (Der_type)(((*p) >> 5) & 0x01);
-    *tag = (*p) & 0x1F;
-    if(size) *size = 1;
+    *tag = (*p) & 0x1f;
+    p++; len--; ret++;
+    if(*tag == 0x1f) {
+       unsigned int continuation;
+       unsigned int tag1;
+       *tag = 0;
+       do {
+           if(len < 1)
+               return ASN1_OVERRUN;
+           continuation = *p & 128;
+           tag1 = *tag * 128 + (*p % 128);
+           /* check that we don't overflow the tag */
+           if (tag1 < *tag)
+               return ASN1_OVERFLOW;
+           *tag = tag1;
+           p++; len--; ret++;
+       } while(continuation);
+    }
+    if(size) *size = ret;
     return 0;
 }
 
 int
 der_match_tag (const unsigned char *p, size_t len,
               Der_class class, Der_type type,
-              int tag, size_t *size)
+              unsigned int tag, size_t *size)
 {
     size_t l;
     Der_class thisclass;
     Der_type thistype;
-    int thistag;
+    unsigned int thistag;
     int e;
 
     e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
@@ -227,7 +431,7 @@ der_match_tag (const unsigned char *p, size_t len,
 
 int
 der_match_tag_and_length (const unsigned char *p, size_t len,
-                         Der_class class, Der_type type, int tag,
+                         Der_class class, Der_type type, unsigned int tag,
                          size_t *length_ret, size_t *size)
 {
     size_t l, ret = 0;
@@ -238,7 +442,6 @@ der_match_tag_and_length (const unsigned char *p, size_t len,
     p += l;
     len -= l;
     ret += l;
-
     e = der_get_length (p, len, length_ret, &l);
     if (e) return e;
     p += l;
@@ -248,286 +451,50 @@ der_match_tag_and_length (const unsigned char *p, size_t len,
     return 0;
 }
 
-int
-decode_boolean (const unsigned char *p, size_t len,
-               int *num, size_t *size)
-{
-    size_t ret = 0;
-    size_t l, reallen;
-    int e;
-
-    e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Boolean, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-
-    e = der_get_length (p, len, &reallen, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (reallen > len)
-       return ASN1_OVERRUN;
-
-    e = der_get_boolean (p, reallen, num, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if(size) *size = ret;
-    return 0;
-}
-
-int
-decode_integer (const unsigned char *p, size_t len,
-               int *num, size_t *size)
-{
-    size_t ret = 0;
-    size_t l, reallen;
-    int e;
-
-    e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Integer, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-
-    e = der_get_length (p, len, &reallen, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (reallen > len)
-       return ASN1_OVERRUN;
-
-    e = der_get_int (p, reallen, num, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if(size) *size = ret;
-    return 0;
-}
-
-int
-decode_unsigned (const unsigned char *p, size_t len,
-                unsigned *num, size_t *size)
-{
-    size_t ret = 0;
-    size_t l, reallen;
-    int e;
-
-    e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Integer, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-
-    e = der_get_length (p, len, &reallen, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (reallen > len)
-       return ASN1_OVERRUN;
-
-    e = der_get_unsigned (p, reallen, num, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if(size) *size = ret;
-    return 0;
-}
-
-int
-decode_enumerated (const unsigned char *p, size_t len,
-                  unsigned *num, size_t *size)
-{
-    size_t ret = 0;
-    size_t l, reallen;
-    int e;
-
-    e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_Enumerated, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-
-    e = der_get_length (p, len, &reallen, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (reallen > len)
-       return ASN1_OVERRUN;
-
-    e = der_get_int (p, reallen, num, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if(size) *size = ret;
-    return 0;
-}
-
-int
-decode_general_string (const unsigned char *p, size_t len, 
-                      heim_general_string *str, size_t *size)
-{
-    size_t ret = 0;
-    size_t l, reallen;
-    int e;
-
-    e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_GeneralString, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-
-    e = der_get_length (p, len, &reallen, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (len < reallen)
-       return ASN1_OVERRUN;
-
-    e = der_get_general_string (p, reallen, str, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if(size) *size = ret;
-    return 0;
-}
+/* 
+ * Old versions of DCE was based on a very early beta of the MIT code,
+ * which used MAVROS for ASN.1 encoding. MAVROS had the interesting
+ * feature that it encoded data in the forward direction, which has
+ * it's problems, since you have no idea how long the data will be
+ * until after you're done. MAVROS solved this by reserving one byte
+ * for length, and later, if the actual length was longer, it reverted
+ * to indefinite, BER style, lengths. The version of MAVROS used by
+ * the DCE people could apparently generate correct X.509 DER encodings, and
+ * did this by making space for the length after encoding, but
+ * unfortunately this feature wasn't used with Kerberos. 
+ */
 
 int
-decode_octet_string (const unsigned char *p, size_t len, 
-                    heim_octet_string *k, size_t *size)
+_heim_fix_dce(size_t reallen, size_t *len)
 {
-    size_t ret = 0;
-    size_t l, reallen;
-    int e;
-
-    e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-
-    e = der_get_length (p, len, &reallen, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (len < reallen)
-       return ASN1_OVERRUN;
-
-    e = der_get_octet_string (p, reallen, k, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if(size) *size = ret;
+    if(reallen == ASN1_INDEFINITE)
+       return 1;
+    if(*len < reallen)
+       return -1;
+    *len = reallen;
     return 0;
 }
 
 int
-decode_oid (const unsigned char *p, size_t len, 
-           heim_oid *k, size_t *size)
+der_get_bit_string (const unsigned char *p, size_t len, 
+                   heim_bit_string *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l, reallen;
-    int e;
-
-    e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_OID, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-
-    e = der_get_length (p, len, &reallen, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (len < reallen)
+    if (len < 1)
        return ASN1_OVERRUN;
-
-    e = der_get_oid (p, reallen, k, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if(size) *size = ret;
-    return 0;
-}
-
-static void
-generalizedtime2time (const char *s, time_t *t)
-{
-    struct tm tm;
-
-    memset(&tm, 0, sizeof(tm));
-    sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
-           &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
-           &tm.tm_min, &tm.tm_sec);
-    tm.tm_year -= 1900;
-    tm.tm_mon -= 1;
-    *t = timegm (&tm);
-}
-
-int
-decode_generalized_time (const unsigned char *p, size_t len,
-                        time_t *t, size_t *size)
-{
-    heim_octet_string k;
-    char *times;
-    size_t ret = 0;
-    size_t l, reallen;
-    int e;
-
-    e = der_match_tag (p, len, ASN1_C_UNIV, PRIM, UT_GeneralizedTime, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-
-    e = der_get_length (p, len, &reallen, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    if (len < reallen)
+    if (p[0] > 7)
+       return ASN1_BAD_FORMAT;
+    if (len - 1 == 0 && p[0] != 0)
+       return ASN1_BAD_FORMAT;
+    /* check if any of the three upper bits are set
+     * any of them will cause a interger overrun */
+    if ((len - 1) >> (sizeof(len) * 8 - 3))
        return ASN1_OVERRUN;
-
-    e = der_get_octet_string (p, reallen, &k, &l);
-    if (e) return e;
-    p += l;
-    len -= l;
-    ret += l;
-    times = realloc(k.data, k.length + 1);
-    if (times == NULL){
-       free(k.data);
+    data->length = (len - 1) * 8;
+    data->data = malloc(len - 1);
+    if (data->data == NULL && (len - 1) != 0)
        return ENOMEM;
-    }
-    times[k.length] = 0;
-    generalizedtime2time (times, t);
-    free (times);
-    if(size) *size = ret;
-    return 0;
-}
-
-
-int
-fix_dce(size_t reallen, size_t *len)
-{
-    if(reallen == ASN1_INDEFINITE)
-       return 1;
-    if(*len < reallen)
-       return -1;
-    *len = reallen;
+    memcpy (data->data, p + 1, len - 1);
+    data->length -= p[0];
+    if(size) *size = len;
     return 0;
 }
index cb07254a670045fc1a4de033d663c4db7f3bba35..e818267bf48e806b976b900a5761ab27c9927275 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
 
 #include "der_locl.h"
 
-RCSID("$Id: der_length.c,v 1.16 2004/02/07 14:27:59 lha Exp $");
+RCSID("$Id: der_length.c,v 1.17 2005/07/12 06:27:22 lha Exp $");
 
 size_t
 _heim_len_unsigned (unsigned val)
 {
     size_t ret = 0;
-
+    int last_val_gt_128;
+    
     do {
        ++ret;
+       last_val_gt_128 = (val >= 128);
        val /= 256;
     } while (val);
+
+    if(last_val_gt_128)
+       ret++;
+
     return ret;
 }
 
@@ -83,12 +89,10 @@ len_oid (const heim_oid *oid)
     for (n = 2; n < oid->length; ++n) {
        unsigned u = oid->components[n];
 
-       ++ret;
-       u /= 128;
-       while (u > 0) {
+       do {
            ++ret;
            u /= 128;
-       }
+       } while(u > 0);
     }
     return ret;
 }
@@ -98,68 +102,91 @@ length_len (size_t len)
 {
     if (len < 128)
        return 1;
-    else
-       return _heim_len_unsigned (len) + 1;
+    else {
+       int ret = 0;
+       do {
+           ++ret;
+           len /= 256;
+       } while (len);
+       return ret + 1;
+    }
 }
 
 size_t
-length_boolean (const int *data)
+length_integer (const int *data)
 {
-  return 1 + length_len(1) + 1;
+    return _heim_len_int (*data);
 }
 
 size_t
-length_integer (const int *data)
+length_unsigned (const unsigned *data)
 {
-    size_t len = _heim_len_int (*data);
+    return _heim_len_unsigned(*data);
+}
 
-    return 1 + length_len(len) + len;
+size_t
+length_enumerated (const unsigned *data)
+{
+  return _heim_len_int (*data);
 }
 
 size_t
-length_unsigned (const unsigned *data)
+length_general_string (const heim_general_string *data)
 {
-    unsigned val = *data;
-    size_t len = 0;
-    while (val > 255) {
-       ++len;
-       val /= 256;
-    }
-    len++;
-    if (val >= 128)
-       len++;
-    return 1 + length_len(len) + len;
+    return strlen(*data);
 }
 
 size_t
-length_enumerated (const unsigned *data)
+length_utf8string (const heim_utf8_string *data)
 {
-    size_t len = _heim_len_int (*data);
+    return strlen(*data);
+}
 
-    return 1 + length_len(len) + len;
+size_t
+length_printable_string (const heim_printable_string *data)
+{
+    return strlen(*data);
 }
 
 size_t
-length_general_string (const heim_general_string *data)
+length_ia5_string (const heim_ia5_string *data)
+{
+    return strlen(*data);
+}
+
+size_t
+length_bmp_string (const heim_bmp_string *data)
 {
-    char *str = *data;
-    size_t len = strlen(str);
-    return 1 + length_len(len) + len;
+    return data->length * 2;
+}
+
+size_t
+length_universal_string (const heim_universal_string *data)
+{
+    return data->length * 4;
 }
 
 size_t
 length_octet_string (const heim_octet_string *k)
 {
-    return 1 + length_len(k->length) + k->length;
+    return k->length;
 }
 
 size_t
-length_oid (const heim_oid *k)
+length_heim_integer (const heim_integer *k)
 {
-    size_t len = len_oid (k);
+    if (k->length == 0)
+       return 1;
+    if (k->negative)
+       return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 0 : 1);
+    else
+       return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 1 : 0);
+}
 
-    return 1 + length_len(len) + len;
+size_t
+length_oid (const heim_oid *k)
+{
+    return len_oid (k);
 }
 
 size_t
@@ -168,8 +195,32 @@ length_generalized_time (const time_t *t)
     heim_octet_string k;
     size_t ret;
 
-    time2generalizedtime (*t, &k);
-    ret = 1 + length_len(k.length) + k.length;
-    free (k.data);
+    _heim_time2generalizedtime (*t, &k, 1);
+    ret = k.length;
+    free(k.data);
+    return ret;
+}
+
+size_t
+length_utctime (const time_t *t)
+{
+    heim_octet_string k;
+    size_t ret;
+
+    _heim_time2generalizedtime (*t, &k, 0);
+    ret = k.length;
+    free(k.data);
     return ret;
 }
+
+size_t
+length_boolean (const int *k)
+{
+    return 1;
+}
+
+size_t
+length_bit_string (const heim_bit_string *k)
+{
+    return (k->length + 7) / 8 + 1;
+}
index 67e1e877f60115181001aa96c8bf4e0c600da610..1127383e6caceda666e3b884d83979088ae21264 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2002, 2004 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: der_locl.h,v 1.5 2004/02/07 14:16:53 lha Exp $ */
+/* $Id: der_locl.h,v 1.6 2005/07/12 06:27:22 lha Exp $ */
 
 #ifndef __DER_LOCL_H__
 #define __DER_LOCL_H__
 #include <asn1_err.h>
 #include <der.h>
 
+#ifndef HAVE_TIMEGM
+time_t timegm (struct tm *);
+#endif
+
 size_t _heim_len_unsigned (unsigned);
 size_t _heim_len_int (int);
 
index 687dedd09f58dbdc1d25ea14205cba63a291da32..b006f233ca62ab8ab9395fc74c8bf61837501782 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "der_locl.h"
 
-RCSID("$Id: der_put.c,v 1.32 2005/05/29 14:23:01 lha Exp $");
+RCSID("$Id: der_put.c,v 1.33 2005/07/12 06:27:23 lha Exp $");
 
 /*
  * All encoding functions take a pointer `p' to first position in
@@ -43,10 +43,11 @@ RCSID("$Id: der_put.c,v 1.32 2005/05/29 14:23:01 lha Exp $");
  * The return value is 0 or an error.
  */
 
-static int
-der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
+int
+der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
 {
     unsigned char *base = p;
+    unsigned val = *v;
 
     if (val) {
        while (len > 0 && val) {
@@ -57,6 +58,11 @@ der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
        if (val != 0)
            return ASN1_OVERFLOW;
        else {
+           if(p[1] >= 128) {
+               if(len < 1)
+                   return ASN1_OVERFLOW;
+               *p-- = 0;
+           }
            *size = base - p;
            return 0;
        }
@@ -70,9 +76,10 @@ der_put_unsigned (unsigned char *p, size_t len, unsigned val, size_t *size)
 }
 
 int
-der_put_int (unsigned char *p, size_t len, int val, size_t *size)
+der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size)
 {
     unsigned char *base = p;
+    int val = *v;
 
     if(val >= 0) {
        do {
@@ -114,22 +121,26 @@ der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
 {
     if (len < 1)
        return ASN1_OVERFLOW;
+
     if (val < 128) {
        *p = val;
        *size = 1;
-       return 0;
     } else {
-       size_t l;
-       int e;
+       size_t l = 0;
 
-       e = der_put_unsigned (p, len - 1, val, &l);
-       if (e)
-           return e;
-       p -= l;
+       while(val > 0) {
+           if(len < 2)
+               return ASN1_OVERFLOW;
+           *p-- = val % 256;
+           val /= 256;
+           len--;
+           l++;
+       }
        *p = 0x80 | l;
-       *size = l + 1;
-       return 0;
+       if(size)
+           *size = l + 1;
     }
+    return 0;
 }
 
 int
@@ -161,254 +172,247 @@ der_put_general_string (unsigned char *p, size_t len,
 }
 
 int
-der_put_octet_string (unsigned char *p, size_t len, 
-                     const heim_octet_string *data, size_t *size)
+der_put_utf8string (unsigned char *p, size_t len, 
+                   const heim_utf8_string *str, size_t *size)
 {
-    if (len < data->length)
-       return ASN1_OVERFLOW;
-    p -= data->length;
-    len -= data->length;
-    memcpy (p+1, data->data, data->length);
-    *size = data->length;
-    return 0;
+    return der_put_general_string(p, len, str, size);
 }
 
 int
-der_put_oid (unsigned char *p, size_t len,
-            const heim_oid *data, size_t *size)
+der_put_printable_string (unsigned char *p, size_t len, 
+                         const heim_printable_string *str, size_t *size)
 {
-    unsigned char *base = p;
-    int n;
-
-    for (n = data->length - 1; n >= 2; --n) {
-       unsigned u = data->components[n];
-
-       if (len < 1)
-           return ASN1_OVERFLOW;
-       *p-- = u % 128;
-       u /= 128;
-       --len;
-       while (u > 0) {
-           if (len < 1)
-               return ASN1_OVERFLOW;
-           *p-- = 128 + u % 128;
-           u /= 128;
-           --len;
-       }
-    }
-    if (len < 1)
-       return ASN1_OVERFLOW;
-    *p-- = 40 * data->components[0] + data->components[1];
-    *size = base - p;
-    return 0;
+    return der_put_general_string(p, len, str, size);
 }
 
 int
-der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
-            int tag, size_t *size)
+der_put_ia5_string (unsigned char *p, size_t len, 
+                   const heim_ia5_string *str, size_t *size)
 {
-    if (len < 1)
-       return ASN1_OVERFLOW;
-    *p = (class << 6) | (type << 5) | tag; /* XXX */
-    *size = 1;
-    return 0;
+    return der_put_general_string(p, len, str, size);
 }
 
 int
-der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
-                       Der_class class, Der_type type, int tag, size_t *size)
+der_put_bmp_string (unsigned char *p, size_t len, 
+                   const heim_bmp_string *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l;
-    int e;
-
-    e = der_put_length (p, len, len_val, &l);
-    if(e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_tag (p, len, class, type, tag, &l);
-    if(e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    size_t i;
+    if (len / 2 < data->length)
+       return ASN1_OVERFLOW;
+    p -= data->length * 2;
+    len -= data->length * 2;
+    for (i = 0; i < data->length; i++) {
+       p[1] = (data->data[i] >> 8) & 0xff;
+       p[2] = data->data[i] & 0xff;
+       p += 2;
+    }
+    if (size) *size = data->length * 2;
     return 0;
 }
 
 int
-encode_boolean (unsigned char *p, size_t len, const int *data,
-               size_t *size)
+der_put_universal_string (unsigned char *p, size_t len, 
+                         const heim_universal_string *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l;
-    int e;
-    
-    e = der_put_boolean (p, len, data, &l);
-    if(e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Boolean, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    size_t i;
+    if (len / 4 < data->length)
+       return ASN1_OVERFLOW;
+    p -= data->length * 4;
+    len -= data->length * 4;
+    for (i = 0; i < data->length; i++) {
+       p[1] = (data->data[i] >> 24) & 0xff;
+       p[2] = (data->data[i] >> 16) & 0xff;
+       p[3] = (data->data[i] >> 8) & 0xff;
+       p[4] = data->data[i] & 0xff;
+       p += 4;
+    }
+    if (size) *size = data->length * 4;
     return 0;
 }
 
 int
-encode_integer (unsigned char *p, size_t len, const int *data, size_t *size)
+der_put_octet_string (unsigned char *p, size_t len, 
+                     const heim_octet_string *data, size_t *size)
 {
-    int num = *data;
-    size_t ret = 0;
-    size_t l;
-    int e;
-    
-    e = der_put_int (p, len, num, &l);
-    if(e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Integer, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    if (len < data->length)
+       return ASN1_OVERFLOW;
+    p -= data->length;
+    len -= data->length;
+    memcpy (p+1, data->data, data->length);
+    *size = data->length;
     return 0;
 }
 
 int
-encode_unsigned (unsigned char *p, size_t len, const unsigned *data,
-                size_t *size)
+der_put_heim_integer (unsigned char *p, size_t len, 
+                    const heim_integer *data, size_t *size)
 {
-    unsigned num = *data;
-    size_t ret = 0;
-    size_t l;
-    int e;
-    
-    e = der_put_unsigned (p, len, num, &l);
-    if(e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    /* if first octet has msb set, we need to pad with a zero byte */
-    if(p[1] >= 128) {
-       if(len == 0)
+    unsigned char *buf = data->data;
+    int hibitset = 0;
+
+    if (data->length == 0) {
+       if (len < 1)
            return ASN1_OVERFLOW;
        *p-- = 0;
-       len--;
-       ret++;
-       l++;
+       if (size)
+           *size = 1;
+       return 0;
     }
-    e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Integer, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    if (len < data->length)
+       return ASN1_OVERFLOW;
+
+    len -= data->length;
+
+    if (data->negative) {
+       int i, carry;
+       for (i = data->length - 1, carry = 1; i >= 0; i--) {
+           *p = buf[i] ^ 0xff;
+           if (carry)
+               carry = !++*p;
+           p--;
+       }
+       if (p[1] < 128) {
+           if (len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = 0xff;
+           len--;
+           hibitset = 1;
+       }
+    } else {
+       p -= data->length;
+       memcpy(p + 1, buf, data->length);
+
+       if (p[1] >= 128) {
+           if (len < 1)
+               return ASN1_OVERFLOW;
+           p[0] = 0;
+           len--;
+           hibitset = 1;
+       }
+    }
+    if (size)
+       *size = data->length + hibitset;
     return 0;
 }
 
 int
-encode_enumerated (unsigned char *p, size_t len, const unsigned *data,
-                  size_t *size)
+der_put_generalized_time (unsigned char *p, size_t len, 
+                         const time_t *data, size_t *size)
 {
-    unsigned num = *data;
-    size_t ret = 0;
+    heim_octet_string k;
     size_t l;
     int e;
-    
-    e = der_put_int (p, len, num, &l);
-    if(e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_Enumerated, &l);
+
+    e = _heim_time2generalizedtime (*data, &k, 1);
     if (e)
        return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    e = der_put_octet_string(p, len, &k, &l);
+    free(k.data);
+    if(e)
+       return e;
+    if(size)
+       *size = l;
     return 0;
 }
 
 int
-encode_general_string (unsigned char *p, size_t len, 
-                      const heim_general_string *data, size_t *size)
+der_put_utctime (unsigned char *p, size_t len, 
+                const time_t *data, size_t *size)
 {
-    size_t ret = 0;
+    heim_octet_string k;
     size_t l;
     int e;
 
-    e = der_put_general_string (p, len, data, &l);
+    e = _heim_time2generalizedtime (*data, &k, 0);
     if (e)
        return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_GeneralString, &l);
-    if (e)
+    e = der_put_octet_string(p, len, &k, &l);
+    free(k.data);
+    if(e)
        return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    if(size)
+       *size = l;
     return 0;
 }
 
 int
-encode_octet_string (unsigned char *p, size_t len, 
-                    const heim_octet_string *k, size_t *size)
+der_put_oid (unsigned char *p, size_t len,
+            const heim_oid *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l;
-    int e;
+    unsigned char *base = p;
+    int n;
 
-    e = der_put_octet_string (p, len, k, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    for (n = data->length - 1; n >= 2; --n) {
+       unsigned u = data->components[n];
+
+       if (len < 1)
+           return ASN1_OVERFLOW;
+       *p-- = u % 128;
+       u /= 128;
+       --len;
+       while (u > 0) {
+           if (len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = 128 + u % 128;
+           u /= 128;
+           --len;
+       }
+    }
+    if (len < 1)
+       return ASN1_OVERFLOW;
+    *p-- = 40 * data->components[0] + data->components[1];
+    *size = base - p;
+    return 0;
+}
+
+int
+der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
+            unsigned int tag, size_t *size)
+{
+    if (tag <= 30) {
+       if (len < 1)
+           return ASN1_OVERFLOW;
+       *p = MAKE_TAG(class, type, tag);
+       *size = 1;
+    } else {
+       size_t ret = 0;
+       unsigned int continuation = 0;
+       
+       do {
+           if (len < 1)
+               return ASN1_OVERFLOW;
+           *p-- = tag % 128 | continuation;
+           len--;
+           ret++;
+           tag /= 128;
+           continuation = 0x80;
+       } while(tag > 0);
+       if (len < 1)
+           return ASN1_OVERFLOW;
+       *p-- = MAKE_TAG(class, type, 0x1f);
+       ret++;
+       *size = ret;
+    }
     return 0;
 }
 
 int
-encode_oid(unsigned char *p, size_t len,
-          const heim_oid *k, size_t *size)
+der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
+                       Der_class class, Der_type type, 
+                       unsigned int tag, size_t *size)
 {
     size_t ret = 0;
     size_t l;
     int e;
 
-    e = der_put_oid (p, len, k, &l);
-    if (e)
+    e = der_put_length (p, len, len_val, &l);
+    if(e)
        return e;
     p -= l;
     len -= l;
     ret += l;
-    e = der_put_length_and_tag (p, len, l, ASN1_C_UNIV, PRIM, UT_OID, &l);
-    if (e)
+    e = der_put_tag (p, len, class, type, tag, &l);
+    if(e)
        return e;
     p -= l;
     len -= l;
@@ -418,50 +422,55 @@ encode_oid(unsigned char *p, size_t len,
 }
 
 int
-time2generalizedtime (time_t t, heim_octet_string *s)
+_heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
 {
      struct tm *tm;
-     size_t len;
-
-     len = 15;
+     const size_t len = gtimep ? 15 : 13;
 
      s->data = malloc(len + 1);
      if (s->data == NULL)
         return ENOMEM;
      s->length = len;
      tm = gmtime (&t);
-     snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ", 
-              tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 
-              tm->tm_hour, tm->tm_min, tm->tm_sec);
+     if (gtimep)
+        snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ", 
+                  tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 
+                  tm->tm_hour, tm->tm_min, tm->tm_sec);
+     else
+        snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ", 
+                  tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday, 
+                  tm->tm_hour, tm->tm_min, tm->tm_sec);
+
      return 0;
 }
 
 int
-encode_generalized_time (unsigned char *p, size_t len,
-                        const time_t *t, size_t *size)
+der_put_bit_string (unsigned char *p, size_t len, 
+                   const heim_bit_string *data, size_t *size)
 {
-    size_t ret = 0;
-    size_t l;
-    heim_octet_string k;
-    int e;
-
-    e = time2generalizedtime (*t, &k);
-    if (e)
-       return e;
-    e = der_put_octet_string (p, len, &k, &l);
-    free (k.data);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    e = der_put_length_and_tag (p, len, k.length, ASN1_C_UNIV, PRIM, 
-                               UT_GeneralizedTime, &l);
-    if (e)
-       return e;
-    p -= l;
-    len -= l;
-    ret += l;
-    *size = ret;
+    size_t data_size = (data->length + 7) / 8;
+    if (len < data_size + 1)
+       return ASN1_OVERFLOW;
+    p -= data_size + 1;
+    len -= data_size + 1;
+    memcpy (p+2, data->data, data_size);
+    if (data->length && (data->length % 8) != 0)
+       p[1] = 8 - (data->length % 8);
+    else
+       p[1] = 0;
+    *size = data_size + 1;
     return 0;
 }
+
+int 
+_heim_der_set_sort(const void *a1, const void *a2)
+{
+    const struct heim_octet_string *s1 = a1, *s2 = a2;
+    int ret;
+
+    ret = memcmp(s1->data, s2->data, 
+                s1->length < s2->length ? s1->length : s2->length);
+    if(ret)
+       return ret;
+    return s1->length - s2->length;
+}
diff --git a/source4/heimdal/lib/asn1/extra.c b/source4/heimdal/lib/asn1/extra.c
new file mode 100644 (file)
index 0000000..ba081e3
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2003 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * 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 above 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. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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. 
+ */
+
+#include "der_locl.h"
+#include "heim_asn1.h"
+
+RCSID("$Id: extra.c,v 1.5 2005/07/19 18:05:16 lha Exp $");
+
+int
+encode_heim_any(unsigned char *p, size_t len, 
+               const heim_any *data, size_t *size)
+{
+    if (data->length > len)
+       return ASN1_OVERFLOW;
+    p -= data->length;
+    len -= data->length;
+    memcpy (p+1, data->data, data->length);
+    *size = data->length;
+    return 0;
+}
+
+int
+decode_heim_any(const unsigned char *p, size_t len, 
+               heim_any *data, size_t *size)
+{
+    size_t len_len, length, l;
+    Der_class thisclass;
+    Der_type thistype;
+    unsigned int thistag;
+    int e;
+
+    if (data == NULL && len == 0) { /* XXX tag less OPTIONAL */
+       *size = 0;
+       return 0;
+    }
+
+    e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
+    if (e) return e;
+    if (l > len)
+       return ASN1_OVERFLOW;
+    e = der_get_length(p + l, len - l, &length, &len_len);
+    if (e) return e;
+    if (length + len_len + l > len)
+       return ASN1_OVERFLOW;
+
+    if (data) { /* XXX hack to workaround tag less OPTIONAL data */
+       memset(data, 0, sizeof(*data));
+       
+       data->data = malloc(length + len_len + l);
+       if (data->data == NULL)
+           return ENOMEM;
+       data->length = length + len_len + l;
+       memcpy(data->data, p, length + len_len + l);
+    }
+    if (size) *size = length + len_len + l;
+    return 0;
+}
+
+void
+free_heim_any(heim_any *data)
+{
+    free(data->data);
+    data->data = NULL;
+}
+
+size_t
+length_heim_any(const heim_any *data)
+{
+    return data->length;
+}
+
+int
+copy_heim_any(const heim_any *from, heim_any *to)
+{
+    to->data = malloc(from->length);
+    if (to->data == NULL && from->length != 0)
+       return ENOMEM;
+    memcpy(to->data, from->data, from->length);
+    to->length = from->length;
+    return 0;
+}
+
+int
+encode_heim_any_set(unsigned char *p, size_t len, 
+                   const heim_any_set *data, size_t *size)
+{
+    return encode_heim_any(p, len, data, size);
+}
+
+
+int
+decode_heim_any_set(const unsigned char *p, size_t len, 
+               heim_any_set *data, size_t *size)
+{
+    memset(data, 0, sizeof(*data));
+    data->data = malloc(len);
+    if (data->data == NULL && len != 0)
+       return ENOMEM;
+    data->length = len;
+    memcpy(data->data, p, len);
+    if (size) *size = len;
+    return 0;
+}
+
+void
+free_heim_any_set(heim_any_set *data)
+{
+    free_heim_any(data);
+}
+
+size_t
+length_heim_any_set(const heim_any *data)
+{
+    return length_heim_any(data);
+}
+
+int
+copy_heim_any_set(const heim_any_set *from, heim_any_set *to)
+{
+    return copy_heim_any(from, to);
+}
+
+int
+heim_any_cmp(const heim_any_set *p, const heim_any_set *q)
+{
+    if (p->length != q->length)
+       return p->length - q->length;
+    return memcmp(p->data, q->data, p->length);
+}
index 67cc5ce65a2ee5181912a254cdabef8634f1fdaf..1189a03ab10fd105fb60267010e9336dbdac4b68 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen.c,v 1.59 2005/06/16 19:58:15 lha Exp $");
+RCSID("$Id: gen.c,v 1.62 2005/07/19 18:46:50 lha Exp $");
 
 FILE *headerfile, *codefile, *logfile;
 
@@ -41,7 +41,7 @@ FILE *headerfile, *codefile, *logfile;
 
 static const char *orig_filename;
 static char *header;
-static char *headerbase;
+static char *headerbase = STEM;
 
 /*
  * list of all IMPORTs
@@ -70,29 +70,20 @@ get_filename (void)
     return orig_filename;
 }
 
-static int unique_number;
-
-void
-unique_reset(void)
-{
-    unique_number = 0;
-}
-
-int
-unique_get_next(void)
-{
-    return unique_number++;
-}
-
 void
 init_generate (const char *filename, const char *base)
 {
+    char *fn;
+
     orig_filename = filename;
-    if(base)
+    if (base != NULL) {
        asprintf(&headerbase, "%s", base);
-    else
-       headerbase = strdup(STEM);
+       if (headerbase == NULL)
+           errx(1, "malloc");
+    }
     asprintf(&header, "%s.h", headerbase);
+    if (header == NULL)
+       errx(1, "malloc");
     headerfile = fopen (header, "w");
     if (headerfile == NULL)
        err (1, "open %s", header);
@@ -112,6 +103,12 @@ init_generate (const char *filename, const char *base)
     fprintf (headerfile,
             "#ifndef __asn1_common_definitions__\n"
             "#define __asn1_common_definitions__\n\n");
+    fprintf (headerfile,
+            "typedef struct heim_integer {\n"
+            "  size_t length;\n"
+            "  void *data;\n"
+            "  int negative;\n"
+            "} heim_integer;\n\n");
     fprintf (headerfile,
             "typedef struct heim_octet_string {\n"
             "  size_t length;\n"
@@ -123,11 +120,32 @@ init_generate (const char *filename, const char *base)
     fprintf (headerfile,
             "typedef char *heim_utf8_string;\n\n"
             );
+    fprintf (headerfile,
+            "typedef char *heim_printable_string;\n\n"
+            );
+    fprintf (headerfile,
+            "typedef char *heim_ia5_string;\n\n"
+            );
+    fprintf (headerfile,
+            "typedef struct heim_bmp_string {\n"
+            "  size_t length;\n"
+            "  uint16_t *data;\n"
+            "} heim_bmp_string;\n\n");
+    fprintf (headerfile,
+            "typedef struct heim_universal_string {\n"
+            "  size_t length;\n"
+            "  uint32_t *data;\n"
+            "} heim_universal_string;\n\n");
     fprintf (headerfile,
             "typedef struct heim_oid {\n"
             "  size_t length;\n"
             "  unsigned *components;\n"
             "} heim_oid;\n\n");
+    fprintf (headerfile,
+            "typedef struct heim_bit_string {\n"
+            "  size_t length;\n"
+            "  void *data;\n"
+            "} heim_bit_string;\n\n");
     fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R)                  \\\n"
          "  do {                                                         \\\n"
          "    (BL) = length_##T((S));                                    \\\n"
@@ -145,9 +163,12 @@ init_generate (const char *filename, const char *base)
          "  } while (0)\n\n",
          headerfile);
     fprintf (headerfile, "#endif\n\n");
-    logfile = fopen(STEM "_files", "w");
+    asprintf(&fn, "%s_files", base);
+    if (fn == NULL)
+       errx(1, "malloc");
+    logfile = fopen(fn, "w");
     if (logfile == NULL)
-       err (1, "open " STEM "_files");
+       err (1, "open %s", fn);
 }
 
 void
@@ -160,11 +181,165 @@ close_generate (void)
     fclose (logfile);
 }
 
+void
+gen_assign_defval(const char *var, struct value *val)
+{
+    switch(val->type) {
+    case stringvalue:
+       fprintf(codefile, "if((%s = strdup(\"%s\")) == NULL)\nreturn ENOMEM;\n", var, val->u.stringvalue);
+       break;
+    case integervalue:
+       fprintf(codefile, "%s = %d;\n", var, val->u.integervalue);
+       break;
+    case booleanvalue:
+       if(val->u.booleanvalue)
+           fprintf(codefile, "%s = TRUE;\n", var);
+       else
+           fprintf(codefile, "%s = FALSE;\n", var);
+       break;
+    default:
+       abort();
+    }
+}
+
+void
+gen_compare_defval(const char *var, struct value *val)
+{
+    switch(val->type) {
+    case stringvalue:
+       fprintf(codefile, "if(strcmp(%s, \"%s\") != 0)\n", var, val->u.stringvalue);
+       break;
+    case integervalue:
+       fprintf(codefile, "if(%s != %d)\n", var, val->u.integervalue);
+       break;
+    case booleanvalue:
+       if(val->u.booleanvalue)
+           fprintf(codefile, "if(!%s)\n", var);
+       else
+           fprintf(codefile, "if(%s)\n", var);
+       break;
+    default:
+       abort();
+    }
+}
+
+static void
+generate_header_of_codefile(const char *name)
+{
+    struct import *i;
+    char *filename;
+
+    if (codefile != NULL)
+       abort();
+
+    asprintf (&filename, "%s_%s.x", STEM, name);
+    if (filename == NULL)
+       errx(1, "malloc");
+    codefile = fopen (filename, "w");
+    if (codefile == NULL)
+       err (1, "fopen %s", filename);
+    fprintf(logfile, "%s ", filename);
+    free(filename);
+    fprintf (codefile, 
+            "/* Generated from %s */\n"
+            "/* Do not edit */\n\n"
+            "#include <stdio.h>\n"
+            "#include <stdlib.h>\n"
+            "#include <time.h>\n"
+            "#include <string.h>\n"
+            "#include <errno.h>\n"
+            "#include <krb5-types.h>\n",
+            orig_filename);
+
+    for (i = imports; i != NULL; i = i->next)
+       fprintf (codefile,
+                "#include <%s_asn1.h>\n",
+                i->module);
+    fprintf (codefile,
+            "#include <%s.h>\n",
+            headerbase);
+    fprintf (codefile,
+            "#include <asn1_err.h>\n"
+            "#include <der.h>\n"
+            "#include <parse_units.h>\n\n");
+
+}
+
+static void
+close_codefile(void)
+{
+    if (codefile == NULL)
+       abort();
+
+    fclose(codefile);
+    codefile = NULL;
+}
+
+
 void
 generate_constant (const Symbol *s)
 {
-  fprintf (headerfile, "enum { %s = %d };\n\n",
-          s->gen_name, s->constant);
+    switch(s->value->type) {
+    case booleanvalue:
+       break;
+    case integervalue:
+       fprintf (headerfile, "enum { %s = %d };\n\n",
+                s->gen_name, s->value->u.integervalue);
+       break;
+    case nullvalue:
+       break;
+    case stringvalue:
+       break;
+    case objectidentifiervalue: {
+       struct objid *o, **list;
+       int i, len;
+
+       generate_header_of_codefile(s->gen_name);
+
+       len = 0;
+       for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
+           len++;
+       list = emalloc(sizeof(*list) * len);
+
+       i = 0;
+       for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
+           list[i++] = o;
+
+       fprintf (headerfile, "/* OBJECT IDENTIFIER %s ::= { ", s->name);
+       for (i = len - 1 ; i >= 0; i--) {
+           o = list[i];
+           fprintf(headerfile, "%s(%d) ",
+                   o->label ? o->label : "label-less", o->value);
+       }
+
+       fprintf (headerfile, "} */\n");
+       fprintf (headerfile, "const heim_oid *oid_%s(void);\n\n",
+                s->gen_name);
+
+       fprintf (codefile, "static unsigned oid_%s_variable_num[%d] =  {",
+                s->gen_name, len);
+       for (i = len - 1 ; i >= 0; i--) {
+           fprintf(codefile, "%d%s ", list[i]->value, i > 0 ? "," : "");
+       }
+       fprintf(codefile, "};\n");
+
+       fprintf (codefile, "static const heim_oid oid_%s_variable = "
+                "{ %d, oid_%s_variable_num };\n\n", 
+                s->gen_name, len, s->gen_name);
+
+       fprintf (codefile, "const heim_oid *oid_%s(void)\n"
+                "{\n"
+                "return &oid_%s_variable;\n"
+                "}\n\n",
+                s->gen_name, s->gen_name);
+
+       close_codefile();
+
+       break;
+    }
+    default:
+       abort();
+    }
 }
 
 static void
@@ -174,93 +349,108 @@ space(int level)
        fprintf(headerfile, "  ");
 }
 
+static char *
+last_member_p(struct member *m)
+{
+    struct member *n = ASN1_TAILQ_NEXT(m, members);
+    if (n == NULL)
+       return "";
+    if (n->ellipsis && ASN1_TAILQ_NEXT(n, members) == NULL)
+       return "";
+    return ",";
+}
+
+static struct member *
+have_ellipsis(Type *t)
+{
+    struct member *m;
+    ASN1_TAILQ_FOREACH(m, t->members, members) {
+       if (m->ellipsis)
+           return m;
+    }
+    return NULL;
+}
+
 static void
 define_asn1 (int level, Type *t)
 {
     switch (t->type) {
     case TType:
-       space(level);
        fprintf (headerfile, "%s", t->symbol->name);
        break;
     case TInteger:
-       space(level);
-       fprintf (headerfile, "INTEGER");
+       if(t->members == NULL) {
+            fprintf (headerfile, "INTEGER");
+           if (t->range)
+               fprintf (headerfile, " (%d..%d)",
+                        t->range->min, t->range->max);
+        } else {
+           Member *m;
+            fprintf (headerfile, "INTEGER {\n");
+           ASN1_TAILQ_FOREACH(m, t->members, members) {
+                space (level + 1);
+               fprintf(headerfile, "%s(%d)%s\n", m->gen_name, m->val, 
+                       last_member_p(m));
+            }
+           space(level);
+            fprintf (headerfile, "}");
+        }
        break;
-    case TUInteger:
-       space(level);
-       fprintf (headerfile, "UNSIGNED INTEGER");
+    case TBoolean:
+       fprintf (headerfile, "BOOLEAN");
        break;
     case TOctetString:
-       space(level);
        fprintf (headerfile, "OCTET STRING");
        break;
-    case TOID :
-       space(level);
-       fprintf(headerfile, "OBJECT IDENTIFIER");
-       break;
+    case TEnumerated :
     case TBitString: {
        Member *m;
-       int tag = -1;
 
        space(level);
-       fprintf (headerfile, "BIT STRING {\n");
-       for (m = t->members; m && m->val != tag; m = m->next) {
-           if (tag == -1)
-               tag = m->val;
+       if(t->type == TBitString)
+           fprintf (headerfile, "BIT STRING {\n");
+       else
+           fprintf (headerfile, "ENUMERATED {\n");
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
            space(level + 1);
            fprintf (headerfile, "%s(%d)%s\n", m->name, m->val, 
-                    m->next->val == tag?"":",");
-
-       }
-       space(level);
-       fprintf (headerfile, "}");
-       break;
-    }
-    case TEnumerated : {
-       Member *m;
-       int tag = -1;
-
-       space(level);
-       fprintf (headerfile, "ENUMERATED {\n");
-       for (m = t->members; m && m->val != tag; m = m->next) {
-           if (tag == -1)
-               tag = m->val;
-           space(level + 1);
-           fprintf (headerfile, "%s(%d)%s\n", m->name, m->val, 
-                    m->next->val == tag?"":",");
-
+                    last_member_p(m));
        }
        space(level);
        fprintf (headerfile, "}");
        break;
     }
+    case TChoice:
+    case TSet:
     case TSequence: {
        Member *m;
-       int tag;
        int max_width = 0;
 
-       space(level);
-       fprintf (headerfile, "SEQUENCE {\n");
-       for (m = t->members, tag = -1; m && m->val != tag; m = m->next) {
-           if (tag == -1)
-               tag = m->val;
-           if(strlen(m->name) + (m->val > 9) > max_width)
-               max_width = strlen(m->name) + (m->val > 9);
+       if(t->type == TChoice)
+           fprintf(headerfile, "CHOICE {\n");
+       else if(t->type == TSet)
+           fprintf(headerfile, "SET {\n");
+       else
+           fprintf(headerfile, "SEQUENCE {\n");
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           if(strlen(m->name) > max_width)
+               max_width = strlen(m->name);
        }
-       max_width += 3 + 2;
+       max_width += 3;
        if(max_width < 16) max_width = 16;
-       for (m = t->members, tag = -1 ; m && m->val != tag; m = m->next) {
-           int width;
-           if (tag == -1)
-               tag = m->val;
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           int width = max_width;
            space(level + 1);
-           fprintf(headerfile, "%s[%d]", m->name, m->val);
-           width = max_width - strlen(m->name) - 3 - (m->val > 9) - 2;
-           fprintf(headerfile, "%*s", width, "");
-           define_asn1(level + 1, m->type);
-           if(m->optional)
-               fprintf(headerfile, " OPTIONAL");
-           if(m->next->val != tag)
+           if (m->ellipsis) {
+               fprintf (headerfile, "...");
+           } else {
+               width -= fprintf(headerfile, "%s", m->name);
+               fprintf(headerfile, "%*s", width, "");
+               define_asn1(level + 1, m->type);
+               if(m->optional)
+                   fprintf(headerfile, " OPTIONAL");
+           }
+           if(last_member_p(m))
                fprintf (headerfile, ",");
            fprintf (headerfile, "\n");
        }
@@ -268,32 +458,59 @@ define_asn1 (int level, Type *t)
        fprintf (headerfile, "}");
        break;
     }
-    case TSequenceOf: {
-       space(level);
+    case TSequenceOf:
        fprintf (headerfile, "SEQUENCE OF ");
        define_asn1 (0, t->subtype);
        break;
-    }
+    case TSetOf:
+       fprintf (headerfile, "SET OF ");
+       define_asn1 (0, t->subtype);
+       break;
     case TGeneralizedTime:
-       space(level);
        fprintf (headerfile, "GeneralizedTime");
        break;
     case TGeneralString:
-       space(level);
        fprintf (headerfile, "GeneralString");
        break;
-    case TApplication:
-       fprintf (headerfile, "[APPLICATION %d] ", t->application);
+    case TTag: {
+       const char *classnames[] = { "UNIVERSAL ", "APPLICATION ", 
+                                    "" /* CONTEXT */, "PRIVATE " };
+       if(t->tag.tagclass != ASN1_C_UNIV)
+           fprintf (headerfile, "[%s%d] ", 
+                    classnames[t->tag.tagclass],
+                    t->tag.tagvalue);
+       if(t->tag.tagenv == TE_IMPLICIT)
+           fprintf (headerfile, "IMPLICIT ");
        define_asn1 (level, t->subtype);
        break;
-    case TBoolean:
-       space(level);
-       fprintf (headerfile, "BOOLEAN");
+    }
+    case TUTCTime:
+       fprintf (headerfile, "UTCTime");
        break;
     case TUTF8String:
        space(level);
        fprintf (headerfile, "UTF8String");
        break;
+    case TPrintableString:
+       space(level);
+       fprintf (headerfile, "PrintableString");
+       break;
+    case TIA5String:
+       space(level);
+       fprintf (headerfile, "IA5String");
+       break;
+    case TBMPString:
+       space(level);
+       fprintf (headerfile, "BMPString");
+       break;
+    case TUniversalString:
+       space(level);
+       fprintf (headerfile, "UniversalString");
+       break;
+    case TOID :
+       space(level);
+       fprintf(headerfile, "OBJECT IDENTIFIER");
+       break;
     case TNull:
        space(level);
        fprintf (headerfile, "NULL");
@@ -304,7 +521,7 @@ define_asn1 (int level, Type *t)
 }
 
 static void
-define_type (int level, const char *name, Type *t, int typedefp)
+define_type (int level, char *name, Type *t, int typedefp, int preservep)
 {
     switch (t->type) {
     case TType:
@@ -313,104 +530,121 @@ define_type (int level, const char *name, Type *t, int typedefp)
        break;
     case TInteger:
        space(level);
-        if(t->members == NULL) {
-            fprintf (headerfile, "int %s;\n", name);
-        } else {
+       if(t->members) {
             Member *m;
-            int tag = -1;
             fprintf (headerfile, "enum %s {\n", typedefp ? name : "");
-           for (m = t->members; m && m->val != tag; m = m->next) {
-                if(tag == -1)
-                    tag = m->val;
+           ASN1_TAILQ_FOREACH(m, t->members, members) {
                 space (level + 1);
                 fprintf(headerfile, "%s = %d%s\n", m->gen_name, m->val, 
-                        m->next->val == tag ? "" : ",");
+                        last_member_p(m));
             }
             fprintf (headerfile, "} %s;\n", name);
-        }
+       } else if (t->range == NULL) {
+           fprintf (headerfile, "heim_integer %s;\n", name);
+       } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
+           fprintf (headerfile, "int %s;\n", name);
+       } else if (t->range->min == 0 && t->range->max == UINT_MAX) {
+           fprintf (headerfile, "unsigned int %s;\n", name);
+       } else if (t->range->min == 0 && t->range->max == INT_MAX) {
+           fprintf (headerfile, "unsigned int %s;\n", name);
+       } else
+           errx(1, "%s: unsupported range %d -> %d", 
+                name, t->range->min, t->range->max);
        break;
-    case TUInteger:
+    case TBoolean:
        space(level);
-       fprintf (headerfile, "unsigned int %s;\n", name);
+       fprintf (headerfile, "int %s;\n", name);
        break;
     case TOctetString:
        space(level);
        fprintf (headerfile, "heim_octet_string %s;\n", name);
        break;
-    case TOID :
-       space(level);
-       fprintf (headerfile, "heim_oid %s;\n", name);
-       break;
     case TBitString: {
        Member *m;
        Type i;
-       int tag = -1;
+       struct range range = { 0, INT_MAX };
+
+       i.type = TInteger;
+       i.range = &range;
+       i.members = NULL;
 
-       i.type = TUInteger;
        space(level);
-       fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
-       for (m = t->members; m && m->val != tag; m = m->next) {
-           char *n;
-
-           asprintf (&n, "%s:1", m->gen_name);
-           define_type (level + 1, n, &i, FALSE);
-           free (n);
-           if (tag == -1)
-               tag = m->val;
+       if(ASN1_TAILQ_EMPTY(t->members)) 
+           fprintf (headerfile, "heim_bit_string %s;\n", name);
+       else {
+           fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
+           ASN1_TAILQ_FOREACH(m, t->members, members) {
+               char *n;
+               
+               asprintf (&n, "%s:1", m->gen_name);
+               if (n == NULL)
+                   errx(1, "malloc");
+               define_type (level + 1, n, &i, FALSE, FALSE);
+               free (n);
+           }
+           space(level);
+           fprintf (headerfile, "} %s;\n\n", name);
        }
-       space(level);
-       fprintf (headerfile, "} %s;\n\n", name);
        break;
     }
     case TEnumerated: {
        Member *m;
-       int tag = -1;
 
        space(level);
        fprintf (headerfile, "enum %s {\n", typedefp ? name : "");
-       for (m = t->members; m && m->val != tag; m = m->next) {
-           if (tag == -1)
-               tag = m->val;
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
            space(level + 1);
-           fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val,
-                        m->next->val == tag ? "" : ",");
+           if (m->ellipsis)
+               fprintf (headerfile, "/* ... */\n");
+           else
+               fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val,
+                        last_member_p(m));
        }
        space(level);
        fprintf (headerfile, "} %s;\n\n", name);
        break;
     }
+    case TSet:
     case TSequence: {
        Member *m;
-       int tag = -1;
 
        space(level);
        fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
-       for (m = t->members; m && m->val != tag; m = m->next) {
-           if (m->optional) {
+       if (t->type == TSequence && preservep) {
+           space(level + 1);
+           fprintf(headerfile, "heim_octet_string _save;\n");
+       }
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           if (m->ellipsis) {
+               ;
+           } else if (m->optional) {
                char *n;
 
                asprintf (&n, "*%s", m->gen_name);
-               define_type (level + 1, n, m->type, FALSE);
+               if (n == NULL)
+                   errx(1, "malloc");
+               define_type (level + 1, n, m->type, FALSE, FALSE);
                free (n);
            } else
-               define_type (level + 1, m->gen_name, m->type, FALSE);
-           if (tag == -1)
-               tag = m->val;
+               define_type (level + 1, m->gen_name, m->type, FALSE, FALSE);
        }
        space(level);
        fprintf (headerfile, "} %s;\n", name);
        break;
     }
+    case TSetOf:
     case TSequenceOf: {
        Type i;
+       struct range range = { 0, INT_MAX };
 
-       i.type = TUInteger;
-       i.application = 0;
+       i.type = TInteger;
+       i.range = &range;
+       i.members = NULL;
 
        space(level);
        fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
-       define_type (level + 1, "len", &i, FALSE);
-       define_type (level + 1, "*val", t->subtype, FALSE);
+       define_type (level + 1, "len", &i, FALSE, FALSE);
+       define_type (level + 1, "*val", t->subtype, FALSE, FALSE);
        space(level);
        fprintf (headerfile, "} %s;\n", name);
        break;
@@ -423,20 +657,93 @@ define_type (int level, const char *name, Type *t, int typedefp)
        space(level);
        fprintf (headerfile, "heim_general_string %s;\n", name);
        break;
+    case TTag:
+       define_type (level, name, t->subtype, typedefp, preservep);
+       break;
+    case TChoice: {
+       int first = 1;
+       Member *m;
+
+       space(level);
+       fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
+       if (preservep) {
+           space(level + 1);
+           fprintf(headerfile, "heim_octet_string _save;\n");
+       }
+       space(level + 1);
+       fprintf (headerfile, "enum {\n");
+       m = have_ellipsis(t);
+       if (m) {
+           space(level + 2);
+           fprintf (headerfile, "%s = 0,\n", m->label); 
+           first = 0;
+       }
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           space(level + 2);
+           if (m->ellipsis)
+               fprintf (headerfile, "/* ... */\n");
+           else
+               fprintf (headerfile, "%s%s%s\n", m->label, 
+                        first ? " = 1" : "", 
+                        last_member_p(m));
+           first = 0;
+       }
+       space(level + 1);
+       fprintf (headerfile, "} element;\n");
+       space(level + 1);
+       fprintf (headerfile, "union {\n");
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           if (m->ellipsis) {
+               space(level + 2);
+               fprintf(headerfile, "heim_octet_string asn1_ellipsis;\n");
+           } else if (m->optional) {
+               char *n;
+
+               asprintf (&n, "*%s", m->gen_name);
+               if (n == NULL)
+                   errx(1, "malloc");
+               define_type (level + 2, n, m->type, FALSE, FALSE);
+               free (n);
+           } else
+               define_type (level + 2, m->gen_name, m->type, FALSE, FALSE);
+       }
+       space(level + 1);
+       fprintf (headerfile, "} u;\n");
+       space(level);
+       fprintf (headerfile, "} %s;\n", name);
+       break;
+    }
+    case TUTCTime:
+       space(level);
+       fprintf (headerfile, "time_t %s;\n", name);
+       break;
     case TUTF8String:
        space(level);
        fprintf (headerfile, "heim_utf8_string %s;\n", name);
        break;
-    case TBoolean:
+    case TPrintableString:
        space(level);
-       fprintf (headerfile, "int %s;\n", name);
+       fprintf (headerfile, "heim_printable_string %s;\n", name);
        break;
-    case TNull:
+    case TIA5String:
+       space(level);
+       fprintf (headerfile, "heim_ia5_string %s;\n", name);
+       break;
+    case TBMPString:
        space(level);
-       fprintf (headerfile, "NULL %s;\n", name);
+       fprintf (headerfile, "heim_bmp_string %s;\n", name);
        break;
-    case TApplication:
-       define_type (level, name, t->subtype, FALSE);
+    case TUniversalString:
+       space(level);
+       fprintf (headerfile, "heim_universal_string %s;\n", name);
+       break;
+    case TOID :
+       space(level);
+       fprintf (headerfile, "heim_oid %s;\n", name);
+       break;
+    case TNull:
+       space(level);
+       fprintf (headerfile, "int %s;\n", name);
        break;
     default:
        abort ();
@@ -446,13 +753,15 @@ define_type (int level, const char *name, Type *t, int typedefp)
 static void
 generate_type_header (const Symbol *s)
 {
+    int preservep = preserve_type(s->name) ? TRUE : FALSE;
+
     fprintf (headerfile, "/*\n");
     fprintf (headerfile, "%s ::= ", s->name);
     define_asn1 (0, s->type);
     fprintf (headerfile, "\n*/\n\n");
 
     fprintf (headerfile, "typedef ");
-    define_type (0, s->gen_name, s->type, TRUE);
+    define_type (0, s->gen_name, s->type, TRUE, preservep);
 
     fprintf (headerfile, "\n");
 }
@@ -461,50 +770,15 @@ generate_type_header (const Symbol *s)
 void
 generate_type (const Symbol *s)
 {
-    struct import *i;
-    char *filename;
-
-    asprintf (&filename, "%s_%s.x", STEM, s->gen_name);
-    codefile = fopen (filename, "w");
-    if (codefile == NULL)
-       err (1, "fopen %s", filename);
-    fprintf(logfile, "%s ", filename);
-    free(filename);
-    fprintf (codefile, 
-            "/* Generated from %s */\n"
-            "/* Do not edit */\n\n"
-            "#include <stdio.h>\n"
-            "#include <stdlib.h>\n"
-            "#include <time.h>\n"
-            "#include <string.h>\n"
-            "#include <errno.h>\n",
-            orig_filename);
-
-    for (i = imports; i != NULL; i = i->next)
-       fprintf (codefile,
-                "#include <%s_asn1.h>\n",
-                i->module);
-    fprintf (codefile,
-            "#include <%s.h>\n",
-            headerbase);
-    fprintf (codefile,
-            "#include <asn1_err.h>\n"
-            "#include <der.h>\n"
-            "#include <parse_units.h>\n\n");
-
-    if (s->stype == Stype && s->type->type == TChoice) {
-       fprintf(codefile,
-               "/* CHOICE */\n"
-               "int asn1_%s_dummy_holder = 1;\n", s->gen_name);
-    } else {
-       generate_type_header (s);
-       generate_type_encode (s);
-       generate_type_decode (s);
-       generate_type_free (s);
-       generate_type_length (s);
-       generate_type_copy (s);
-       generate_glue (s);
-    }
+    generate_header_of_codefile(s->gen_name);
+
+    generate_type_header (s);
+    generate_type_encode (s);
+    generate_type_decode (s);
+    generate_type_free (s);
+    generate_type_length (s);
+    generate_type_copy (s);
+    generate_glue (s->type, s->gen_name);
     fprintf(headerfile, "\n\n");
-    fclose(codefile);
+    close_codefile();
 }
index a8421fea6a9f2632e6124a5f1c38c2a682cc509a..07b7efba2c833d9860de4518efec473131384efc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen_copy.c,v 1.15 2005/06/16 20:03:38 lha Exp $");
+RCSID("$Id: gen_copy.c,v 1.16 2005/07/12 06:27:26 lha Exp $");
+
+static int used_fail;
 
 static void
 copy_primitive (const char *typename, const char *from, const char *to)
 {
-    fprintf (codefile, "if(copy_%s(%s, %s)) return ENOMEM;\n", 
+    fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n", 
             typename, from, to);
+    used_fail++;
 }
 
 static void
-copy_type (const char *from, const char *to, const Type *t)
+copy_type (const char *from, const char *to, const Type *t, int preserve)
 {
-  switch (t->type) {
-  case TType:
+    switch (t->type) {
+    case TType:
 #if 0
-      copy_type (from, to, t->symbol->type);
+       copy_type (from, to, t->symbol->type, preserve);
 #endif
-      fprintf (codefile, "if(copy_%s(%s, %s)) return ENOMEM;\n", 
-              t->symbol->gen_name, from, to);
-      break;
-  case TInteger:
-  case TUInteger:
-  case TBoolean:
-  case TEnumerated :
-      fprintf(codefile, "*(%s) = *(%s);\n", to, from);
-      break;
-  case TOctetString:
-      copy_primitive ("octet_string", from, to);
-      break;
-  case TOID:
-      copy_primitive ("oid", from, to);
-      break;
-  case TBitString: {
-      fprintf(codefile, "*(%s) = *(%s);\n", to, from);
-      break;
-  }
-  case TSequence: {
-      Member *m;
-      int tag = -1;
-
-      if (t->members == NULL)
-         break;
+       fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n", 
+                t->symbol->gen_name, from, to);
+       used_fail++;
+       break;
+    case TInteger:
+       if (t->range == NULL && t->members == NULL) {
+           copy_primitive ("heim_integer", from, to);
+           break;
+       }
+    case TBoolean:
+    case TEnumerated :
+       fprintf(codefile, "*(%s) = *(%s);\n", to, from);
+       break;
+    case TOctetString:
+       copy_primitive ("octet_string", from, to);
+       break;
+    case TBitString:
+       if (ASN1_TAILQ_EMPTY(t->members))
+           copy_primitive ("bit_string", from, to);
+       else
+           fprintf(codefile, "*(%s) = *(%s);\n", to, from);
+       break;
+    case TSet:
+    case TSequence:
+    case TChoice: {
+       Member *m, *have_ellipsis = NULL;
+
+       if(t->members == NULL)
+           break;
       
-      for (m = t->members; m && tag != m->val; m = m->next) {
-         char *fn;
-         char *tn;
-
-         asprintf (&fn, "%s(%s)->%s",
-                   m->optional ? "" : "&", from, m->gen_name);
-         asprintf (&tn, "%s(%s)->%s",
-                   m->optional ? "" : "&", to, m->gen_name);
-         if(m->optional){
-             fprintf(codefile, "if(%s) {\n", fn);
-             fprintf(codefile, "%s = malloc(sizeof(*%s));\n", tn, tn);
-             fprintf(codefile, "if(%s == NULL) return ENOMEM;\n", tn);
-         }
-         copy_type (fn, tn, m->type);
-         if(m->optional){
-             fprintf(codefile, "}else\n");
-             fprintf(codefile, "%s = NULL;\n", tn);
-         }
-         if (tag == -1)
-             tag = m->val;
-         free (fn);
-         free (tn);
-      }
-      break;
-  }
-  case TSequenceOf: {
-      char *f;
-      char *T;
-
-      fprintf (codefile, "if(((%s)->val = "
-              "malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n", 
-              to, from, to, from);
-      fprintf (codefile, "return ENOMEM;\n");
-      fprintf(codefile,
-             "for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
-             to, to, from, to);
-      asprintf(&f, "&(%s)->val[(%s)->len]", from, to);
-      asprintf(&T, "&(%s)->val[(%s)->len]", to, to);
-      copy_type(f, T, t->subtype);
-      fprintf(codefile, "}\n");
-      free(f);
-      free(T);
-      break;
-  }
-  case TGeneralizedTime:
-      fprintf(codefile, "*(%s) = *(%s);\n", to, from);
-      break;
-  case TGeneralString:
-      copy_primitive ("general_string", from, to);
-      break;
-  case TUTF8String:
-      copy_primitive ("utf8string", from, to);
-      break;
-  case TNull:
-      break;
-  case TApplication:
-      copy_type (from, to, t->subtype);
-      break;
-  default :
-      abort ();
-  }
+       if ((t->type == TSequence || t->type == TChoice) && preserve) {
+           fprintf(codefile,
+                   "{ int ret;\n"
+                   "ret = copy_octet_string(&(%s)->_save, &(%s)->_save);\n"
+                   "if (ret) goto fail;\n"
+                   "}\n",
+                   from, to);
+           used_fail++;
+       }
+
+       if(t->type == TChoice) {
+           fprintf(codefile, "(%s)->element = (%s)->element;\n", to, from);
+           fprintf(codefile, "switch((%s)->element) {\n", from);
+       }
+
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           char *fs;
+           char *ts;
+
+           if (m->ellipsis) {
+               have_ellipsis = m;
+               continue;
+           }
+
+           if(t->type == TChoice)
+               fprintf(codefile, "case %s:\n", m->label);
+
+           asprintf (&fs, "%s(%s)->%s%s",
+                     m->optional ? "" : "&", from, 
+                     t->type == TChoice ? "u." : "", m->gen_name);
+           if (fs == NULL)
+               errx(1, "malloc");
+           asprintf (&ts, "%s(%s)->%s%s",
+                     m->optional ? "" : "&", to, 
+                     t->type == TChoice ? "u." : "", m->gen_name);
+           if (ts == NULL)
+               errx(1, "malloc");
+           if(m->optional){
+               fprintf(codefile, "if(%s) {\n", fs);
+               fprintf(codefile, "%s = malloc(sizeof(*%s));\n", ts, ts);
+               fprintf(codefile, "if(%s == NULL) goto fail;\n", ts);
+               used_fail++;
+           }
+           copy_type (fs, ts, m->type, FALSE);
+           if(m->optional){
+               fprintf(codefile, "}else\n");
+               fprintf(codefile, "%s = NULL;\n", ts);
+           }
+           free (fs);
+           free (ts);
+           if(t->type == TChoice)
+               fprintf(codefile, "break;\n");
+       }
+       if(t->type == TChoice) {
+           if (have_ellipsis) {
+               fprintf(codefile, "case %s: {\n"
+                       "int ret;\n"
+                       "ret = copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n"
+                       "if (ret) goto fail;\n"
+                       "break;\n"
+                       "}\n",
+                       have_ellipsis->label,
+                       from, have_ellipsis->gen_name, 
+                       to, have_ellipsis->gen_name);
+               used_fail++;
+           }
+           fprintf(codefile, "}\n");   
+       }
+       break;
+    }
+    case TSetOf:
+    case TSequenceOf: {
+       char *f;
+       char *T;
+
+       fprintf (codefile, "if(((%s)->val = "
+                "malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n", 
+                to, from, to, from);
+       fprintf (codefile, "goto fail;\n");
+       used_fail++;
+       fprintf(codefile,
+               "for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
+               to, to, from, to);
+       asprintf(&f, "&(%s)->val[(%s)->len]", from, to);
+       if (f == NULL)
+           errx(1, "malloc");
+       asprintf(&T, "&(%s)->val[(%s)->len]", to, to);
+       if (T == NULL)
+           errx(1, "malloc");
+       copy_type(f, T, t->subtype, FALSE);
+       fprintf(codefile, "}\n");
+       free(f);
+       free(T);
+       break;
+    }
+    case TGeneralizedTime:
+       fprintf(codefile, "*(%s) = *(%s);\n", to, from);
+       break;
+    case TGeneralString:
+       copy_primitive ("general_string", from, to);
+       break;
+    case TUTCTime:
+       fprintf(codefile, "*(%s) = *(%s);\n", to, from);
+       break;
+    case TUTF8String:
+       copy_primitive ("utf8string", from, to);
+       break;
+    case TPrintableString:
+       copy_primitive ("printable_string", from, to);
+       break;
+    case TIA5String:
+       copy_primitive ("ia5_string", from, to);
+       break;
+    case TBMPString:
+       copy_primitive ("bmp_string", from, to);
+       break;
+    case TUniversalString:
+       copy_primitive ("universal_string", from, to);
+       break;
+    case TTag:
+       copy_type (from, to, t->subtype, preserve);
+       break;
+    case TOID:
+       copy_primitive ("oid", from, to);
+       break;
+    case TNull:
+       break;
+    default :
+       abort ();
+    }
 }
 
 void
 generate_type_copy (const Symbol *s)
 {
+  int preserve = preserve_type(s->name) ? TRUE : FALSE;
+
+  used_fail = 0;
+
   fprintf (headerfile,
           "int    copy_%s  (const %s *, %s *);\n",
           s->gen_name, s->gen_name, s->gen_name);
 
   fprintf (codefile, "int\n"
           "copy_%s(const %s *from, %s *to)\n"
-          "{\n",
+          "{\n"
+          "memset(to, 0, sizeof(*to));\n",
           s->gen_name, s->gen_name, s->gen_name);
+  copy_type ("from", "to", s->type, preserve);
+  fprintf (codefile, "return 0;\n");
+
+  if (used_fail)
+      fprintf (codefile, "fail:\n"
+              "free_%s(to);\n"
+              "return ENOMEM;\n",
+              s->gen_name);
 
-  copy_type ("from", "to", s->type);
-  fprintf (codefile, "return 0;\n}\n\n");
+  fprintf(codefile,
+         "}\n\n");
 }
 
index f49593dbcf69e1443f5d57d40d99beb0cd5313fb..ff75113576392be532b72dc56d9699ae9cbff836 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
  */
 
 #include "gen_locl.h"
+#include "lex.h"
 
-RCSID("$Id: gen_decode.c,v 1.21 2005/05/29 14:23:01 lha Exp $");
+RCSID("$Id: gen_decode.c,v 1.27 2005/07/19 18:09:30 lha Exp $");
 
 static void
-decode_primitive (const char *typename, const char *name)
+decode_primitive (const char *typename, const char *name, const char *forwstr)
 {
+#if 0
     fprintf (codefile,
             "e = decode_%s(p, len, %s, &l);\n"
-            "FORW;\n",
+            "%s;\n",
+            typename,
+            name,
+            forwstr);
+#else
+    fprintf (codefile,
+            "e = der_get_%s(p, len, %s, &l);\n"
+            "if(e) %s;\np += l; len -= l; ret += l;\n",
             typename,
-            name);
+            name,
+            forwstr);
+#endif
+}
+
+static int
+is_primitive_type(int type)
+{
+    switch(type) {
+    case TInteger:
+    case TBoolean:
+    case TOctetString:
+    case TBitString:
+    case TEnumerated:
+    case TGeneralizedTime:
+    case TGeneralString:
+    case TOID:
+    case TUTCTime:
+    case TUTF8String:
+    case TPrintableString:
+    case TIA5String:
+    case TBMPString:
+    case TUniversalString:
+    case TNull:
+       return 1;
+    default:
+       return 0;
+    }
 }
 
 static void
-decode_type (const char *name, const Type *t)
+find_tag (const Type *t,
+         Der_class *cl, Der_type *ty, unsigned *tag)
 {
     switch (t->type) {
-    case TType:
-#if 0
-       decode_type (name, t->symbol->type);
-#endif
+    case TBitString:
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_BitString;
+       break;
+    case TBoolean:
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_Boolean;
+       break;
+    case TChoice: 
+       errx(1, "Cannot have recursive CHOICE");
+    case TEnumerated:
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_Enumerated;
+       break;
+    case TGeneralString: 
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_GeneralString;
+       break;
+    case TGeneralizedTime: 
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_GeneralizedTime;
+       break;
+    case TIA5String:
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_IA5String;
+       break;
+    case TInteger: 
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_Integer;
+       break;
+    case TNull:
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_Null;
+       break;
+    case TOID: 
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_OID;
+       break;
+    case TOctetString: 
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_OctetString;
+       break;
+    case TPrintableString:
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_PrintableString;
+       break;
+    case TSequence: 
+    case TSequenceOf:
+       *cl  = ASN1_C_UNIV;
+       *ty  = CONS;
+       *tag = UT_Sequence;
+       break;
+    case TSet: 
+    case TSetOf:
+       *cl  = ASN1_C_UNIV;
+       *ty  = CONS;
+       *tag = UT_Set;
+       break;
+    case TTag: 
+       *cl  = t->tag.tagclass;
+       *ty  = is_primitive_type(t->subtype->type) ? PRIM : CONS;
+       *tag = t->tag.tagvalue;
+       break;
+    case TType: 
+       if ((t->symbol->stype == Stype && t->symbol->type == NULL)
+           || t->symbol->stype == SUndefined) {
+           error_message("%s is imported or still undefined, "
+                         " can't generate tag checking data in CHOICE "
+                         "without this information",
+                         t->symbol->name);
+           exit(1);
+       }
+       find_tag(t->symbol->type, cl, ty, tag);
+       return;
+    case TUTCTime: 
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_UTCTime;
+       break;
+    case TUTF8String:
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_UTF8String;
+       break;
+    case TBMPString:
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_BMPString;
+       break;
+    case TUniversalString:
+       *cl  = ASN1_C_UNIV;
+       *ty  = PRIM;
+       *tag = UT_UniversalString;
+       break;
+    default:
+       abort();
+    }
+}
+
+static int
+decode_type (const char *name, const Type *t, int optional, 
+            const char *forwstr)
+{
+    switch (t->type) {
+    case TType: {
+       if (optional)
+           fprintf(codefile, 
+                   "%s = calloc(1, sizeof(*%s));\n"
+                   "if (%s == NULL) %s;\n",
+                   name, name, name, forwstr);
        fprintf (codefile,
-                "e = decode_%s(p, len, %s, &l);\n"
-                "FORW;\n",
+                "e = decode_%s(p, len, %s, &l);\n",
                 t->symbol->gen_name, name);
+       if (optional) {
+           fprintf (codefile,
+                    "if(e) {\n"
+                    "free(%s);\n"
+                    "%s = NULL;\n"
+                    "} else {\n"
+                    "p += l; len -= l; ret += l;\n"
+                    "}\n",
+                    name, name);
+       } else {
+           fprintf (codefile,
+                    "if(e) %s;\n",
+                    forwstr);
+           fprintf (codefile,
+                    "p += l; len -= l; ret += l;\n");
+       }
        break;
+    }
     case TInteger:
-       if(t->members == NULL)
-           decode_primitive ("integer", name);
-       else {
+       if(t->members) {
            char *s;
            asprintf(&s, "(int*)%s", name);
-           if(s == NULL)
+           if (s == NULL)
                errx (1, "out of memory");
-           decode_primitive ("integer", s);
+           decode_primitive ("integer", s, forwstr);
            free(s);
-       }
-       break;
-    case TUInteger:
-       decode_primitive ("unsigned", name);
+       } else if (t->range == NULL) {
+           decode_primitive ("heim_integer", name, forwstr);
+       } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
+           decode_primitive ("integer", name, forwstr);
+       } else if (t->range->min == 0 && t->range->max == UINT_MAX) {
+           decode_primitive ("unsigned", name, forwstr);
+       } else if (t->range->min == 0 && t->range->max == INT_MAX) {
+           decode_primitive ("unsigned", name, forwstr);
+       } else
+           errx(1, "%s: unsupported range %d -> %d", 
+                name, t->range->min, t->range->max);
        break;
+    case TBoolean:
+      decode_primitive ("boolean", name, forwstr);
+      break;
     case TEnumerated:
-       decode_primitive ("enumerated", name);
+       decode_primitive ("enumerated", name, forwstr);
        break;
     case TOctetString:
-       decode_primitive ("octet_string", name);
-       break;
-    case TOID :
-       decode_primitive ("oid", name);
+       decode_primitive ("octet_string", name, forwstr);
        break;
     case TBitString: {
        Member *m;
-       int tag = -1;
-       int pos;
+       int pos = 0;
 
-       fprintf (codefile,
-                "e = der_match_tag_and_length (p, len, ASN1_C_UNIV, PRIM, UT_BitString,"
-                "&reallen, &l);\n"
-                "FORW;\n"
-                "if(len < reallen)\n"
-                "return ASN1_OVERRUN;\n"
-                "p++;\n"
-                "len--;\n"
-                "reallen--;\n"
-                "ret++;\n");
-       pos = 0;
-       for (m = t->members; m && tag != m->val; m = m->next) {
+       if (ASN1_TAILQ_EMPTY(t->members)) {
+           decode_primitive ("bit_string", name, forwstr);
+           break;
+       }
+       fprintf(codefile,
+               "if (len < 1) return ASN1_OVERRUN;\n"
+               "p++; len--; ret++;\n");
+       fprintf(codefile,
+               "do {\n"
+               "if (len < 1) break;\n");
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
            while (m->val / 8 > pos / 8) {
                fprintf (codefile,
-                        "p++; len--; reallen--; ret++;\n");
+                        "p++; len--; ret++;\n"
+                        "if (len < 1) break;\n");
                pos += 8;
            }
            fprintf (codefile,
-                    "%s->%s = (*p >> %d) & 1;\n",
+                    "(%s)->%s = (*p >> %d) & 1;\n",
                     name, m->gen_name, 7 - m->val % 8);
-           if (tag == -1)
-               tag = m->val;
        }
+       fprintf(codefile,
+               "} while(0);\n");
        fprintf (codefile,
-                "p += reallen; len -= reallen; ret += reallen;\n");
+                "p += len; ret += len;\n");
        break;
     }
     case TSequence: {
        Member *m;
-       int tag = -1;
-       int fd_counter = unique_get_next();
-       int fd_counter_inner = unique_get_next();
 
        if (t->members == NULL)
            break;
 
-       fprintf (codefile,
-                "e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,"
-                "&reallen, &l);\n"
-                "FORW;\n"
-                "{\n"
-                "int dce_fix%d;\n"
-                "if((dce_fix%d = fix_dce(reallen, &len)) < 0)\n"
-                "return ASN1_BAD_FORMAT;\n",
-                fd_counter, fd_counter);
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           char *s;
+
+           if (m->ellipsis)
+               continue;
+
+           asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&",
+                     name, m->gen_name);
+           if (s == NULL)
+               errx(1, "malloc");
+           decode_type (s, m->type, m->optional, forwstr);
+           free (s);
+       }
+
+       break;
+    }
+    case TSet: {
+       Member *m;
+       unsigned int memno;
+
+       if(t->members == NULL)
+           break;
 
-       for (m = t->members; m && tag != m->val; m = m->next) {
+       fprintf(codefile, "{\n");
+       fprintf(codefile, "unsigned int members = 0;\n");
+       fprintf(codefile, "while(len > 0) {\n");
+       fprintf(codefile, 
+               "Der_class class;\n"
+               "Der_type type;\n"
+               "int tag;\n"
+               "e = der_get_tag (p, len, &class, &type, &tag, NULL);\n"
+               "if(e) %s;\n", forwstr);
+       fprintf(codefile, "switch (MAKE_TAG(class, type, tag)) {\n");
+       memno = 0;
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
            char *s;
 
+           assert(m->type->type == TTag);
+
+           fprintf(codefile, "case MAKE_TAG(%s, %s, %s):\n",
+                   classname(m->type->tag.tagclass),
+                   is_primitive_type(m->type->subtype->type) ? "PRIM" : "CONS",
+                   valuename(m->type->tag.tagclass, m->type->tag.tagvalue));
+
            asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
-           if (0 && m->type->type == TType){
-               if(m->optional)
-                   fprintf (codefile,
-                            "%s = malloc(sizeof(*%s));\n"
-                            "if(%s == NULL) return ENOMEM;\n", s, s, s);
-               fprintf (codefile, 
-                        "e = decode_seq_%s(p, len, %d, %d, %s, &l);\n",
-                        m->type->symbol->gen_name,
-                        m->val, 
-                        m->optional,
-                        s);
-               if(m->optional)
-                   fprintf (codefile, 
-                            "if (e == ASN1_MISSING_FIELD) {\n"
-                            "free(%s);\n"
-                            "%s = NULL;\n"
-                            "e = l = 0;\n"
-                            "}\n",
-                            s, s);
-         
-               fprintf (codefile, "FORW;\n");
-         
-           }else{
-               fprintf (codefile, "{\n"
-                        "size_t newlen, oldlen;\n\n"
-                        "e = der_match_tag (p, len, ASN1_C_CONTEXT, CONS, %d, &l);\n",
-                        m->val);
-               fprintf (codefile,
-                        "if (e)\n");
-               if(m->optional)
-                   /* XXX should look at e */
-                   fprintf (codefile,
-                            "%s = NULL;\n", s);
-               else
-                   fprintf (codefile,
-                            "return e;\n");
-               fprintf (codefile, 
-                        "else {\n");
-               fprintf (codefile,
-                        "p += l;\n"
-                        "len -= l;\n"
-                        "ret += l;\n"
-                        "e = der_get_length (p, len, &newlen, &l);\n"
-                        "FORW;\n"
-                        "{\n"
-              
-                        "int dce_fix%d;\n"
-                        "oldlen = len;\n"
-                        "if((dce_fix%d = fix_dce(newlen, &len)) < 0)"
-                        "return ASN1_BAD_FORMAT;\n",
-                        fd_counter_inner,
-                        fd_counter_inner);
-               if (m->optional)
-                   fprintf (codefile,
-                            "%s = malloc(sizeof(*%s));\n"
-                            "if(%s == NULL) return ENOMEM;\n", s, s, s);
-               decode_type (s, m->type);
-               fprintf (codefile,
-                        "if(dce_fix%d){\n"
-                        "e = der_match_tag_and_length (p, len, "
-                        "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
-                        "FORW;\n"
-                        "}else \n"
-                        "len = oldlen - newlen;\n"
-                        "}\n"
-                        "}\n",
-                        fd_counter_inner);
-               fprintf (codefile,
-                        "}\n");
-           }
-           if (tag == -1)
-               tag = m->val;
+           if (s == NULL)
+               errx(1, "malloc");
+           if(m->optional)
+               fprintf(codefile, 
+                       "%s = calloc(1, sizeof(*%s));\n"
+                       "if (%s == NULL) { e = ENOMEM; %s; }\n",
+                       s, s, s, forwstr);
+           decode_type (s, m->type, 0, forwstr);
            free (s);
+
+           fprintf(codefile, "members |= (1 << %d);\n", memno);
+           memno++;
+           fprintf(codefile, "break;\n");
        }
-       fprintf(codefile,
-               "if(dce_fix%d){\n"
-               "e = der_match_tag_and_length (p, len, "
-               "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
-               "FORW;\n"
-               "}\n"
-               "}\n",
-               fd_counter);
+       fprintf(codefile, 
+               "default:\n"
+               "return ASN1_MISPLACED_FIELD;\n"
+               "break;\n");
+       fprintf(codefile, "}\n");
+       fprintf(codefile, "}\n");
+       memno = 0;
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           char *s;
 
+           asprintf (&s, "%s->%s", name, m->gen_name);
+           if (s == NULL)
+               errx(1, "malloc");
+           fprintf(codefile, "if((members & (1 << %d)) == 0)\n", memno);
+           if(m->optional)
+               fprintf(codefile, "%s = NULL;\n", s);
+           else if(m->defval)
+               gen_assign_defval(s, m->defval);
+           else
+               fprintf(codefile, "return ASN1_MISSING_FIELD;\n");
+           free(s);
+           memno++;
+       }
+       fprintf(codefile, "}\n");
        break;
     }
+    case TSetOf:
     case TSequenceOf: {
        char *n;
-       int oldret_counter = unique_get_next();
-
-       fprintf (codefile,
-                "e = der_match_tag_and_length (p, len, ASN1_C_UNIV, CONS, UT_Sequence,"
-                "&reallen, &l);\n"
-                "FORW;\n"
-                "if(len < reallen)\n"
-                "return ASN1_OVERRUN;\n"
-                "len = reallen;\n");
 
        fprintf (codefile,
                 "{\n"
                 "size_t origlen = len;\n"
-                "int oldret%d = ret;\n"
+                "size_t oldret = ret;\n"
+                "void *tmp;\n"
                 "ret = 0;\n"
                 "(%s)->len = 0;\n"
                 "(%s)->val = NULL;\n"
                 "while(ret < origlen) {\n"
+                "tmp = realloc((%s)->val, "
+                "    sizeof(*((%s)->val)) * ((%s)->len + 1));\n"
+                "if (tmp == NULL) { %s; }\n"
                 "(%s)->len++;\n"
-                "(%s)->val = realloc((%s)->val, sizeof(*((%s)->val)) * (%s)->len);\n",
-                oldret_counter, name, name, name, name, name, name, name);
+                "(%s)->val = tmp;\n",
+                name, name, name, name, name, forwstr, name, name);
+
        asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
-       decode_type (n, t->subtype);
+       if (n == NULL)
+           errx(1, "malloc");
+       decode_type (n, t->subtype, 0, forwstr);
        fprintf (codefile, 
                 "len = origlen - ret;\n"
                 "}\n"
-                "ret += oldret%d;\n"
-                "}\n",
-                oldret_counter);
+                "ret += oldret;\n"
+                "}\n");
        free (n);
        break;
     }
     case TGeneralizedTime:
-       decode_primitive ("generalized_time", name);
+       decode_primitive ("generalized_time", name, forwstr);
        break;
     case TGeneralString:
-       decode_primitive ("general_string", name);
+       decode_primitive ("general_string", name, forwstr);
        break;
-    case TUTF8String:
-       decode_primitive ("utf8string", name);
-       break;
-    case TNull:
-       fprintf (codefile,
-                "e = decode_nulltype(p, len, &l);\n"
-                "FORW;\n");
-       break;
-    case TApplication:
+    case TTag:{
+       fprintf(codefile, 
+               "{\n"
+               "size_t tagdatalen, oldlen;\n");
+       if(dce_fix)
+           fprintf(codefile, 
+                   "int dce_fix;\n");
+       fprintf(codefile, "e = der_match_tag_and_length(p, len, %s, %s, %s, "
+               "&tagdatalen, &l);\n",
+               classname(t->tag.tagclass),
+               is_primitive_type(t->subtype->type) ? "PRIM" : "CONS",
+               valuename(t->tag.tagclass, t->tag.tagvalue));
+       if(optional) {
+           fprintf(codefile, 
+                   "if(e) {\n"
+                   "%s = NULL;\n"
+                   "} else {\n"
+                    "%s = calloc(1, sizeof(*%s));\n"
+                    "if (%s == NULL) { e = ENOMEM; %s; }\n",
+                    name, name, name, name, forwstr);
+       } else {
+           fprintf(codefile, "if(e) %s;\n", forwstr);
+       }
        fprintf (codefile,
-                "e = der_match_tag_and_length (p, len, ASN1_C_APPL, CONS, %d, "
-                "&reallen, &l);\n"
-                "FORW;\n"
-                "{\n"
-                "int dce_fix;\n"
-                "if((dce_fix = fix_dce(reallen, &len)) < 0)\n"
-                "return ASN1_BAD_FORMAT;\n", 
-                t->application);
-       decode_type (name, t->subtype);
-       fprintf(codefile,
-               "if(dce_fix){\n"
-               "e = der_match_tag_and_length (p, len, "
-               "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
-               "FORW;\n"
-               "}\n"
+                "p += l; len -= l; ret += l;\n"
+                "oldlen = len;\n");
+       if(dce_fix)
+           fprintf (codefile,
+                    "if((dce_fix = _heim_fix_dce(tagdatalen, &len)) < 0)\n"
+                    "{ e = ASN1_BAD_FORMAT; %s; }\n",
+                    forwstr);
+       else
+           fprintf(codefile, 
+                   "if (tagdatalen > len) { e = ASN1_OVERRUN; %s; }\n"
+                   "len = tagdatalen;\n", forwstr);
+       decode_type (name, t->subtype, 0, forwstr);
+       if(dce_fix)
+           fprintf(codefile,
+                   "if(dce_fix){\n"
+                   "e = der_match_tag_and_length (p, len, "
+                   "(Der_class)0,(Der_type)0, UT_EndOfContent, "
+                   "&tagdatalen, &l);\n"
+                   "if(e) %s;\np += l; len -= l; ret += l;\n"
+                   "} else \n", forwstr);
+       fprintf(codefile, 
+               "len = oldlen - tagdatalen;\n");
+       if(optional)
+           fprintf(codefile, 
+                   "}\n");
+       fprintf(codefile, 
                "}\n");
+       break;
+    }
+    case TChoice: {
+       Member *m, *have_ellipsis = NULL;
+       const char *els = "";
 
+       if (t->members == NULL)
+           break;
+
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           const Type *tt = m->type;
+           char *s;
+           Der_class cl;
+           Der_type  ty;
+           unsigned  tag;
+           
+           if (m->ellipsis) {
+               have_ellipsis = m;
+               continue;
+           }
+
+           find_tag(tt, &cl, &ty, &tag);
+
+           fprintf(codefile,
+                   "%sif (der_match_tag(p, len, %s, %s, %s, NULL) == 0) {\n",
+                   els,
+                   classname(cl),
+                   ty ? "CONS" : "PRIM",
+                   valuename(cl, tag));
+           asprintf (&s, "%s(%s)->u.%s", m->optional ? "" : "&",
+                     name, m->gen_name);
+           if (s == NULL)
+               errx(1, "malloc");
+           decode_type (s, m->type, m->optional, forwstr);
+           fprintf(codefile,
+                   "(%s)->element = %s;\n",
+                   name, m->label);
+           free(s);
+           fprintf(codefile,
+                   "}\n");
+           els = "else ";
+       }
+       if (have_ellipsis) {
+           fprintf(codefile,
+                   "else {\n"
+                   "(%s)->u.%s.data = calloc(1, len);\n"
+                   "if ((%s)->u.%s.data == NULL) {\n"
+                   "e = ENOMEM; %s;\n"
+                   "}\n"
+                   "(%s)->u.%s.length = len;\n"
+                   "memcpy((%s)->u.%s.data, p, len);\n"
+                   "(%s)->element = %s;\n"
+                   "p += len;\n"
+                   "ret += len;\n"
+                   "len -= len;\n"
+                   "}\n",
+                   name, have_ellipsis->gen_name,
+                   name, have_ellipsis->gen_name,
+                   forwstr, 
+                   name, have_ellipsis->gen_name,
+                   name, have_ellipsis->gen_name,
+                   name, have_ellipsis->label);
+       } else {
+           fprintf(codefile,
+                   "else {\n"
+                   "e = ASN1_PARSE_ERROR;\n"
+                   "%s;\n"
+                   "}\n",
+                   forwstr);
+       }
        break;
-    case TBoolean:
-       decode_primitive ("boolean", name);
+    }
+    case TUTCTime:
+       decode_primitive ("utctime", name, forwstr);
+       break;
+    case TUTF8String:
+       decode_primitive ("utf8string", name, forwstr);
+       break;
+    case TPrintableString:
+       decode_primitive ("printable_string", name, forwstr);
+       break;
+    case TIA5String:
+       decode_primitive ("ia5_string", name, forwstr);
+       break;
+    case TBMPString:
+       decode_primitive ("bmp_string", name, forwstr);
+       break;
+    case TUniversalString:
+       decode_primitive ("universal_string", name, forwstr);
+       break;
+    case TNull:
+       fprintf (codefile, "/* NULL */\n");
+       break;
+    case TOID:
+       decode_primitive ("oid", name, forwstr);
        break;
     default :
        abort ();
     }
+    return 0;
 }
 
 void
 generate_type_decode (const Symbol *s)
 {
-  unique_reset();
+  int preserve = preserve_type(s->name) ? TRUE : FALSE;
+
   fprintf (headerfile,
           "int    "
           "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
           s->gen_name, s->gen_name);
 
-  fprintf (codefile, "#define FORW "
-          "if(e) goto fail; "
-          "p += l; "
-          "len -= l; "
-          "ret += l\n\n");
-
-
   fprintf (codefile, "int\n"
           "decode_%s(const unsigned char *p,"
           " size_t len, %s *data, size_t *size)\n"
@@ -322,28 +588,45 @@ generate_type_decode (const Symbol *s)
 
   switch (s->type->type) {
   case TInteger:
-  case TUInteger:
   case TBoolean:
   case TOctetString:
   case TOID:
   case TGeneralizedTime:
   case TGeneralString:
   case TUTF8String:
+  case TPrintableString:
+  case TIA5String:
+  case TBMPString:
+  case TUniversalString:
+  case TUTCTime:
   case TNull:
   case TEnumerated:
   case TBitString:
   case TSequence:
   case TSequenceOf:
-  case TApplication:
+  case TSet:
+  case TSetOf:
+  case TTag:
   case TType:
+  case TChoice:
     fprintf (codefile,
             "size_t ret = 0, reallen;\n"
             "size_t l;\n"
-            "int e;\n\n");
+            "int e;\n");
+    if (preserve)
+       fprintf (codefile, "const unsigned char *begin = p;\n");
+
+    fprintf (codefile, "\n");
     fprintf (codefile, "memset(data, 0, sizeof(*data));\n");
     fprintf (codefile, "reallen = 0;\n"); /* hack to avoid `unused variable' */
 
-    decode_type ("data", s->type);
+    decode_type ("data", s->type, 0, "goto fail");
+    if (preserve)
+       fprintf (codefile,
+                "data->_save.data = calloc(1, ret);\n"
+                "if (data->_save.data == NULL) { e = ENOMEM; goto fail; }\n"
+                "data->_save.length = ret;\n"
+                "memcpy(data->_save.data, begin, ret);\n");
     fprintf (codefile, 
             "if(size) *size = ret;\n"
             "return 0;\n");
@@ -358,62 +641,3 @@ generate_type_decode (const Symbol *s)
   }
   fprintf (codefile, "}\n\n");
 }
-
-void
-generate_seq_type_decode (const Symbol *s)
-{
-    fprintf (headerfile,
-            "int decode_seq_%s(const unsigned char *, size_t, int, int, "
-            "%s *, size_t *);\n",
-            s->gen_name, s->gen_name);
-
-    fprintf (codefile, "int\n"
-            "decode_seq_%s(const unsigned char *p, size_t len, int tag, "
-            "int optional, %s *data, size_t *size)\n"
-            "{\n",
-            s->gen_name, s->gen_name);
-
-    fprintf (codefile,
-            "size_t newlen, oldlen;\n"
-            "size_t l, ret = 0;\n"
-            "int e;\n"
-            "int dce_fix;\n");
-    
-    fprintf (codefile,
-            "e = der_match_tag(p, len, ASN1_C_CONTEXT, CONS, tag, &l);\n"
-            "if (e)\n"
-            "return e;\n");
-    fprintf (codefile, 
-            "p += l;\n"
-            "len -= l;\n"
-            "ret += l;\n"
-            "e = der_get_length(p, len, &newlen, &l);\n"
-            "if (e)\n"
-            "return e;\n"
-            "p += l;\n"
-            "len -= l;\n"
-            "ret += l;\n"
-            "oldlen = len;\n"
-            "if ((dce_fix = fix_dce(newlen, &len)) < 0)\n"
-            "return ASN1_BAD_FORMAT;\n"
-            "e = decode_%s(p, len, data, &l);\n"
-            "if (e)\n"
-            "return e;\n"
-            "p += l;\n"
-            "len -= l;\n"
-            "ret += l;\n"
-            "if (dce_fix) {\n"
-            "size_t reallen;\n\n"
-            "e = der_match_tag_and_length(p, len, "
-            "(Der_class)0, (Der_type)0, 0, &reallen, &l);\n"
-            "if (e)\n"
-            "return e;\n"
-            "ret += l;\n"
-            "}\n",
-            s->gen_name);
-    fprintf (codefile, 
-            "if(size) *size = ret;\n"
-            "return 0;\n");
-
-    fprintf (codefile, "}\n\n");
-}
index e77bcc559c5f9059e297123bd0bffd9147ac5aa0..acd058c7dd9f3373c11c9a065f6cdbd8be2797a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen_encode.c,v 1.15 2005/05/29 14:23:01 lha Exp $");
+RCSID("$Id: gen_encode.c,v 1.18 2005/07/13 10:40:23 lha Exp $");
 
 static void
 encode_primitive (const char *typename, const char *name)
 {
     fprintf (codefile,
-            "e = encode_%s(p, len, %s, &l);\n"
-            "BACK;\n",
+            "e = der_put_%s(p, len, %s, &l);\n"
+            "if (e) return e;\np -= l; len -= l; ret += l;\n\n",
             typename,
             name);
 }
 
-static void
+const char *
+classname(Der_class class)
+{
+    const char *cn[] = { "ASN1_C_UNIV", "ASN1_C_APPL",
+                        "ASN1_C_CONTEXT", "ASN1_C_PRIV" };
+    if(class < ASN1_C_UNIV || class > ASN1_C_PRIVATE)
+       return "???";
+    return cn[class];
+}
+
+
+const char *
+valuename(Der_class class, int value)
+{
+    static char s[32];
+    struct { 
+       int value;
+       char *s;
+    } *p, values[] = {
+#define X(Y) { Y, #Y }
+       X(UT_BMPString),
+       X(UT_BitString),
+       X(UT_Boolean),
+       X(UT_EmbeddedPDV),
+       X(UT_Enumerated),
+       X(UT_External),
+       X(UT_GeneralString),
+       X(UT_GeneralizedTime),
+       X(UT_GraphicString),
+       X(UT_IA5String),
+       X(UT_Integer),
+       X(UT_Null),
+       X(UT_NumericString),
+       X(UT_OID),
+       X(UT_ObjectDescriptor),
+       X(UT_OctetString),
+       X(UT_PrintableString),
+       X(UT_Real),
+       X(UT_RelativeOID),
+       X(UT_Sequence),
+       X(UT_Set),
+       X(UT_TeletexString),
+       X(UT_UTCTime),
+       X(UT_UTF8String),
+       X(UT_UniversalString),
+       X(UT_VideotexString),
+       X(UT_VisibleString),
+#undef X
+       { -1, NULL }
+    };
+    if(class == ASN1_C_UNIV) {
+       for(p = values; p->value != -1; p++)
+           if(p->value == value)
+               return p->s;
+    }
+    snprintf(s, sizeof(s), "%d", value);
+    return s;
+}
+
+static int
 encode_type (const char *name, const Type *t)
 {
+    int constructed = 1;
+
     switch (t->type) {
     case TType:
 #if 0
@@ -55,45 +116,60 @@ encode_type (const char *name, const Type *t)
 #endif
        fprintf (codefile,
                 "e = encode_%s(p, len, %s, &l);\n"
-                "BACK;\n",
+                "if (e) return e;\np -= l; len -= l; ret += l;\n\n",
                 t->symbol->gen_name, name);
        break;
     case TInteger:
-       if(t->members == NULL)
-           encode_primitive ("integer", name);
-       else {
+       if(t->members) {
            char *s;
            asprintf(&s, "(const int*)%s", name);
            if(s == NULL)
                errx(1, "out of memory");
            encode_primitive ("integer", s);
            free(s);
-       }
+       } else if (t->range == NULL) {
+           encode_primitive ("heim_integer", name);
+       } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
+           encode_primitive ("integer", name);
+       } else if (t->range->min == 0 && t->range->max == UINT_MAX) {
+           encode_primitive ("unsigned", name);
+       } else if (t->range->min == 0 && t->range->max == INT_MAX) {
+           encode_primitive ("unsigned", name);
+       } else
+           errx(1, "%s: unsupported range %d -> %d", 
+                name, t->range->min, t->range->max);
+       constructed = 0;
        break;
-    case TUInteger:
-       encode_primitive ("unsigned", name);
+    case TBoolean:
+       encode_primitive ("boolean", name);
+       constructed = 0;
        break;
     case TOctetString:
        encode_primitive ("octet_string", name);
-       break;
-    case TOID :
-       encode_primitive ("oid", name);
+       constructed = 0;
        break;
     case TBitString: {
        Member *m;
        int pos;
        int rest;
-       int tag = -1;
 
-       if (t->members == NULL)
+       if (ASN1_TAILQ_EMPTY(t->members)) {
+           encode_primitive("bit_string", name);
+           constructed = 0;
            break;
+       }
 
        fprintf (codefile, "{\n"
                 "unsigned char c = 0;\n");
+       if (!rfc1510_bitstring)
+           fprintf (codefile,
+                    "int bit_set = 0;\n");
+#if 0
        pos = t->members->prev->val;
        /* fix for buggy MIT (and OSF?) code */
        if (pos > 31)
            abort ();
+#endif
        /*
         * It seems that if we do not always set pos to 31 here, the MIT
         * code will do the wrong thing.
@@ -101,139 +177,293 @@ encode_type (const char *name, const Type *t)
         * I hate ASN.1 (and DER), but I hate it even more when everybody
         * has to screw it up differently.
         */
-       pos = 31;
-       rest = 7 - (pos % 8);
+       pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
+       if (rfc1510_bitstring) {
+           if (pos < 31)
+               pos = 31;
+           rest = 7 - (pos % 8);
+       } else
+           rest = 0;
 
-       for (m = t->members->prev; m && tag != m->val; m = m->prev) {
+       ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
            while (m->val / 8 < pos / 8) {
+               if (!rfc1510_bitstring)
+                   fprintf (codefile,
+                            "if (c != 0 || bit_set) {\n");
                fprintf (codefile,
+                        "if (len < 1) return ASN1_OVERFLOW;\n"
                         "*p-- = c; len--; ret++;\n"
                         "c = 0;\n");
+               if (!rfc1510_bitstring)
+                   fprintf (codefile,
+                            "bit_set = 1;\n"
+                            "}\n");
                pos -= 8;
            }
            fprintf (codefile,
-                    "if(%s->%s) c |= 1<<%d;\n", name, m->gen_name,
-                    7 - m->val % 8);
-
-           if (tag == -1)
-               tag = m->val;
+                    "if((%s)->%s) {\n"
+                    "c |= 1<<%d;\n", 
+                    name, m->gen_name, 7 - m->val % 8);
+           if (!rfc1510_bitstring)
+               rest = 7 - m->val % 8;
+           fprintf (codefile,
+                    "}\n");
        }
 
+       if (!rfc1510_bitstring)
+           fprintf (codefile,
+                    "if (c != 0 || bit_set) {\n");
        fprintf (codefile, 
-                "*p-- = c;\n"
+                "if (len < 1) return ASN1_OVERFLOW;\n"
+                "*p-- = c; len--; ret++;\n");
+       if (!rfc1510_bitstring)
+           fprintf (codefile,
+                    "}\n");
+       
+       fprintf (codefile, 
+                "if (len < 1) return ASN1_OVERFLOW;\n"
                 "*p-- = %d;\n"
-                "len -= 2;\n"
-                "ret += 2;\n"
-                "}\n\n"
-                "e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, PRIM,"
-                "UT_BitString, &l);\n"
-                "BACK;\n",
+                "len -= 1;\n"
+                "ret += 1;\n"
+                "}\n\n",
                 rest);
+       constructed = 0;
        break;
     }
     case TEnumerated : {
        encode_primitive ("enumerated", name);
+       constructed = 0;
        break;
     }
+
+    case TSet:
     case TSequence: {
        Member *m;
-       int tag = -1;
-       int oldret_counter = unique_get_next();
 
        if (t->members == NULL)
            break;
-
-       for (m = t->members->prev; m && tag != m->val; m = m->prev) {
+       
+       ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
            char *s;
 
+           if (m->ellipsis)
+               continue;
+
            asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
+           if (s == NULL)
+               errx(1, "malloc");
+           fprintf(codefile, "/* %s */\n", m->name);
            if (m->optional)
                fprintf (codefile,
-                        "if(%s)\n",
+                        "if(%s) ",
                         s);
-#if 1
-           fprintf (codefile, "{\n"
-                    "int oldret%d = ret;\n"
-                    "ret = 0;\n",
-                    oldret_counter);
-#endif
+           else if(m->defval)
+               gen_compare_defval(s + 1, m->defval);
+           fprintf (codefile, "{\n");
+           fprintf (codefile, "size_t oldret = ret;\n");
+           fprintf (codefile, "ret = 0;\n");
            encode_type (s, m->type);
-           fprintf (codefile,
-                    "e = der_put_length_and_tag (p, len, ret, ASN1_C_CONTEXT, CONS, "
-                    "%d, &l);\n"
-                    "BACK;\n",
-                    m->val);
-#if 1
-           fprintf (codefile,
-                    "ret += oldret%d;\n"
-                    "}\n",
-                    oldret_counter);
-#endif
-           if (tag == -1)
-               tag = m->val;
+           fprintf (codefile, "ret += oldret;\n");
+           fprintf (codefile, "}\n");
            free (s);
        }
+       break;
+    }
+    case TSetOf: {
+
+       fprintf(codefile,
+               "{\n"
+               "struct heim_octet_string *val;\n"
+               "size_t elen, totallen = 0;\n"
+               "int eret;\n");
+
+       fprintf(codefile,
+               "val = malloc(sizeof(val[0]) * (%s)->len);\n"
+               "if (val == NULL && (%s)->len != 0) return ENOMEM;\n",
+               name, name);
+
+       fprintf(codefile,
+               "for(i = 0; i < (%s)->len; i++) {\n",
+               name);
+
+       fprintf(codefile,
+               "ASN1_MALLOC_ENCODE(%s, val[i].data, "
+               "val[i].length, &(%s)->val[i], &elen, eret);\n",
+               t->subtype->symbol->gen_name,
+               name);
+
+       fprintf(codefile,
+               "if(eret) {\n"
+               "i--;\n"
+               "while (i >= 0) {\n"
+               "free(val[i].data);\n"
+               "i--;\n"
+               "}\n"
+               "free(val);\n"
+               "return eret;\n"
+               "}\n"
+               "totallen += elen;\n"
+               "}\n");
+
+       fprintf(codefile,
+               "if (totallen > len) {\n"
+               "for (i = 0; i < (%s)->len; i++) {\n"
+               "free(val[i].data);\n"
+               "}\n"
+               "free(val);\n"
+               "return ASN1_OVERFLOW;\n"
+               "}\n",
+               name);
+
+       fprintf(codefile,
+               "qsort(val, (%s)->len, sizeof(val[0]), _heim_der_set_sort);\n",
+               name);
+
        fprintf (codefile,
-                "e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);\n"
-                "BACK;\n");
+                "for(i = (%s)->len - 1; i >= 0; --i) {\n"
+                "p -= val[i].length;\n"
+                "ret += val[i].length;\n"
+                "memcpy(p + 1, val[i].data, val[i].length);\n"
+                "free(val[i].data);\n"
+                "}\n"
+                "free(val);\n"
+                "}\n",
+                name);
        break;
     }
     case TSequenceOf: {
-       int oldret_counter = unique_get_next();
        char *n;
 
        fprintf (codefile,
                 "for(i = (%s)->len - 1; i >= 0; --i) {\n"
-#if 1
-                "int oldret%d = ret;\n"
+                "size_t oldret = ret;\n"
                 "ret = 0;\n",
-#else
-                ,
-#endif
-                name, oldret_counter);
+                name);
        asprintf (&n, "&(%s)->val[i]", name);
+       if (n == NULL)
+           errx(1, "malloc");
        encode_type (n, t->subtype);
        fprintf (codefile,
-#if 1
-                "ret += oldret%d;\n"
-#endif
-                "}\n"
-                "e = der_put_length_and_tag (p, len, ret, ASN1_C_UNIV, CONS, UT_Sequence, &l);\n"
-                "BACK;\n"
-#if 1
-                , oldret_counter
-#endif
-           );
+                "ret += oldret;\n"
+                "}\n");
        free (n);
        break;
     }
     case TGeneralizedTime:
        encode_primitive ("generalized_time", name);
+       constructed = 0;
        break;
     case TGeneralString:
        encode_primitive ("general_string", name);
+       constructed = 0;
+       break;
+    case TTag: {
+       int c = encode_type (name, t->subtype);
+       fprintf (codefile,
+                "e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n"
+                "if (e) return e;\np -= l; len -= l; ret += l;\n\n",
+                classname(t->tag.tagclass),
+                c ? "CONS" : "PRIM", 
+                valuename(t->tag.tagclass, t->tag.tagvalue));
+       break;
+    }
+    case TChoice:{
+       Member *m, *have_ellipsis = NULL;
+       char *s;
+
+       if (t->members == NULL)
+           break;
+
+       fprintf(codefile, "\n");
+
+       asprintf (&s, "(%s)", name);
+       if (s == NULL)
+           errx(1, "malloc");
+       fprintf(codefile, "switch(%s->element) {\n", s);
+
+       ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
+           char *s2;
+
+           if (m->ellipsis) {
+               have_ellipsis = m;
+               continue;
+           }
+
+           fprintf (codefile, "case %s: {", m->label); 
+           asprintf(&s2, "%s(%s)->u.%s", m->optional ? "" : "&", 
+                    s, m->gen_name);
+           if (s2 == NULL)
+               errx(1, "malloc");
+           if (m->optional)
+               fprintf (codefile, "if(%s) {\n", s2);
+           fprintf (codefile, "size_t oldret;\n");
+           fprintf (codefile, "oldret = ret;\n");
+           fprintf (codefile, "ret = 0;\n");
+           constructed = encode_type (s2, m->type);
+           fprintf (codefile, "ret += oldret;\n");
+           if(m->optional)
+               fprintf (codefile, "}\n");
+           fprintf(codefile, "break;\n");
+           fprintf(codefile, "}\n");
+           free (s2);
+       }
+       free (s);
+       if (have_ellipsis) {
+           fprintf(codefile,
+                   "case %s: {\n"
+                   "if (len < (%s)->u.%s.length)\n"
+                   "return ASN1_OVERFLOW;\n"
+                   "p -= (%s)->u.%s.length;\n"
+                   "ret += (%s)->u.%s.length;\n"
+                   "memcpy(p + 1, (%s)->u.%s.data, (%s)->u.%s.length);\n"
+                   "break;\n"
+                   "}\n",
+                   have_ellipsis->label,
+                   name, have_ellipsis->gen_name,
+                   name, have_ellipsis->gen_name,
+                   name, have_ellipsis->gen_name,
+                   name, have_ellipsis->gen_name,
+                   name, have_ellipsis->gen_name);
+       }
+       fprintf(codefile, "};\n");
+       break;
+    }
+    case TOID:
+       encode_primitive ("oid", name);
+       constructed = 0;
+       break;
+    case TUTCTime:
+       encode_primitive ("utctime", name);
+       constructed = 0;
        break;
     case TUTF8String:
        encode_primitive ("utf8string", name);
+       constructed = 0;
        break;
-    case TNull:
-       fprintf (codefile,
-                "e = encode_nulltype(p, len, &l);\n"
-                "BACK;\n");
+    case TPrintableString:
+       encode_primitive ("printable_string", name);
+       constructed = 0;
        break;
-    case TApplication:
-       encode_type (name, t->subtype);
-       fprintf (codefile,
-                "e = der_put_length_and_tag (p, len, ret, ASN1_C_APPL, CONS, %d, &l);\n"
-                "BACK;\n",
-                t->application);
+    case TIA5String:
+       encode_primitive ("ia5_string", name);
+       constructed = 0;
        break;
-    case TBoolean:
-       encode_primitive ("boolean", name);
+    case TBMPString:
+       encode_primitive ("bmp_string", name);
+       constructed = 0;
+       break;
+    case TUniversalString:
+       encode_primitive ("universal_string", name);
+       constructed = 0;
+       break;
+    case TNull:
+       fprintf (codefile, "/* NULL */\n");
+       constructed = 0;
        break;
     default:
        abort ();
     }
+    return constructed;
 }
 
 void
@@ -244,9 +474,6 @@ generate_type_encode (const Symbol *s)
           "encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
           s->gen_name, s->gen_name);
 
-  fprintf (codefile, "#define BACK if (e) return e; p -= l; len -= l; ret += l\n\n");
-
-
   fprintf (codefile, "int\n"
           "encode_%s(unsigned char *p, size_t len,"
           " const %s *data, size_t *size)\n"
@@ -255,20 +482,27 @@ generate_type_encode (const Symbol *s)
 
   switch (s->type->type) {
   case TInteger:
-  case TUInteger:
   case TBoolean:
   case TOctetString:
   case TGeneralizedTime:
   case TGeneralString:
+  case TUTCTime:
   case TUTF8String:
+  case TPrintableString:
+  case TIA5String:
+  case TBMPString:
+  case TUniversalString:
   case TNull:
   case TBitString:
   case TEnumerated:
   case TOID:
   case TSequence:
   case TSequenceOf:
-  case TApplication:
+  case TSet:
+  case TSetOf:
+  case TTag:
   case TType:
+  case TChoice:
     fprintf (codefile,
             "size_t ret = 0;\n"
             "size_t l;\n"
index 9665d074fdaa3f17db72304646e920529fd2c885..36c7474a03abe5122ee7ab5a84897e3bbf2b262c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen_free.c,v 1.12 2003/10/03 00:28:08 lha Exp $");
+RCSID("$Id: gen_free.c,v 1.14 2005/07/25 21:28:29 lha Exp $");
 
 static void
 free_primitive (const char *typename, const char *name)
@@ -42,92 +42,140 @@ free_primitive (const char *typename, const char *name)
 }
 
 static void
-free_type (const char *name, const Type *t)
+free_type (const char *name, const Type *t, int preserve)
 {
-  switch (t->type) {
-  case TType:
+    switch (t->type) {
+    case TType:
 #if 0
-      free_type (name, t->symbol->type);
+       free_type (name, t->symbol->type, preserve);
 #endif
-      fprintf (codefile, "free_%s(%s);\n", t->symbol->gen_name, name);
-      break;
-  case TInteger:
-  case TUInteger:
-  case TBoolean:
-  case TEnumerated :
-      break;
-  case TOctetString:
-      free_primitive ("octet_string", name);
-      break;
-  case TOID :
-      free_primitive ("oid", name);
-      break;
-  case TBitString: {
-      break;
-  }
-  case TSequence: {
-      Member *m;
-      int tag = -1;
+       fprintf (codefile, "free_%s(%s);\n", t->symbol->gen_name, name);
+       break;
+    case TInteger:
+       if (t->range == NULL && t->members == NULL) {
+           free_primitive ("heim_integer", name);
+           break;
+       }
+    case TBoolean:
+    case TEnumerated :
+    case TNull:
+    case TGeneralizedTime:
+    case TUTCTime:
+       break;
+    case TBitString:
+       if (ASN1_TAILQ_EMPTY(t->members))
+           free_primitive("bit_string", name);
+       break;
+    case TOctetString:
+       free_primitive ("octet_string", name);
+       break;
+    case TChoice:
+    case TSet:
+    case TSequence: {
+       Member *m, *have_ellipsis = NULL;
 
-      if (t->members == NULL)
-         break;
+       if (t->members == NULL)
+           break;
+
+       if ((t->type == TSequence || t->type == TChoice) && preserve)
+           fprintf(codefile, "free_octet_string(&data->_save);\n");
+
+       if(t->type == TChoice)
+           fprintf(codefile, "switch((%s)->element) {\n", name);
       
-      for (m = t->members; m && tag != m->val; m = m->next) {
-         char *s;
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           char *s;
 
-         asprintf (&s, "%s(%s)->%s",
-                   m->optional ? "" : "&", name, m->gen_name);
-         if(m->optional)
-             fprintf(codefile, "if(%s) {\n", s);
-         free_type (s, m->type);
-         if(m->optional)
-             fprintf(codefile, 
-                     "free(%s);\n"
-                     "%s = NULL;\n"
-                     "}\n", s, s);
-         if (tag == -1)
-             tag = m->val;
-         free (s);
-      }
-      break;
-  }
-  case TSequenceOf: {
-      char *n;
+           if (m->ellipsis){
+               have_ellipsis = m;
+               continue;
+           }
 
-      fprintf (codefile, "while((%s)->len){\n", name);
-      asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
-      free_type(n, t->subtype);
-      fprintf(codefile, 
-             "(%s)->len--;\n"
-             "}\n",
-             name);
-      fprintf(codefile,
-             "free((%s)->val);\n"
-             "(%s)->val = NULL;\n", name, name);
-      free(n);
-      break;
-  }
-  case TGeneralizedTime:
-      break;
-  case TGeneralString:
-      free_primitive ("general_string", name);
-      break;
-  case TUTF8String:
-      free_primitive ("utf8string", name);
-      break;
-  case TNull:
-      break;
-  case TApplication:
-      free_type (name, t->subtype);
-      break;
-  default :
-      abort ();
-  }
+           if(t->type == TChoice)
+               fprintf(codefile, "case %s:\n", m->label);
+           asprintf (&s, "%s(%s)->%s%s",
+                     m->optional ? "" : "&", name, 
+                     t->type == TChoice ? "u." : "", m->gen_name);
+           if (s == NULL)
+               errx(1, "malloc");
+           if(m->optional)
+               fprintf(codefile, "if(%s) {\n", s);
+           free_type (s, m->type, FALSE);
+           if(m->optional)
+               fprintf(codefile, 
+                       "free(%s);\n"
+                       "%s = NULL;\n"
+                       "}\n",s, s);
+           free (s);
+           if(t->type == TChoice)
+               fprintf(codefile, "break;\n");
+       }
+       
+       if(t->type == TChoice) {
+           if (have_ellipsis)
+               fprintf(codefile,
+                       "case %s:\n"
+                       "free_octet_string(&(%s)->u.%s);\n"
+                       "break;",
+                       have_ellipsis->label,
+                       name, have_ellipsis->gen_name);
+           fprintf(codefile, "}\n");
+       }
+       break;
+    }
+    case TSetOf:
+    case TSequenceOf: {
+       char *n;
+
+       fprintf (codefile, "while((%s)->len){\n", name);
+       asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
+       if (n == NULL)
+           errx(1, "malloc");
+       free_type(n, t->subtype, FALSE);
+       fprintf(codefile, 
+               "(%s)->len--;\n"
+               "}\n",
+               name);
+       fprintf(codefile,
+               "free((%s)->val);\n"
+               "(%s)->val = NULL;\n", name, name);
+       free(n);
+       break;
+    }
+    case TGeneralString:
+       free_primitive ("general_string", name);
+       break;
+    case TUTF8String:
+       free_primitive ("utf8string", name);
+       break;
+    case TPrintableString:
+       free_primitive ("printable_string", name);
+       break;
+    case TIA5String:
+       free_primitive ("ia5_string", name);
+       break;
+    case TBMPString:
+       free_primitive ("bmp_string", name);
+       break;
+    case TUniversalString:
+       free_primitive ("universal_string", name);
+       break;
+    case TTag:
+       free_type (name, t->subtype, preserve);
+       break;
+    case TOID :
+       free_primitive ("oid", name);
+       break;
+    default :
+       abort ();
+    }
 }
 
 void
 generate_type_free (const Symbol *s)
 {
+  int preserve = preserve_type(s->name) ? TRUE : FALSE;
+
   fprintf (headerfile,
           "void   free_%s  (%s *);\n",
           s->gen_name, s->gen_name);
@@ -137,7 +185,7 @@ generate_type_free (const Symbol *s)
           "{\n",
           s->gen_name, s->gen_name);
 
-  free_type ("data", s->type);
+  free_type ("data", s->type, preserve);
   fprintf (codefile, "}\n\n");
 }
 
index 6ab4725502b3696e1694b6e34fecbf4239a41cad..2f3e283ad63c0f64821b61c2a963decb2e588d04 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997, 1999, 2000, 2003 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen_glue.c,v 1.8 2005/04/25 18:07:07 lha Exp $");
+RCSID("$Id: gen_glue.c,v 1.9 2005/07/12 06:27:29 lha Exp $");
 
 static void
-generate_2int (const Symbol *s)
+generate_2int (const Type *t, const char *gen_name)
 {
-    Type *t = s->type;
     Member *m;
-    int tag = -1;
 
     fprintf (headerfile,
             "unsigned %s2int(%s);\n",
-            s->gen_name, s->gen_name);
+            gen_name, gen_name);
 
     fprintf (codefile,
             "unsigned %s2int(%s f)\n"
             "{\n"
             "unsigned r = 0;\n",
-            s->gen_name, s->gen_name);
+            gen_name, gen_name);
 
-    for (m = t->members; m && m->val != tag; m = m->next) {
+    ASN1_TAILQ_FOREACH(m, t->members, members) {
        fprintf (codefile, "if(f.%s) r |= (1U << %d);\n",
                 m->gen_name, m->val);
-       
-       if (tag == -1)
-           tag = m->val;
     }
     fprintf (codefile, "return r;\n"
             "}\n\n");
 }
 
 static void
-generate_int2 (const Symbol *s)
+generate_int2 (const Type *t, const char *gen_name)
 {
-    Type *t = s->type;
     Member *m;
-    int tag = -1;
 
     fprintf (headerfile,
             "%s int2%s(unsigned);\n",
-            s->gen_name, s->gen_name);
+            gen_name, gen_name);
 
     fprintf (codefile,
             "%s int2%s(unsigned n)\n"
             "{\n"
             "\t%s flags;\n\n",
-            s->gen_name, s->gen_name, s->gen_name);
+            gen_name, gen_name, gen_name);
 
-    for (m = t->members; m && m->val != tag; m = m->next) {
-       fprintf (codefile, "\tflags.%s = (n >> %d) & 1;\n",
-                m->gen_name, m->val);
-       
-       if (tag == -1)
-           tag = m->val;
+    if(t->members) {
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
+           fprintf (codefile, "\tflags.%s = (n >> %d) & 1;\n",
+                    m->gen_name, m->val);
+       }
     }
     fprintf (codefile, "\treturn flags;\n"
             "}\n\n");
@@ -96,28 +88,24 @@ generate_int2 (const Symbol *s)
  */
 
 static void
-generate_units (const Symbol *s)
+generate_units (const Type *t, const char *gen_name)
 {
-    Type *t = s->type;
     Member *m;
-    int tag = -1;
 
     fprintf (headerfile,
             "const struct units * asn1_%s_units(void);",
-            s->gen_name);
+            gen_name);
 
     fprintf (codefile,
             "static struct units %s_units[] = {\n",
-            s->gen_name);
+            gen_name);
 
-    if(t->members)
-       for (m = t->members->prev; m && m->val != tag; m = m->prev) {
+    if(t->members) {
+       ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
            fprintf (codefile,
                     "\t{\"%s\",\t1U << %d},\n", m->gen_name, m->val);
-           
-           if (tag == -1)
-               tag = m->val;
        }
+    }
 
     fprintf (codefile,
             "\t{NULL,\t0}\n"
@@ -127,19 +115,24 @@ generate_units (const Symbol *s)
             "const struct units * asn1_%s_units(void){\n"
             "return %s_units;\n"
             "}\n\n",
-            s->gen_name, s->gen_name);
+            gen_name, gen_name);
 
 
 }
 
 void
-generate_glue (const Symbol *s)
+generate_glue (const Type *t, const char *gen_name)
 {
-    switch(s->type->type) {
+    switch(t->type) {
+    case TTag:
+       generate_glue(t->subtype, gen_name);
+       break;
     case TBitString :
-       generate_2int (s);
-       generate_int2 (s);
-       generate_units (s);
+       if (!ASN1_TAILQ_EMPTY(t->members)) {
+           generate_2int (t, gen_name);
+           generate_int2 (t, gen_name);
+           generate_units (t, gen_name);
+       }
        break;
     default :
        break;
index c6ea0f701ab3aa1b4396cbbf13a0d3c6fa0dd9b6..aed49e89c3d5cc39a8e04dbdfdf593813b612899 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "gen_locl.h"
 
-RCSID("$Id: gen_length.c,v 1.14 2004/01/19 17:54:33 lha Exp $");
+RCSID("$Id: gen_length.c,v 1.18 2005/07/19 18:01:59 lha Exp $");
 
 static void
 length_primitive (const char *typename,
@@ -43,7 +43,22 @@ length_primitive (const char *typename,
     fprintf (codefile, "%s += length_%s(%s);\n", variable, typename, name);
 }
 
-static void
+static size_t
+length_tag(unsigned int tag)
+{
+    size_t len = 0;
+    
+    if(tag <= 30)
+       return 1;
+    while(tag) {
+       tag /= 128;
+       len++;
+    }
+    return len + 1;
+}
+
+
+static int
 length_type (const char *name, const Type *t, const char *variable)
 {
     switch (t->type) {
@@ -55,19 +70,28 @@ length_type (const char *name, const Type *t, const char *variable)
                 variable, t->symbol->gen_name, name);
        break;
     case TInteger:
-        if(t->members == NULL)
-            length_primitive ("integer", name, variable);
-        else {
-            char *s;
-            asprintf(&s, "(const int*)%s", name);
-            if(s == NULL)
+       if(t->members) {
+           char *s;
+           asprintf(&s, "(const int*)%s", name);
+           if(s == NULL)
                errx (1, "out of memory");
-            length_primitive ("integer", s, variable);
-            free(s);
-        }
+           length_primitive ("integer", s, variable);
+           free(s);
+       } else if (t->range == NULL) {
+           length_primitive ("heim_integer", name, variable);
+       } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
+           length_primitive ("integer", name, variable);
+       } else if (t->range->min == 0 && t->range->max == UINT_MAX) {
+           length_primitive ("unsigned", name, variable);
+       } else if (t->range->min == 0 && t->range->max == INT_MAX) {
+           length_primitive ("unsigned", name, variable);
+       } else
+           errx(1, "%s: unsupported range %d -> %d", 
+                name, t->range->min, t->range->max);
+
        break;
-    case TUInteger:
-       length_primitive ("unsigned", name, variable);
+    case TBoolean:
+       fprintf (codefile, "%s += 1;\n", variable);
        break;
     case TEnumerated :
        length_primitive ("enumerated", name, variable);
@@ -75,71 +99,112 @@ length_type (const char *name, const Type *t, const char *variable)
     case TOctetString:
        length_primitive ("octet_string", name, variable);
        break;
-    case TOID :
-       length_primitive ("oid", name, variable);
-       break;
     case TBitString: {
-       /*
-        * XXX - Hope this is correct
-        * look at TBitString case in `encode_type'
-        */
-       fprintf (codefile, "%s += 7;\n", variable);
+       if (ASN1_TAILQ_EMPTY(t->members))
+           length_primitive("bit_string", name, variable);
+       else {
+           if (!rfc1510_bitstring) {
+               Member *m;
+               int pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
+
+               fprintf(codefile,
+                       "do {\n");
+               ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
+                   while (m->val / 8 < pos / 8) {
+                       pos -= 8;
+                   }
+                   fprintf (codefile,
+                            "if((%s)->%s) { %s += %d; break; }\n",
+                            name, m->gen_name, variable, (pos + 8) / 8);
+               }
+               fprintf(codefile,
+                       "} while(0);\n");
+               fprintf (codefile, "%s += 1;\n", variable);
+           } else {
+               fprintf (codefile, "%s += 5;\n", variable);
+           }
+       }
        break;
     }
-    case TSequence: {
-       Member *m;
-       int tag = -1;
-       int oldret_counter = unique_get_next();
+    case TSet:
+    case TSequence:
+    case TChoice: {
+       Member *m, *have_ellipsis = NULL;
 
        if (t->members == NULL)
            break;
       
-       for (m = t->members; m && tag != m->val; m = m->next) {
+       if(t->type == TChoice)
+           fprintf (codefile, "switch((%s)->element) {\n", name);
+
+       ASN1_TAILQ_FOREACH(m, t->members, members) {
            char *s;
+           
+           if (m->ellipsis) {
+               have_ellipsis = m;
+               continue;
+           }
+
+           if(t->type == TChoice)
+               fprintf(codefile, "case %s:\n", m->label);
 
-           asprintf (&s, "%s(%s)->%s",
-                     m->optional ? "" : "&", name, m->gen_name);
+           asprintf (&s, "%s(%s)->%s%s",
+                     m->optional ? "" : "&", name, 
+                     t->type == TChoice ? "u." : "", m->gen_name);
+           if (s == NULL)
+               errx(1, "malloc");
            if (m->optional)
                fprintf (codefile, "if(%s)", s);
+           else if(m->defval)
+               gen_compare_defval(s + 1, m->defval);
            fprintf (codefile, "{\n"
-                    "int oldret%d = %s;\n"
-                    "%s = 0;\n", oldret_counter, variable, variable);
+                    "size_t oldret = %s;\n"
+                    "%s = 0;\n", variable, variable);
            length_type (s, m->type, "ret");
-           fprintf (codefile, "%s += 1 + length_len(%s) + oldret%d;\n",
-                    variable, variable, oldret_counter);
+           fprintf (codefile, "ret += oldret;\n");
            fprintf (codefile, "}\n");
-           if (tag == -1)
-               tag = m->val;
            free (s);
+           if(t->type == TChoice)
+               fprintf(codefile, "break;\n");
+       }
+       if(t->type == TChoice) {
+           if (have_ellipsis)
+               fprintf(codefile,
+                       "case %s:\n"
+                       "ret += (%s)->u.%s.length;\n"
+                       "break;\n",
+                       have_ellipsis->label,
+                       name,
+                       have_ellipsis->gen_name);
+           fprintf (codefile, "}\n"); /* switch */
        }
-       fprintf (codefile,
-                "%s += 1 + length_len(%s);\n", variable, variable);
        break;
     }
+    case TSetOf:
     case TSequenceOf: {
        char *n;
-       int oldret_counter = unique_get_next();
-       int oldret_counter_inner = unique_get_next();
 
        fprintf (codefile,
                 "{\n"
-                "int oldret%d = %s;\n"
+                "int oldret = %s;\n"
                 "int i;\n"
                 "%s = 0;\n",
-                oldret_counter, variable, variable);
+                variable, variable);
 
        fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
-       fprintf (codefile, "int oldret%d = %s;\n"
-                "%s = 0;\n", oldret_counter_inner, variable, variable);
+       fprintf (codefile, "int oldret = %s;\n"
+                "%s = 0;\n", variable, variable);
        asprintf (&n, "&(%s)->val[i]", name);
+       if (n == NULL)
+           errx(1, "malloc");
        length_type(n, t->subtype, variable);
-       fprintf (codefile, "%s += oldret%d;\n",
-                variable, oldret_counter_inner);
+       fprintf (codefile, "%s += oldret;\n",
+                variable);
        fprintf (codefile, "}\n");
 
        fprintf (codefile,
-                "%s += 1 + length_len(%s) + oldret%d;\n"
-                "}\n", variable, variable, oldret_counter);
+                "%s += oldret;\n"
+                "}\n", variable);
        free(n);
        break;
     }
@@ -149,28 +214,44 @@ length_type (const char *name, const Type *t, const char *variable)
     case TGeneralString:
        length_primitive ("general_string", name, variable);
        break;
+    case TUTCTime:
+       length_primitive ("utctime", name, variable);
+       break;
     case TUTF8String:
        length_primitive ("utf8string", name, variable);
        break;
+    case TPrintableString:
+       length_primitive ("printable_string", name, variable);
+       break;
+    case TIA5String:
+       length_primitive ("ia5_string", name, variable);
+       break;
+    case TBMPString:
+       length_primitive ("bmp_string", name, variable);
+       break;
+    case TUniversalString:
+       length_primitive ("universal_string", name, variable);
+       break;
     case TNull:
-       fprintf (codefile, "%s += length_nulltype();\n", variable);
+       fprintf (codefile, "/* NULL */\n");
        break;
-    case TApplication:
+    case TTag:
        length_type (name, t->subtype, variable);
-       fprintf (codefile, "ret += 1 + length_len (ret);\n");
+       fprintf (codefile, "ret += %lu + length_len (ret);\n", 
+                (unsigned long)length_tag(t->tag.tagvalue));
        break;
-    case TBoolean:
-       length_primitive ("boolean", name, variable);
+    case TOID:
+       length_primitive ("oid", name, variable);
        break;
     default :
        abort ();
     }
+    return 0;
 }
 
 void
 generate_type_length (const Symbol *s)
 {
-  unique_reset();
   fprintf (headerfile,
           "size_t length_%s(const %s *);\n",
           s->gen_name, s->gen_name);
index adaf8539f591baf3ea3c0fc9a8a7e1f9459da240..a03097a68eb76fbd269cf9a46285647751ef1b3c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: gen_locl.h,v 1.10 2005/06/16 19:58:58 lha Exp $ */
+/* $Id: gen_locl.h,v 1.12 2005/07/12 06:27:30 lha Exp $ */
 
 #ifndef __GEN_LOCL_H__
 #define __GEN_LOCL_H__
@@ -51,6 +51,8 @@
 #include <roken.h>
 #include "hash.h"
 #include "symbol.h"
+#include "asn1-common.h"
+#include "der.h"
 
 void generate_type (const Symbol *);
 void generate_constant (const Symbol *);
@@ -61,10 +63,14 @@ void generate_type_free (const Symbol *s);
 void generate_type_length (const Symbol *s);
 void generate_type_copy (const Symbol *s);
 void generate_type_maybe (const Symbol *s);
-void generate_glue (const Symbol *s);
+void generate_glue (const Type *, const char*);
+
+const char *classname(Der_class);
+const char *valuename(Der_class class, int);
+
+void gen_compare_defval(const char *var, struct value *val);
+void gen_assign_defval(const char *var, struct value *val);
 
-void unique_reset(void);
-int unique_get_next(void);
 
 void init_generate (const char *filename, const char *basename);
 const char *get_filename (void);
@@ -72,6 +78,12 @@ void close_generate(void);
 void add_import(const char *module);
 int yyparse(void);
 
+int preserve_type(const char *);
+
 extern FILE *headerfile, *codefile, *logfile;
+extern int dce_fix;
+extern int rfc1510_bitstring;
+
+extern int error_flag;
 
 #endif /* __GEN_LOCL_H__ */
index 54be897c019a3fb055c1025b186012d224d393c7..7926541c193ac771ddc478ed9605ad1e9614d566 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "gen_locl.h"
 
-RCSID("$Id: hash.c,v 1.9 2005/01/08 22:55:26 lha Exp $");
+RCSID("$Id: hash.c,v 1.10 2005/07/12 06:27:30 lha Exp $");
 
 static Hashentry *_search(Hashtab * htab,      /* The hash table */
                          void *ptr);   /* And key */
diff --git a/source4/heimdal/lib/asn1/heim_asn1.h b/source4/heimdal/lib/asn1/heim_asn1.h
new file mode 100644 (file)
index 0000000..99f8e95
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2003-2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * 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 above 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. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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. 
+ */
+
+#ifndef __HEIM_ANY_H__
+#define __HEIM_ANY_H__ 1
+
+typedef struct heim_octet_string heim_any;
+typedef struct heim_octet_string heim_any_set;
+
+int    encode_heim_any(unsigned char *, size_t, const heim_any *, size_t *);
+int    decode_heim_any(const unsigned char *, size_t, heim_any *, size_t *);
+void   free_heim_any(heim_any *);
+size_t length_heim_any(const heim_any *);
+int    copy_heim_any(const heim_any *, heim_any *);
+
+int    encode_heim_any_set(unsigned char *, size_t,
+                           const heim_any_set *, size_t *);
+int    decode_heim_any_set(const unsigned char *, size_t,
+                           heim_any_set *,size_t *);
+void   free_heim_any_set(heim_any_set *);
+size_t length_heim_any_set(const heim_any_set *);
+int    copy_heim_any_set(const heim_any_set *, heim_any_set *);
+int    heim_any_cmp(const heim_any_set *, const heim_any_set *);
+
+#endif /* __HEIM_ANY_H__ */
index 802c0a4c7794d6b511c3251cb14bcea2ff7ca90e..dd49baf0ffb2e6580bafa44c7eabaedb997a0917 100644 (file)
@@ -1,4 +1,4 @@
--- $Id: k5.asn1,v 1.43 2005/06/17 04:58:59 lha Exp $
+-- $Id: k5.asn1,v 1.45 2005/07/13 05:29:49 lha Exp $
 
 KERBEROS5 DEFINITIONS ::=
 BEGIN
@@ -11,7 +11,11 @@ NAME-TYPE ::= INTEGER {
        KRB5_NT_SRV_XHST(4),    -- Service with host as remaining components
        KRB5_NT_UID(5),         -- Unique ID
        KRB5_NT_X500_PRINCIPAL(6), -- PKINIT
-       KRB5_NT_ENTERPRISE(10)  -- May be mapped to principal name
+       KRB5_NT_SMTP_NAME(7),   -- Name in form of SMTP email name
+       KRB5_NT_ENTERPRISE_PRINCIPAL(10), -- Windows 2000 UPN
+       KRB5_NT_ENT_PRINCIPAL_AND_ID(-130), -- Windows 2000 UPN and SID
+       KRB5_NT_MS_PRINCIPAL(-128), -- NT 4 style name
+       KRB5_NT_MS_PRINCIPAL_AND_ID(-129) -- NT style name and SID
 }
 
 -- message types
@@ -49,6 +53,7 @@ PADATA-TYPE ::= INTEGER {
        KRB5-PADATA-SAM-RESPONSE(13), -- (sam/otp)
        KRB5-PADATA-PK-AS-REQ-19(14), -- (PKINIT-19)
        KRB5-PADATA-PK-AS-REP-19(15), -- (PKINIT-19)
+       KRB5-PADATA-PK-AS-REQ-WIN(15), -- (PKINIT - old number)
        KRB5-PADATA-PK-AS-REQ(16), -- (PKINIT-25)
        KRB5-PADATA-PK-AS-REP(17), -- (PKINIT-25)
        KRB5-PADATA-ETYPE-INFO2(19),
@@ -58,7 +63,6 @@ PADATA-TYPE ::= INTEGER {
        KRB5-PADATA-SAM-ETYPE-INFO(23),
        KRB5-PADATA-SERVER-REFERRAL(25),
        KRB5-PADATA-TD-KRB-PRINCIPAL(102),      -- PrincipalName
-       KRB5-PADATA-TD-KRB-REALM(103),          -- Realm
        KRB5-PADATA-PK-TD-TRUSTED-CERTIFIERS(104), -- PKINIT
        KRB5-PADATA-PK-TD-CERTIFICATE-INDEX(105), -- PKINIT
        KRB5-PADATA-TD-APP-DEFINED-ERROR(106),  -- application specific
@@ -137,9 +141,13 @@ ENCTYPE ::= INTEGER {
        ETYPE_DES3_CBC_NONE_CMS(-0x100a)
 }
 
+
+
+
 -- this is sugar to make something ASN1 does not have: unsigned
 
-UNSIGNED ::= INTEGER (0..4294967295)
+krb5uint32 ::= INTEGER (0..4294967295)
+krb5int32 ::= INTEGER (-2147483648..2147483647)
 
 KerberosString  ::= GeneralString
 
@@ -156,14 +164,14 @@ Principal ::= SEQUENCE {
 }
 
 HostAddress ::= SEQUENCE  {
-       addr-type[0]            INTEGER,
+       addr-type[0]            krb5int32,
        address[1]              OCTET STRING
 }
 
 -- This is from RFC1510.
 --
 -- HostAddresses ::= SEQUENCE OF SEQUENCE {
---     addr-type[0]            INTEGER,
+--     addr-type[0]            krb5int32,
 --     address[1]              OCTET STRING
 -- }
 
@@ -174,7 +182,7 @@ HostAddresses ::= SEQUENCE OF HostAddress
 KerberosTime ::= GeneralizedTime -- Specifying UTC time zone (Z)
 
 AuthorizationData ::= SEQUENCE OF SEQUENCE {
-       ad-type[0]              INTEGER,
+       ad-type[0]              krb5int32,
        ad-data[1]              OCTET STRING
 }
 
@@ -243,23 +251,23 @@ LastReq ::= SEQUENCE OF SEQUENCE {
 
 EncryptedData ::= SEQUENCE {
        etype[0]                ENCTYPE, -- EncryptionType
-       kvno[1]                 INTEGER OPTIONAL,
+       kvno[1]                 krb5int32 OPTIONAL,
        cipher[2]               OCTET STRING -- ciphertext
 }
 
 EncryptionKey ::= SEQUENCE {
-       keytype[0]              INTEGER,
+       keytype[0]              krb5int32,
        keyvalue[1]             OCTET STRING
 }
 
 -- encoded Transited field
 TransitedEncoding ::= SEQUENCE {
-       tr-type[0]              INTEGER, -- must be registered
+       tr-type[0]              krb5int32, -- must be registered
        contents[1]             OCTET STRING
 }
 
 Ticket ::= [APPLICATION 1] SEQUENCE {
-       tkt-vno[0]              INTEGER,
+       tkt-vno[0]              krb5int32,
        realm[1]                Realm,
        sname[2]                PrincipalName,
        enc-part[3]             EncryptedData
@@ -285,14 +293,14 @@ Checksum ::= SEQUENCE {
 }
 
 Authenticator ::= [APPLICATION 2] SEQUENCE    {
-       authenticator-vno[0]    INTEGER,
+       authenticator-vno[0]    krb5int32,
        crealm[1]               Realm,
        cname[2]                PrincipalName,
        cksum[3]                Checksum OPTIONAL,
-       cusec[4]                INTEGER,
+       cusec[4]                krb5int32,
        ctime[5]                KerberosTime,
        subkey[6]               EncryptionKey OPTIONAL,
-       seq-number[7]           UNSIGNED OPTIONAL,
+       seq-number[7]           krb5uint32 OPTIONAL,
        authorization-data[8]   AuthorizationData OPTIONAL
        }
 
@@ -305,7 +313,7 @@ PA-DATA ::= SEQUENCE {
 ETYPE-INFO-ENTRY ::= SEQUENCE {
        etype[0]                ENCTYPE,
        salt[1]                 OCTET STRING OPTIONAL,
-       salttype[2]             INTEGER OPTIONAL
+       salttype[2]             krb5int32 OPTIONAL
 }
 
 ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY
@@ -320,6 +328,13 @@ ETYPE-INFO2 ::= SEQUENCE OF ETYPE-INFO2-ENTRY
 
 METHOD-DATA ::= SEQUENCE OF PA-DATA
 
+TypedData ::=   SEQUENCE {
+       data-type[0]            krb5int32,
+       data-value[1]           OCTET STRING OPTIONAL
+}
+
+TYPED-DATA ::= SEQUENCE OF TypedData
+
 KDC-REQ-BODY ::= SEQUENCE {
        kdc-options[0]          KDCOptions,
        cname[1]                PrincipalName OPTIONAL, -- Used only in AS-REQ
@@ -329,7 +344,7 @@ KDC-REQ-BODY ::= SEQUENCE {
        from[4]                 KerberosTime OPTIONAL,
        till[5]                 KerberosTime OPTIONAL,
        rtime[6]                KerberosTime OPTIONAL,
-       nonce[7]                INTEGER,
+       nonce[7]                krb5int32,
        etype[8]                SEQUENCE OF ENCTYPE, -- EncryptionType,
                                        -- in preference order
        addresses[9]            HostAddresses OPTIONAL,
@@ -339,7 +354,7 @@ KDC-REQ-BODY ::= SEQUENCE {
 }
 
 KDC-REQ ::= SEQUENCE {
-       pvno[1]                 INTEGER,
+       pvno[1]                 krb5int32,
        msg-type[2]             MESSAGE-TYPE,
        padata[3]               METHOD-DATA OPTIONAL,
        req-body[4]             KDC-REQ-BODY
@@ -353,7 +368,7 @@ TGS-REQ ::= [APPLICATION 12] KDC-REQ
 
 PA-ENC-TS-ENC ::= SEQUENCE {
        patimestamp[0]          KerberosTime, -- client's time
-       pausec[1]               INTEGER OPTIONAL
+       pausec[1]               krb5int32 OPTIONAL
 }
 
 -- draft-brezak-win2k-krb-authz-01
@@ -362,8 +377,11 @@ PA-PAC-REQUEST ::= SEQUENCE {
                                        -- should be included or not
 }
 
+-- PacketCable provisioning server location, PKT-SP-SEC-I09-030728.pdf
+PROV-SRV-LOCATION ::= GeneralString
+
 KDC-REP ::= SEQUENCE {
-       pvno[0]                 INTEGER,
+       pvno[0]                 krb5int32,
        msg-type[1]             MESSAGE-TYPE,
        padata[2]               METHOD-DATA OPTIONAL,
        crealm[3]               Realm,
@@ -378,7 +396,7 @@ TGS-REP ::= [APPLICATION 13] KDC-REP
 EncKDCRepPart ::= SEQUENCE {
        key[0]                  EncryptionKey,
        last-req[1]             LastReq,
-       nonce[2]                INTEGER,
+       nonce[2]                krb5int32,
        key-expiration[3]       KerberosTime OPTIONAL,
        flags[4]                TicketFlags,
        authtime[5]             KerberosTime,
@@ -394,7 +412,7 @@ EncASRepPart ::= [APPLICATION 25] EncKDCRepPart
 EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
 
 AP-REQ ::= [APPLICATION 14] SEQUENCE {
-       pvno[0]                 INTEGER,
+       pvno[0]                 krb5int32,
        msg-type[1]             MESSAGE-TYPE,
        ap-options[2]           APOptions,
        ticket[3]               Ticket,
@@ -402,50 +420,50 @@ AP-REQ ::= [APPLICATION 14] SEQUENCE {
 }
 
 AP-REP ::= [APPLICATION 15] SEQUENCE {
-       pvno[0]                 INTEGER,
+       pvno[0]                 krb5int32,
        msg-type[1]             MESSAGE-TYPE,
        enc-part[2]             EncryptedData
 }
 
 EncAPRepPart ::= [APPLICATION 27]     SEQUENCE {
        ctime[0]                KerberosTime,
-       cusec[1]                INTEGER,
+       cusec[1]                krb5int32,
        subkey[2]               EncryptionKey OPTIONAL,
-       seq-number[3]           UNSIGNED OPTIONAL
+       seq-number[3]           krb5uint32 OPTIONAL
 }
 
 KRB-SAFE-BODY ::= SEQUENCE {
        user-data[0]            OCTET STRING,
        timestamp[1]            KerberosTime OPTIONAL,
-       usec[2]                 INTEGER OPTIONAL,
-       seq-number[3]           UNSIGNED OPTIONAL,
+       usec[2]                 krb5int32 OPTIONAL,
+       seq-number[3]           krb5uint32 OPTIONAL,
        s-address[4]            HostAddress OPTIONAL,
        r-address[5]            HostAddress OPTIONAL
 }
 
 KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
-       pvno[0]                 INTEGER,
+       pvno[0]                 krb5int32,
        msg-type[1]             MESSAGE-TYPE,
        safe-body[2]            KRB-SAFE-BODY,
        cksum[3]                Checksum
 }
 
 KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
-       pvno[0]                 INTEGER,
+       pvno[0]                 krb5int32,
        msg-type[1]             MESSAGE-TYPE,
        enc-part[3]             EncryptedData
 }
 EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
        user-data[0]            OCTET STRING,
        timestamp[1]            KerberosTime OPTIONAL,
-       usec[2]                 INTEGER OPTIONAL,
-       seq-number[3]           UNSIGNED OPTIONAL,
+       usec[2]                 krb5int32 OPTIONAL,
+       seq-number[3]           krb5uint32 OPTIONAL,
        s-address[4]            HostAddress OPTIONAL, -- sender's addr
        r-address[5]            HostAddress OPTIONAL  -- recip's addr
 }
 
 KRB-CRED ::= [APPLICATION 22]   SEQUENCE {
-       pvno[0]                 INTEGER,
+       pvno[0]                 krb5int32,
        msg-type[1]             MESSAGE-TYPE, -- KRB_CRED
        tickets[2]              SEQUENCE OF Ticket,
        enc-part[3]             EncryptedData
@@ -467,21 +485,21 @@ KrbCredInfo ::= SEQUENCE {
 
 EncKrbCredPart ::= [APPLICATION 29]   SEQUENCE {
        ticket-info[0]          SEQUENCE OF KrbCredInfo,
-       nonce[1]                INTEGER OPTIONAL,
+       nonce[1]                krb5int32 OPTIONAL,
        timestamp[2]            KerberosTime OPTIONAL,
-       usec[3]                 INTEGER OPTIONAL,
+       usec[3]                 krb5int32 OPTIONAL,
        s-address[4]            HostAddress OPTIONAL,
        r-address[5]            HostAddress OPTIONAL
 }
 
 KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
-       pvno[0]                 INTEGER,
+       pvno[0]                 krb5int32,
        msg-type[1]             MESSAGE-TYPE,
        ctime[2]                KerberosTime OPTIONAL,
-       cusec[3]                INTEGER OPTIONAL,
+       cusec[3]                krb5int32 OPTIONAL,
        stime[4]                KerberosTime,
-       susec[5]                INTEGER,
-       error-code[6]           INTEGER,
+       susec[5]                krb5int32,
+       error-code[6]           krb5int32,
        crealm[7]               Realm OPTIONAL,
        cname[8]                PrincipalName OPTIONAL,
        realm[9]                Realm, -- Correct realm
@@ -496,15 +514,15 @@ ChangePasswdDataMS ::= SEQUENCE {
        targrealm[2]            Realm OPTIONAL
 }
 
-EtypeList ::= SEQUENCE OF INTEGER
+EtypeList ::= SEQUENCE OF krb5int32
        -- the client's proposed enctype list in
        -- decreasing preference order, favorite choice first
 
-krb5-pvno INTEGER ::= 5 -- current Kerberos protocol version number
+krb5-pvno krb5int32 ::= 5 -- current Kerberos protocol version number
 
 -- transited encodings
 
-DOMAIN-X500-COMPRESS   INTEGER ::= 1
+DOMAIN-X500-COMPRESS   krb5int32 ::= 1
 
 -- authorization data primitives
 
@@ -544,7 +562,7 @@ SAMFlags ::= BIT STRING {
 }
 
 PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE {
-       sam-type[0]             INTEGER,
+       sam-type[0]             krb5int32,
        sam-flags[1]            SAMFlags,
        sam-type-name[2]        GeneralString OPTIONAL,
        sam-track-id[3]         GeneralString OPTIONAL,
@@ -552,8 +570,8 @@ PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE {
        sam-challenge[5]        GeneralString OPTIONAL,
        sam-response-prompt[6]  GeneralString OPTIONAL,
        sam-pk-for-sad[7]       EncryptionKey OPTIONAL,
-       sam-nonce[8]            INTEGER,
-       sam-etype[9]            INTEGER,
+       sam-nonce[8]            krb5int32,
+       sam-etype[9]            krb5int32,
        ...
 }
 
@@ -564,27 +582,31 @@ PA-SAM-CHALLENGE-2 ::= SEQUENCE {
 }
 
 PA-SAM-RESPONSE-2 ::= SEQUENCE {
-       sam-type[0]             INTEGER,
+       sam-type[0]             krb5int32,
        sam-flags[1]            SAMFlags,
        sam-track-id[2]         GeneralString OPTIONAL,
        sam-enc-nonce-or-sad[3] EncryptedData, -- PA-ENC-SAM-RESPONSE-ENC
-       sam-nonce[4]            INTEGER,
+       sam-nonce[4]            krb5int32,
        ...
 }
 
 PA-ENC-SAM-RESPONSE-ENC ::= SEQUENCE {
-       sam-nonce[0]            INTEGER,
+       sam-nonce[0]            krb5int32,
        sam-sad[1]              GeneralString OPTIONAL,
        ...
 }
 
+-- This is really part of CMS, but its here because KCRYPTO provides
+-- the crypto framework for CMS glue in heimdal.
+
 RC2CBCParameter ::= SEQUENCE {
-       rc2ParameterVersion     [0] INTEGER,
-       iv                      [1] OCTET STRING -- exactly 8 octets
+       rc2ParameterVersion     krb5int32,
+       iv                      OCTET STRING -- exactly 8 octets
 }
 
 CBCParameter ::= OCTET STRING
 
+
 END
 
 -- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1
index 655dbeb9d2bd8cd18f7cd3fd432fc64d57a33f2f..713a3d26aacd6de653a1279c75431da7618b286e 100644 (file)
@@ -1,85 +1,32 @@
-
-#line 3 "lex.yy.c"
-
-#define  YY_INT_ALIGNED short int
-
 /* A lexical scanner generated by flex */
 
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 31
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
 
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
 #include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+#include <unistd.h>
 
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
 
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
 #endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
 #endif
 
-#endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
 
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
 /* The "const" storage-class-modifier is valid. */
 #define YY_USE_CONST
 
@@ -87,17 +34,34 @@ typedef unsigned int flex_uint32_t;
 
 #if __STDC__
 
+#define YY_USE_PROTOS
 #define YY_USE_CONST
 
 #endif /* __STDC__ */
 #endif /* ! __cplusplus */
 
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
 #ifdef YY_USE_CONST
 #define yyconst const
 #else
 #define yyconst
 #endif
 
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
 /* Returned upon end-of-file. */
 #define YY_NULL 0
 
@@ -112,71 +76,71 @@ typedef unsigned int flex_uint32_t;
  * but we do it the disgusting crufty way forced on us by the ()-less
  * definition of BEGIN.
  */
-#define BEGIN (yy_start) = 1 + 2 *
+#define BEGIN yy_start = 1 + 2 *
 
 /* Translate the current start state into a value that can be later handed
  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  * compatibility.
  */
-#define YY_START (((yy_start) - 1) / 2)
+#define YY_START ((yy_start - 1) / 2)
 #define YYSTATE YY_START
 
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
 
 /* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin  )
+#define YY_NEW_FILE yyrestart( yyin )
 
 #define YY_END_OF_BUFFER_CHAR 0
 
 /* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
 #define YY_BUF_SIZE 16384
-#endif
 
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
 
 extern int yyleng;
-
 extern FILE *yyin, *yyout;
 
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
 
-    #define YY_LESS_LINENO(n)
-    
-/* Return all but the first "n" matched characters back to the input stream. */
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ *     if ( condition_holds )
+ *             yyless( 5 );
+ *     else
+ *             do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
 #define yyless(n) \
        do \
                { \
                /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               *yy_cp = (yy_hold_char); \
+               *yy_cp = yy_hold_char; \
                YY_RESTORE_YY_MORE_OFFSET \
-               (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+               yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
                YY_DO_BEFORE_ACTION; /* set up yytext again */ \
                } \
        while ( 0 )
 
-#define unput(c) yyunput( c, (yytext_ptr)  )
+#define unput(c) yyunput( c, yytext_ptr )
 
 /* The following is because we cannot portably get our hands on size_t
  * (without autoconf's help, which isn't available because we want
  * flex-generated scanners to compile on their own).
  */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
 typedef unsigned int yy_size_t;
-#endif
 
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
+
 struct yy_buffer_state
        {
        FILE *yy_input_file;
@@ -213,16 +177,12 @@ struct yy_buffer_state
         */
        int yy_at_bol;
 
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-    
        /* Whether to try to fill the input buffer when we reach the
         * end of it.
         */
        int yy_fill_buffer;
 
        int yy_buffer_status;
-
 #define YY_BUFFER_NEW 0
 #define YY_BUFFER_NORMAL 1
        /* When an EOF's been seen but there's still some text to process
@@ -236,33 +196,23 @@ struct yy_buffer_state
         * just pointing yyin at a new input file.
         */
 #define YY_BUFFER_EOF_PENDING 2
-
        };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
 
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+static YY_BUFFER_STATE yy_current_buffer = 0;
 
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
  * "scanner state".
- *
- * Returns the top of the stack, or NULL.
  */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
-                          : NULL)
+#define YY_CURRENT_BUFFER yy_current_buffer
 
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
 
 /* yy_hold_char holds the character lost when yytext is formed. */
 static char yy_hold_char;
+
 static int yy_n_chars;         /* number of characters read into yy_ch_buf */
+
+
 int yyleng;
 
 /* Points to current character in buffer. */
@@ -275,131 +225,147 @@ static int yy_start = 0;        /* start state number */
  */
 static int yy_did_buffer_switch_on_eof;
 
-void yyrestart (FILE *input_file  );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
-void yy_delete_buffer (YY_BUFFER_STATE b  );
-void yy_flush_buffer (YY_BUFFER_STATE b  );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void yypop_buffer_state (void );
+void yyrestart YY_PROTO(( FILE *input_file ));
 
-static void yyensure_buffer_stack (void );
-static void yy_load_buffer_state (void );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
 
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
 
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
-
-void *yyalloc (yy_size_t  );
-void *yyrealloc (void *,yy_size_t  );
-void yyfree (void *  );
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
 
 #define yy_new_buffer yy_create_buffer
 
 #define yy_set_interactive(is_interactive) \
        { \
-       if ( ! YY_CURRENT_BUFFER ){ \
-        yyensure_buffer_stack (); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_is_interactive = is_interactive; \
        }
 
 #define yy_set_bol(at_bol) \
        { \
-       if ( ! YY_CURRENT_BUFFER ){\
-        yyensure_buffer_stack (); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_at_bol = at_bol; \
        }
 
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
 
 typedef unsigned char YY_CHAR;
-
 FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-
 typedef int yy_state_type;
-
-extern int yylineno;
-
-int yylineno = 1;
-
 extern char *yytext;
 #define yytext_ptr yytext
 
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[]  );
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
 
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
-       (yytext_ptr) = yy_bp; \
-       yyleng = (size_t) (yy_cp - yy_bp); \
-       (yy_hold_char) = *yy_cp; \
+       yytext_ptr = yy_bp; \
+       yyleng = (int) (yy_cp - yy_bp); \
+       yy_hold_char = *yy_cp; \
        *yy_cp = '\0'; \
-       (yy_c_buf_p) = yy_cp;
+       yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 38
-#define YY_END_OF_BUFFER 39
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-       {
-       flex_int32_t yy_verify;
-       flex_int32_t yy_nxt;
-       };
-static yyconst flex_int16_t yy_accept[183] =
+#define YY_NUM_RULES 95
+#define YY_END_OF_BUFFER 96
+static yyconst short int yy_accept[568] =
     {   0,
-        0,    0,   39,   37,   33,   34,   25,   25,   37,   37,
-       31,   31,   37,   32,   32,   32,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   26,   27,   29,   36,
-       30,   31,    0,    0,   32,   32,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
-       32,    7,   32,   32,   32,   32,   35,   31,   28,   32,
-       32,   14,   32,   32,   32,   18,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   32,   32,    4,   32,
-       32,   32,   32,   13,   32,   32,   32,   32,   32,   32,
-
-       32,   17,   32,   32,   32,   32,   32,   32,   32,   32,
-       32,   32,   32,    8,   32,   32,   32,   32,   32,   32,
-        6,   32,   32,   32,   32,   32,   32,   32,   32,   23,
-       32,   32,    9,   32,   32,    2,   19,   32,   32,   32,
-       32,   32,    3,    1,   32,   32,   32,   32,   32,   32,
-       22,   32,   32,   32,   16,    5,   32,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   21,   32,   32,   24,
-       12,   15,   20,   32,   32,   32,   32,   11,   32,   32,
-       10,    0
+        0,    0,   96,   94,   90,   91,   87,   81,   81,   94,
+       94,   88,   88,   94,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   82,   83,   85,   88,   88,   93,   86,
+        0,    0,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   10,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   51,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   92,   88,   84,
+
+       89,    3,   89,   89,   89,    7,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   22,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   44,   45,   89,   89,   89,   89,   89,   89,
+       89,   55,   89,   89,   89,   89,   89,   89,   89,   63,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   30,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+
+       47,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   60,   89,   89,   64,   89,   89,   89,   68,   69,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       80,   89,   89,   89,   89,    6,   89,   89,   89,   89,
+       13,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   29,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   50,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   72,   89,   89,   89,   89,   89,
+       89,   89,    1,   89,   89,   89,   89,   89,   89,   12,
+
+       89,   89,   89,   89,   89,   89,   89,   89,   24,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   49,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   65,   66,   89,
+       89,   89,   73,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,    9,   89,   89,   89,   89,   18,   89,
+       89,   21,   89,   89,   26,   89,   89,   89,   89,   89,
+       89,   89,   37,   38,   89,   89,   41,   89,   89,   89,
+       89,   89,   89,   54,   89,   57,   58,   89,   89,   89,
+       89,   89,   89,   89,   75,   89,   89,   89,   89,   89,
+
+       89,   89,   89,   89,   89,   89,   89,   89,   20,   89,
+       25,   89,   28,   89,   89,   89,   89,   89,   36,   39,
+       40,   89,   89,   89,   89,   52,   89,   89,   89,   89,
+       62,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,    5,    8,   11,   14,   89,   89,   89,   89,   89,
+       89,   89,   89,   34,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   67,   89,   89,   74,   89,   89,   89,
+       89,   89,   89,   15,   89,   17,   89,   23,   89,   89,
+       89,   89,   35,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   76,   89,   89,   89,   89,    4,   16,
+
+       19,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,
+       89,   89,   89,   42,   43,   89,   89,   89,   89,   89,
+       61,   89,   89,   89,   89,   89,   89,   27,   31,   89,
+       33,   89,   48,   89,   56,   89,   89,   71,   89,   89,
+       79,   89,   89,   46,   89,   89,   89,   89,   78,    2,
+       32,   89,   59,   70,   77,   53,    0
     } ;
 
-static yyconst flex_int32_t yy_ec[256] =
+static yyconst int yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    1,    4,    1,    1,    1,    1,    1,    4,
-        4,    5,    1,    4,    6,    7,    8,    9,   10,   10,
-       10,   10,   10,   10,   10,   11,   10,   12,    4,    1,
-       13,    1,    1,    1,   14,   15,   16,   17,   18,   19,
-       20,   21,   22,   23,   24,   25,   26,   27,   28,   29,
-       30,   31,   32,   33,   34,   24,   24,   35,   24,   24,
-       36,    1,   37,    1,   38,    1,   39,   40,   40,   41,
-
-       42,   40,   43,   24,   44,   24,   24,   45,   46,   47,
-       24,   24,   24,   48,   24,   49,   24,   24,   24,   50,
-       24,   51,    4,    4,    4,    1,    1,    1,    1,    1,
+        1,    2,    1,    4,    1,    1,    1,    1,    1,    5,
+        5,    6,    1,    5,    7,    8,    9,   10,   11,   12,
+       12,   13,   14,   15,   12,   16,   12,   17,    5,    1,
+       18,    1,    1,    1,   19,   20,   21,   22,   23,   24,
+       25,   26,   27,   28,   29,   30,   31,   32,   33,   34,
+       35,   36,   37,   38,   39,   40,   41,   42,   43,   44,
+       45,    1,   46,    1,   47,    1,   48,   49,   50,   51,
+
+       52,   53,   54,   55,   56,   57,   29,   58,   59,   60,
+       61,   62,   29,   63,   64,   65,   66,   67,   29,   68,
+       29,   69,    5,    5,    5,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -416,136 +382,316 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[52] =
+static yyconst int yy_meta[70] =
     {   0,
-        1,    1,    1,    1,    1,    2,    1,    1,    3,    3,
-        3,    1,    1,    3,    3,    3,    3,    3,    3,    2,
+        1,    1,    1,    1,    1,    1,    2,    1,    1,    3,
+        3,    3,    3,    3,    3,    3,    1,    1,    3,    3,
+        3,    3,    3,    3,    2,    2,    2,    2,    2,    2,
         2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-        2,    2,    2,    2,    2,    1,    1,    2,    3,    3,
-        3,    3,    2,    2,    2,    2,    2,    2,    2,    2,
-        2
+        2,    2,    2,    2,    1,    1,    2,    3,    3,    3,
+        3,    3,    3,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2
     } ;
 
-static yyconst flex_int16_t yy_base[185] =
+static yyconst short int yy_base[570] =
     {   0,
-        0,    0,  214,  215,  215,  215,  215,  207,  205,  206,
-       43,   46,  198,  180,   40,  187,  189,   32,  175,  163,
-        0,   43,  170,   56,   43,  170,  215,  215,  215,  195,
-      215,   54,    0,  188,    0,  171,  179,  165,  169,  168,
-      176,   49,  161,  165,  145,  173,  161,  156,  163,  164,
-      153,    0,  152,  154,  152,  163,  215,    0,  215,  156,
-      158,    0,  154,  156,   59,    0,  151,  158,  149,  132,
-      146,  144,  153,  145,  151,  150,  145,  132,  143,  153,
-      141,  135,  143,  144,  125,  131,  139,  125,    0,  107,
-      121,  122,  132,    0,  135,  117,  121,  130,  120,  114,
-
-      129,    0,  130,  125,  117,  119,  109,  112,   99,  115,
-      103,  117,  101,    0,  106,  105,  111,   81,  115,  101,
-        0,   94,   93,  111,  110,   78,  103,   89,   89,    0,
-      105,  102,    0,   69,   83,    0,    0,   93,   81,   88,
-       42,   90,    0,    0,   86,   92,   65,   86,   79,   88,
-        0,   56,   53,   85,    0,    0,   55,   73,   73,   82,
-       50,   55,   65,   49,   64,   58,    0,   45,   47,    0,
-        0,    0,    0,   40,   51,   39,   36,    0,   33,   36,
-        0,  215,   92,   74
+        0,    0,  636,  637,  637,  637,  637,  637,   63,  627,
+      628,   70,   77,  616,   74,   72,   76,  609,   65,   81,
+       49,    0,   92,   91,   32,  101,   97,  608,  103,  113,
+       99,  574,  602,  637,  637,  637,  156,  163,  620,  637,
+        0,  609,    0,  589,  595,  590,  585,  597,  583,  586,
+      586,    0,  101,  599,  108,  593,  596,  122,  124,  585,
+      581,  553,  564,  597,  587,  575,  115,  575,  565,  574,
+      575,  545,  575,  564,    0,  563,  543,  561,  558,  558,
+      124,  540,  161,  119,  551,  558,  561,  581,  566,  551,
+      555,  530,  560,  160,  530,   91,  547,  637,    0,  637,
+
+      125,    0,  554,  550,  555,    0,  544,  550,  543,  551,
+      540,  542,  145,  166,  552,  541,    0,  542,  549,  156,
+      548,  533,  538,  516,  505,  529,  533,  157,  534,  525,
+      539,  546,    0,  521,  529,  506,  534,  533,  528,  502,
+      515,    0,  515,  514,  510,  489,  518,  528,  507,    0,
+      522,  517,  505,  505,  504,  517,  516,  486,  159,  499,
+      520,  468,  482,  477,  506,  499,  494,  502,  497,  495,
+      461,  502,  505,  502,  485,  488,  482,  500,  479,  485,
+      494,  493,  491,  479,  485,  475,  164,  487,    0,  446,
+      453,  442,  468,  478,  468,  464,  483,  170,  488,  463,
+
+        0,  436,  477,  459,  463,  445,  471,  486,  469,  472,
+      425,    0,  451,  465,    0,  455,  467,  420,    0,    0,
+      477,  418,  450,  442,  457,  423,  441,  425,  415,  426,
+        0,  436,  454,  451,  452,    0,  407,  450,  447,  444,
+        0,  434,  429,  437,  433,  435,  439,  437,  423,  420,
+      436,  418,  418,  422,    0,  405,  396,  388,  423,  180,
+      411,  426,  415,  423,  408,  429,  436,  386,  403,    0,
+      408,  374,  402,  410,  404,  397,  386,  406,  400,  406,
+      388,  366,  401,  375,    0,  403,  389,  365,  358,  359,
+      356,  362,    0,  398,  399,  379,  360,  383,  376,    0,
+
+      390,  393,  379,  372,  371,  385,  385,  387,    0,  378,
+      367,  376,  383,  343,  350,  343,  374,  370,  374,  358,
+      371,  372,  356,  368,  353,  362,  338,    0,  368,  364,
+      353,  352,  345,  359,  332,  340,  358,    0,    0,  322,
+      355,  308,    0,  338,  322,  310,  308,  319,  318,  331,
+      330,  340,  306,    0,  342,  332,  336,  335,    0,  334,
+      338,    0,  321,  320,    0,  337,  326,  151,  318,  294,
+      326,  314,    0,    0,  314,  327,    0,  328,  283,  315,
+      309,  315,  292,    0,  319,    0,    0,  284,  318,  317,
+      279,  315,  300,  317,    0,  279,  286,  265,  295,  324,
+
+      303,  308,  274,  291,  288,  293,  292,  290,    0,  299,
+        0,  294,    0,  255,  250,  253,  263,  293,    0,    0,
+        0,  277,  251,  289,  247,    0,  247,  283,  257,  261,
+        0,  253,  274,  240,  274,  243,  244,  264,  235,  262,
+      265,    0,    0,    0,  260,  273,  270,  262,  271,  262,
+      228,  238,  226,    0,  252,  260,  230,  258,  221,  233,
+      250,  244,  247,    0,  241,  215,    0,  223,  239,  210,
+      211,  230,  240,    0,  249,    0,  233,    0,  242,  212,
+      216,  210,    0,  232,  204,  231,  206,  198,  233,  194,
+      231,  230,  200,    0,  190,  191,  197,  220,    0,    0,
+
+        0,  213,  190,  211,  188,  215,  192,  218,  184,  187,
+      204,  178,  218,  215,  178,  174,  180,  175,  196,  190,
+      178,  175,  176,    0,    0,  191,  174,  165,  180,  166,
+        0,  194,  166,  163,  158,  163,  197,    0,    0,  156,
+        0,  171,    0,  148,    0,  152,  188,    0,  150,  155,
+        0,  166,  153,    0,  143,  148,  162,  143,    0,    0,
+        0,  101,    0,    0,    0,    0,  637,  223,   69
     } ;
 
-static yyconst flex_int16_t yy_def[185] =
+static yyconst short int yy_def[570] =
     {   0,
-      182,    1,  182,  182,  182,  182,  182,  182,  182,  182,
-      182,  182,  182,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  182,  182,  182,  182,
-      182,  182,  184,  182,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  182,  184,  182,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,  183,  183,  183,  183,  183,  183,  183,  183,  183,
-      183,    0,  182,  182
+      567,    1,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  567,  567,  567,  567,  567,  567,  567,
+      569,  567,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  567,  569,  567,
+
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,  568,  568,  568,  568,
+      568,  568,  568,  568,  568,  568,    0,  567,  567
     } ;
 
-static yyconst flex_int16_t yy_nxt[267] =
+static yyconst short int yy_nxt[707] =
     {   0,
-        4,    5,    6,    7,    4,    8,    9,   10,   11,   12,
-       12,   13,    4,   14,   15,   16,   17,   18,   19,   20,
-       21,   22,   21,   21,   21,   21,   23,   24,   21,   21,
-       21,   25,   21,   26,   21,   27,   28,    4,   21,   21,
-       21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
-       21,   32,   32,   32,   32,   32,   32,   37,   42,   46,
-       54,   38,   32,   32,   32,   66,   43,   39,   47,   48,
-       50,   51,   85,  152,   52,   55,   58,  181,  180,  179,
-       86,  178,   67,  177,   53,  153,  176,  175,  174,  173,
-      172,  171,   33,   35,   35,  170,  169,  168,  167,  166,
-
-      165,  164,  163,  162,  161,  160,  159,  158,  157,  156,
-      155,  154,  151,  150,  149,  148,  147,  146,  145,  144,
-      143,  142,  141,  140,  139,  138,  137,  136,  135,  134,
-      133,  132,  131,  130,  129,  128,  127,  126,  125,  124,
-      123,  122,  121,  120,  119,  118,  117,  116,  115,  114,
-      113,  112,  111,  110,  109,  108,  107,  106,  105,  104,
-      103,  102,  101,  100,   99,   98,   97,   96,   95,   94,
-       93,   92,   91,   90,   89,   88,   87,   84,   83,   82,
-       81,   80,   79,   78,   77,   76,   75,   74,   73,   72,
-       71,   70,   69,   68,   65,   64,   63,   62,   61,   60,
-
-       59,   57,   56,   49,   45,   44,   41,   40,   36,   34,
-       31,   30,   29,  182,    3,  182,  182,  182,  182,  182,
-      182,  182,  182,  182,  182,  182,  182,  182,  182,  182,
-      182,  182,  182,  182,  182,  182,  182,  182,  182,  182,
-      182,  182,  182,  182,  182,  182,  182,  182,  182,  182,
-      182,  182,  182,  182,  182,  182,  182,  182,  182,  182,
-      182,  182,  182,  182,  182,  182
+        4,    5,    6,    7,    8,    4,    9,   10,   11,   12,
+       13,   13,   13,   13,   13,   13,   14,    4,   15,   16,
+       17,   18,   19,   20,   21,   22,   23,   22,   22,   22,
+       24,   25,   26,   27,   22,   28,   29,   30,   31,   32,
+       33,   22,   22,   22,   34,   35,    4,   22,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   22,   22,   36,
+       71,   99,   37,   38,   38,   38,   38,   38,   38,   38,
+       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
+       38,   38,   38,   44,   48,   57,   58,   72,   49,   60,
+
+       62,   53,   50,   45,   51,   54,   59,   46,   55,   69,
+       64,   63,   47,   65,   52,   78,   61,   70,   79,  109,
+       73,   74,   66,   67,   75,   84,   80,   88,   68,   85,
+       93,   89,   81,  110,   76,  129,   94,   41,  112,  113,
+       86,  163,  116,  117,  119,   87,  144,  166,   90,   77,
+      145,  130,  131,  149,  164,   91,  150,  120,   95,   82,
+      118,  121,  167,  566,   92,   38,   38,   38,   38,   38,
+       38,   38,   38,   38,   38,   38,   38,   38,   38,  147,
+      160,  177,  178,  161,  179,  185,  194,  414,  186,  195,
+      148,  223,  180,  224,  264,  253,  565,  564,  225,  254,
+
+      318,  563,  319,  562,  561,  265,  415,  560,  559,  558,
+      557,  556,  555,  554,  553,  552,  551,  550,  549,  548,
+      547,  546,  545,   41,   43,   43,  544,  543,  542,  541,
+      540,  539,  538,  537,  536,  535,  534,  533,  532,  531,
+      530,  529,  528,  527,  526,  525,  524,  523,  522,  521,
+      520,  519,  518,  517,  516,  515,  514,  513,  512,  511,
+      510,  509,  508,  507,  506,  505,  504,  503,  502,  501,
+      500,  499,  498,  497,  496,  495,  494,  493,  492,  491,
+      490,  489,  488,  487,  486,  485,  484,  483,  482,  481,
+      480,  479,  478,  477,  476,  475,  474,  473,  472,  471,
+
+      470,  469,  468,  467,  466,  465,  464,  463,  462,  461,
+      460,  459,  458,  457,  456,  455,  454,  453,  452,  451,
+      450,  449,  448,  447,  446,  445,  444,  443,  442,  441,
+      440,  439,  438,  437,  436,  435,  434,  433,  432,  431,
+      430,  429,  428,  427,  426,  425,  424,  423,  422,  421,
+      420,  419,  418,  417,  416,  413,  412,  411,  410,  409,
+      408,  407,  406,  405,  404,  403,  402,  401,  400,  399,
+      398,  397,  396,  395,  394,  393,  392,  391,  390,  389,
+      388,  387,  386,  385,  384,  383,  382,  381,  380,  379,
+      378,  377,  376,  375,  374,  373,  372,  371,  370,  369,
+
+      368,  367,  366,  365,  364,  363,  362,  361,  360,  359,
+      358,  357,  356,  355,  354,  353,  352,  351,  350,  349,
+      348,  347,  346,  345,  344,  343,  342,  341,  340,  339,
+      338,  337,  336,  335,  334,  333,  332,  331,  330,  329,
+      328,  327,  326,  325,  324,  323,  322,  321,  320,  317,
+      316,  315,  314,  313,  312,  311,  310,  309,  308,  307,
+      306,  305,  304,  303,  302,  301,  300,  299,  298,  297,
+      296,  295,  294,  293,  292,  291,  290,  289,  288,  287,
+      286,  285,  284,  283,  282,  281,  280,  279,  278,  277,
+      276,  275,  274,  273,  272,  271,  270,  269,  268,  267,
+
+      266,  263,  262,  261,  260,  259,  258,  257,  256,  255,
+      252,  251,  250,  249,  248,  247,  246,  245,  244,  243,
+      242,  241,  240,  239,  238,  237,  236,  235,  234,  233,
+      232,  231,  230,  229,  228,  227,  226,  222,  221,  220,
+      219,  218,  217,  216,  215,  214,  213,  212,  211,  210,
+      209,  208,  207,  206,  205,  204,  203,  202,  201,  200,
+      199,  198,  197,  196,  193,  192,  191,  190,  189,  188,
+      187,  184,  183,  182,  181,  176,  175,  174,  173,  172,
+      171,  170,  169,  168,  165,  162,  159,  158,  157,  156,
+      155,  154,  153,  152,  151,  146,  143,  142,  141,  140,
+
+      139,  138,  137,  136,  135,  134,  133,  132,  128,  127,
+      126,  125,  124,  123,  122,  115,  114,  111,  108,  107,
+      106,  105,  104,  103,  102,  101,  100,   98,   97,   96,
+       83,   56,   42,   40,   39,  567,    3,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+
+      567,  567,  567,  567,  567,  567
     } ;
 
-static yyconst flex_int16_t yy_chk[267] =
+static yyconst short int yy_chk[707] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,   11,   11,   11,   12,   12,   12,   15,   18,   22,
-       25,   15,   32,   32,   32,   42,   18,   15,   22,   22,
-       24,   24,   65,  141,   24,   25,  184,  180,  179,  177,
-       65,  176,   42,  175,   24,  141,  174,  169,  168,  166,
-      165,  164,   11,  183,  183,  163,  162,  161,  160,  159,
-
-      158,  157,  154,  153,  152,  150,  149,  148,  147,  146,
-      145,  142,  140,  139,  138,  135,  134,  132,  131,  129,
-      128,  127,  126,  125,  124,  123,  122,  120,  119,  118,
-      117,  116,  115,  113,  112,  111,  110,  109,  108,  107,
-      106,  105,  104,  103,  101,  100,   99,   98,   97,   96,
-       95,   93,   92,   91,   90,   88,   87,   86,   85,   84,
-       83,   82,   81,   80,   79,   78,   77,   76,   75,   74,
-       73,   72,   71,   70,   69,   68,   67,   64,   63,   61,
-       60,   56,   55,   54,   53,   51,   50,   49,   48,   47,
-       46,   45,   44,   43,   41,   40,   39,   38,   37,   36,
-
-       34,   30,   26,   23,   20,   19,   17,   16,   14,   13,
-       10,    9,    8,    3,  182,  182,  182,  182,  182,  182,
-      182,  182,  182,  182,  182,  182,  182,  182,  182,  182,
-      182,  182,  182,  182,  182,  182,  182,  182,  182,  182,
-      182,  182,  182,  182,  182,  182,  182,  182,  182,  182,
-      182,  182,  182,  182,  182,  182,  182,  182,  182,  182,
-      182,  182,  182,  182,  182,  182
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    9,
+       25,  569,    9,    9,    9,    9,    9,    9,    9,   12,
+       12,   12,   12,   12,   12,   12,   13,   13,   13,   13,
+       13,   13,   13,   15,   16,   19,   19,   25,   16,   20,
+
+       21,   17,   16,   15,   16,   17,   19,   15,   17,   24,
+       23,   21,   15,   23,   16,   27,   20,   24,   27,   53,
+       26,   26,   23,   23,   26,   29,   27,   30,   23,   29,
+       31,   30,   27,   53,   26,   67,   31,   12,   55,   55,
+       29,   96,   58,   58,   59,   29,   81,  101,   30,   26,
+       81,   67,   67,   84,   96,   30,   84,   59,   31,   27,
+       58,   59,  101,  562,   30,   37,   37,   37,   37,   37,
+       37,   37,   38,   38,   38,   38,   38,   38,   38,   83,
+       94,  113,  113,   94,  114,  120,  128,  368,  120,  128,
+       83,  159,  114,  159,  198,  187,  558,  557,  159,  187,
+
+      260,  556,  260,  555,  553,  198,  368,  552,  550,  549,
+      547,  546,  544,  542,  540,  537,  536,  535,  534,  533,
+      532,  530,  529,   37,  568,  568,  528,  527,  526,  523,
+      522,  521,  520,  519,  518,  517,  516,  515,  514,  513,
+      512,  511,  510,  509,  508,  507,  506,  505,  504,  503,
+      502,  498,  497,  496,  495,  493,  492,  491,  490,  489,
+      488,  487,  486,  485,  484,  482,  481,  480,  479,  477,
+      475,  473,  472,  471,  470,  469,  468,  466,  465,  463,
+      462,  461,  460,  459,  458,  457,  456,  455,  453,  452,
+      451,  450,  449,  448,  447,  446,  445,  441,  440,  439,
+
+      438,  437,  436,  435,  434,  433,  432,  430,  429,  428,
+      427,  425,  424,  423,  422,  418,  417,  416,  415,  414,
+      412,  410,  408,  407,  406,  405,  404,  403,  402,  401,
+      400,  399,  398,  397,  396,  394,  393,  392,  391,  390,
+      389,  388,  385,  383,  382,  381,  380,  379,  378,  376,
+      375,  372,  371,  370,  369,  367,  366,  364,  363,  361,
+      360,  358,  357,  356,  355,  353,  352,  351,  350,  349,
+      348,  347,  346,  345,  344,  342,  341,  340,  337,  336,
+      335,  334,  333,  332,  331,  330,  329,  327,  326,  325,
+      324,  323,  322,  321,  320,  319,  318,  317,  316,  315,
+
+      314,  313,  312,  311,  310,  308,  307,  306,  305,  304,
+      303,  302,  301,  299,  298,  297,  296,  295,  294,  292,
+      291,  290,  289,  288,  287,  286,  284,  283,  282,  281,
+      280,  279,  278,  277,  276,  275,  274,  273,  272,  271,
+      269,  268,  267,  266,  265,  264,  263,  262,  261,  259,
+      258,  257,  256,  254,  253,  252,  251,  250,  249,  248,
+      247,  246,  245,  244,  243,  242,  240,  239,  238,  237,
+      235,  234,  233,  232,  230,  229,  228,  227,  226,  225,
+      224,  223,  222,  221,  218,  217,  216,  214,  213,  211,
+      210,  209,  208,  207,  206,  205,  204,  203,  202,  200,
+
+      199,  197,  196,  195,  194,  193,  192,  191,  190,  188,
+      186,  185,  184,  183,  182,  181,  180,  179,  178,  177,
+      176,  175,  174,  173,  172,  171,  170,  169,  168,  167,
+      166,  165,  164,  163,  162,  161,  160,  158,  157,  156,
+      155,  154,  153,  152,  151,  149,  148,  147,  146,  145,
+      144,  143,  141,  140,  139,  138,  137,  136,  135,  134,
+      132,  131,  130,  129,  127,  126,  125,  124,  123,  122,
+      121,  119,  118,  116,  115,  112,  111,  110,  109,  108,
+      107,  105,  104,  103,   97,   95,   93,   92,   91,   90,
+       89,   88,   87,   86,   85,   82,   80,   79,   78,   77,
+
+       76,   74,   73,   72,   71,   70,   69,   68,   66,   65,
+       64,   63,   62,   61,   60,   57,   56,   54,   51,   50,
+       49,   48,   47,   46,   45,   44,   42,   39,   33,   32,
+       28,   18,   14,   11,   10,    3,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,
+
+      567,  567,  567,  567,  567,  567
     } ;
 
 static yy_state_type yy_last_accepting_state;
 static char *yy_last_accepting_cpos;
 
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
  */
@@ -555,9 +701,10 @@ int yy_flex_debug = 0;
 #define YY_RESTORE_YY_MORE_OFFSET
 char *yytext;
 #line 1 "lex.l"
+#define INITIAL 0
 #line 2 "lex.l"
 /*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -589,7 +736,7 @@ char *yytext;
  * SUCH DAMAGE. 
  */
 
-/* $Id: lex.l,v 1.25 2005/06/16 19:58:35 lha Exp $ */
+/* $Id: lex.l,v 1.26 2005/07/12 06:27:33 lha Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -609,27 +756,11 @@ char *yytext;
 
 static unsigned lineno = 1;
 
-#define YY_NO_UNPUT
-
 #undef ECHO
 
 static void handle_comment(int type);
-
-#line 619 "lex.yy.c"
-
-#define INITIAL 0
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
+static char *handle_string(void);
+#line 764 "lex.yy.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -637,30 +768,65 @@ static void handle_comment(int type);
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int yywrap (void );
+extern "C" int yywrap YY_PROTO(( void ));
 #else
-extern int yywrap (void );
+extern int yywrap YY_PROTO(( void ));
 #endif
 #endif
 
-    static void yyunput (int c,char *buf_ptr  );
-    
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+#endif
+
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
 #endif
 
 #ifndef YY_NO_INPUT
-
 #ifdef __cplusplus
-static int yyinput (void );
+static int yyinput YY_PROTO(( void ));
 #else
-static int input (void );
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
 #endif
 
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
 #endif
 
 /* Amount of stuff to slurp up with each read. */
@@ -669,6 +835,7 @@ static int input (void );
 #endif
 
 /* Copy whatever the last rule matched to the standard output. */
+
 #ifndef ECHO
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
@@ -681,10 +848,9 @@ static int input (void );
  */
 #ifndef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+       if ( yy_current_buffer->yy_is_interactive ) \
                { \
-               int c = '*'; \
-               size_t n; \
+               int c = '*', n; \
                for ( n = 0; n < max_size && \
                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
                        buf[n] = (char) c; \
@@ -694,22 +860,9 @@ static int input (void );
                        YY_FATAL_ERROR( "input in flex scanner failed" ); \
                result = n; \
                } \
-       else \
-               { \
-               errno=0; \
-               while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
-                       { \
-                       if( errno != EINTR) \
-                               { \
-                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
-                               break; \
-                               } \
-                       errno=0; \
-                       clearerr(yyin); \
-                       } \
-               }\
-\
-
+       else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+                 && ferror( yyin ) ) \
+               YY_FATAL_ERROR( "input in flex scanner failed" );
 #endif
 
 /* No semi-colon after return; correct usage is to write "yyterminate();" -
@@ -730,18 +883,12 @@ static int input (void );
 #define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
 #endif
 
-/* end tables serialization structures and prototypes */
-
 /* Default declaration of generated scanner - a define so the user can
  * easily add parameters.
  */
 #ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
 
 /* Code executed at the beginning of each rule, after yytext and yyleng
  * have been set up.
@@ -758,28 +905,26 @@ extern int yylex (void);
 #define YY_RULE_SETUP \
        YY_USER_ACTION
 
-/** The main scanner function which does all the work.
- */
 YY_DECL
-{
+       {
        register yy_state_type yy_current_state;
-       register char *yy_cp, *yy_bp;
+       register char *yy_cp = NULL, *yy_bp = NULL;
        register int yy_act;
-    
-#line 64 "lex.l"
 
-#line 772 "lex.yy.c"
+#line 62 "lex.l"
 
-       if ( (yy_init) )
+#line 917 "lex.yy.c"
+
+       if ( yy_init )
                {
-               (yy_init) = 0;
+               yy_init = 0;
 
 #ifdef YY_USER_INIT
                YY_USER_INIT;
 #endif
 
-               if ( ! (yy_start) )
-                       (yy_start) = 1; /* first start state */
+               if ( ! yy_start )
+                       yy_start = 1;   /* first start state */
 
                if ( ! yyin )
                        yyin = stdin;
@@ -787,314 +932,598 @@ YY_DECL
                if ( ! yyout )
                        yyout = stdout;
 
-               if ( ! YY_CURRENT_BUFFER ) {
-                       yyensure_buffer_stack ();
-                       YY_CURRENT_BUFFER_LVALUE =
-                               yy_create_buffer(yyin,YY_BUF_SIZE );
-               }
+               if ( ! yy_current_buffer )
+                       yy_current_buffer =
+                               yy_create_buffer( yyin, YY_BUF_SIZE );
 
-               yy_load_buffer_state( );
+               yy_load_buffer_state();
                }
 
        while ( 1 )             /* loops until end-of-file is reached */
                {
-               yy_cp = (yy_c_buf_p);
+               yy_cp = yy_c_buf_p;
 
                /* Support of yytext. */
-               *yy_cp = (yy_hold_char);
+               *yy_cp = yy_hold_char;
 
                /* yy_bp points to the position in yy_ch_buf of the start of
                 * the current run.
                 */
                yy_bp = yy_cp;
 
-               yy_current_state = (yy_start);
+               yy_current_state = yy_start;
 yy_match:
                do
                        {
                        register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
                        if ( yy_accept[yy_current_state] )
                                {
-                               (yy_last_accepting_state) = yy_current_state;
-                               (yy_last_accepting_cpos) = yy_cp;
+                               yy_last_accepting_state = yy_current_state;
+                               yy_last_accepting_cpos = yy_cp;
                                }
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 183 )
+                               if ( yy_current_state >= 568 )
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_base[yy_current_state] != 215 );
+               while ( yy_base[yy_current_state] != 637 );
 
 yy_find_action:
                yy_act = yy_accept[yy_current_state];
                if ( yy_act == 0 )
                        { /* have to back up */
-                       yy_cp = (yy_last_accepting_cpos);
-                       yy_current_state = (yy_last_accepting_state);
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
                        yy_act = yy_accept[yy_current_state];
                        }
 
                YY_DO_BEFORE_ACTION;
 
+
 do_action:     /* This label is used only to access EOF actions. */
 
+
                switch ( yy_act )
        { /* beginning of action switch */
                        case 0: /* must back up */
                        /* undo the effects of YY_DO_BEFORE_ACTION */
-                       *yy_cp = (yy_hold_char);
-                       yy_cp = (yy_last_accepting_cpos);
-                       yy_current_state = (yy_last_accepting_state);
+                       *yy_cp = yy_hold_char;
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
                        goto yy_find_action;
 
 case 1:
 YY_RULE_SETUP
-#line 65 "lex.l"
-{ return INTEGER; }
+#line 63 "lex.l"
+{ return kw_ABSENT; }
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 66 "lex.l"
-{ return BOOLEAN; }
+#line 64 "lex.l"
+{ return kw_ABSTRACT_SYNTAX; }
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 67 "lex.l"
-{ return IMPORTS; }
+#line 65 "lex.l"
+{ return kw_ALL; }
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 68 "lex.l"
-{ return FROM; }
+#line 66 "lex.l"
+{ return kw_APPLICATION; }
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 69 "lex.l"
-{ return SEQUENCE; }
+#line 67 "lex.l"
+{ return kw_AUTOMATIC; }
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 70 "lex.l"
-{ return CHOICE; }
+#line 68 "lex.l"
+{ return kw_BEGIN; }
        YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 71 "lex.l"
-{ return OF; }
+#line 69 "lex.l"
+{ return kw_BIT; }
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 72 "lex.l"
-{ return OCTET; }
+#line 70 "lex.l"
+{ return kw_BMPString; }
        YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 73 "lex.l"
-{ return STRING; }
+#line 71 "lex.l"
+{ return kw_BOOLEAN; }
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 74 "lex.l"
-{ return GeneralizedTime; }
+#line 72 "lex.l"
+{ return kw_BY; }
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 75 "lex.l"
-{ return GeneralString; }
+#line 73 "lex.l"
+{ return kw_CHARACTER; }
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 76 "lex.l"
-{ return UTF8String; }
+#line 74 "lex.l"
+{ return kw_CHOICE; }
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 77 "lex.l"
-{ return NULLTYPE; }
+#line 75 "lex.l"
+{ return kw_CLASS; }
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 78 "lex.l"
-{ return BIT; }
+#line 76 "lex.l"
+{ return kw_COMPONENT; }
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 79 "lex.l"
-{ return APPLICATION; }
+#line 77 "lex.l"
+{ return kw_COMPONENTS; }
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 80 "lex.l"
-{ return OPTIONAL; }
+#line 78 "lex.l"
+{ return kw_CONSTRAINED; }
        YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 81 "lex.l"
-{ return TBEGIN; }
+#line 79 "lex.l"
+{ return kw_CONTAINING; }
        YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 82 "lex.l"
-{ return END; }
+#line 80 "lex.l"
+{ return kw_DEFAULT; }
        YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 83 "lex.l"
-{ return DEFAULT; }
+#line 81 "lex.l"
+{ return kw_DEFINITIONS; }
        YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 84 "lex.l"
-{ return DEFINITIONS; }
+#line 82 "lex.l"
+{ return kw_EMBEDDED; }
        YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 85 "lex.l"
-{ return ENUMERATED; }
+#line 83 "lex.l"
+{ return kw_ENCODED; }
        YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 86 "lex.l"
-{ return EXTERNAL; }
+#line 84 "lex.l"
+{ return kw_END; }
        YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 87 "lex.l"
-{ return OBJECT; }
+#line 85 "lex.l"
+{ return kw_ENUMERATED; }
        YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 88 "lex.l"
-{ return IDENTIFIER; }
+#line 86 "lex.l"
+{ return kw_EXCEPT; }
        YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 89 "lex.l"
-{ return *yytext; }
+#line 87 "lex.l"
+{ return kw_EXPLICIT; }
        YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 90 "lex.l"
-{ return *yytext; }
+#line 88 "lex.l"
+{ return kw_EXPORTS; }
        YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 91 "lex.l"
-{ return *yytext; }
+#line 89 "lex.l"
+{ return kw_EXTENSIBILITY; }
        YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 92 "lex.l"
-{ return EEQUAL; }
+#line 90 "lex.l"
+{ return kw_EXTERNAL; }
        YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 93 "lex.l"
-{ handle_comment(0); }
+#line 91 "lex.l"
+{ return kw_FALSE; }
        YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 94 "lex.l"
-{ handle_comment(1); }
+#line 92 "lex.l"
+{ return kw_FROM; }
        YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 95 "lex.l"
-{ char *e, *y = yytext;
-                         yylval.constant = strtol((const char *)yytext,
-                                                  &e, 0);
-                         if(e == y) 
-                           error_message("malformed constant (%s)", yytext); 
-                         else
-                           return CONSTANT;
-                       }
+#line 93 "lex.l"
+{ return kw_GeneralString; }
        YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 103 "lex.l"
-{
-                         yylval.name =  strdup ((const char *)yytext);
-                         return IDENT;
-                       }
+#line 94 "lex.l"
+{ return kw_GeneralizedTime; }
        YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 107 "lex.l"
-;
+#line 95 "lex.l"
+{ return kw_GraphicString; }
        YY_BREAK
 case 34:
-/* rule 34 can match eol */
 YY_RULE_SETUP
-#line 108 "lex.l"
-{ ++lineno; }
+#line 96 "lex.l"
+{ return kw_IA5String; }
        YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 109 "lex.l"
-{ return DOTDOTDOT; }
+#line 97 "lex.l"
+{ return kw_IDENTIFIER; }
        YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 110 "lex.l"
-{ return DOTDOT; }
+#line 98 "lex.l"
+{ return kw_IMPLICIT; }
        YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 111 "lex.l"
-{ error_message("Ignoring char(%c)\n", *yytext); }
+#line 99 "lex.l"
+{ return kw_IMPLIED; }
        YY_BREAK
 case 38:
 YY_RULE_SETUP
+#line 100 "lex.l"
+{ return kw_IMPORTS; }
+       YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 101 "lex.l"
+{ return kw_INCLUDES; }
+       YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 102 "lex.l"
+{ return kw_INSTANCE; }
+       YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 103 "lex.l"
+{ return kw_INTEGER; }
+       YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 104 "lex.l"
+{ return kw_INTERSECTION; }
+       YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 105 "lex.l"
+{ return kw_ISO646String; }
+       YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 106 "lex.l"
+{ return kw_MAX; }
+       YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 107 "lex.l"
+{ return kw_MIN; }
+       YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 108 "lex.l"
+{ return kw_MINUS_INFINITY; }
+       YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 109 "lex.l"
+{ return kw_NULL; }
+       YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 110 "lex.l"
+{ return kw_NumericString; }
+       YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 111 "lex.l"
+{ return kw_OBJECT; }
+       YY_BREAK
+case 50:
+YY_RULE_SETUP
 #line 112 "lex.l"
-ECHO;
+{ return kw_OCTET; }
        YY_BREAK
-#line 1056 "lex.yy.c"
-case YY_STATE_EOF(INITIAL):
-       yyterminate();
-
-       case YY_END_OF_BUFFER:
-               {
-               /* Amount of text matched not including the EOB char. */
-               int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
-
-               /* Undo the effects of YY_DO_BEFORE_ACTION. */
-               *yy_cp = (yy_hold_char);
-               YY_RESTORE_YY_MORE_OFFSET
-
-               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
-                       {
-                       /* We're scanning a new file or input source.  It's
-                        * possible that this happened because the user
-                        * just pointed yyin at a new source and called
-                        * yylex().  If so, then we have to assure
-                        * consistency between YY_CURRENT_BUFFER and our
-                        * globals.  Here is the right place to do so, because
-                        * this is the first action (other than possibly a
-                        * back-up) that will match for the new input source.
-                        */
-                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
-                       }
-
-               /* Note that here we test for yy_c_buf_p "<=" to the position
-                * of the first EOB in the buffer, since yy_c_buf_p will
-                * already have been incremented past the NUL character
-                * (since all states make transitions on EOB to the
-                * end-of-buffer state).  Contrast this with the test
+case 51:
+YY_RULE_SETUP
+#line 113 "lex.l"
+{ return kw_OF; }
+       YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 114 "lex.l"
+{ return kw_OPTIONAL; }
+       YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 115 "lex.l"
+{ return kw_ObjectDescriptor; }
+       YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 116 "lex.l"
+{ return kw_PATTERN; }
+       YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 117 "lex.l"
+{ return kw_PDV; }
+       YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 118 "lex.l"
+{ return kw_PLUS_INFINITY; }
+       YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 119 "lex.l"
+{ return kw_PRESENT; }
+       YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 120 "lex.l"
+{ return kw_PRIVATE; }
+       YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 121 "lex.l"
+{ return kw_PrintableString; }
+       YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 122 "lex.l"
+{ return kw_REAL; }
+       YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 123 "lex.l"
+{ return kw_RELATIVE_OID; }
+       YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 124 "lex.l"
+{ return kw_SEQUENCE; }
+       YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 125 "lex.l"
+{ return kw_SET; }
+       YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 126 "lex.l"
+{ return kw_SIZE; }
+       YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 127 "lex.l"
+{ return kw_STRING; }
+       YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 128 "lex.l"
+{ return kw_SYNTAX; }
+       YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 129 "lex.l"
+{ return kw_T61String; }
+       YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 130 "lex.l"
+{ return kw_TAGS; }
+       YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 131 "lex.l"
+{ return kw_TRUE; }
+       YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 132 "lex.l"
+{ return kw_TYPE_IDENTIFIER; }
+       YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 133 "lex.l"
+{ return kw_TeletexString; }
+       YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 134 "lex.l"
+{ return kw_UNION; }
+       YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 135 "lex.l"
+{ return kw_UNIQUE; }
+       YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 136 "lex.l"
+{ return kw_UNIVERSAL; }
+       YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 137 "lex.l"
+{ return kw_UTCTime; }
+       YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 138 "lex.l"
+{ return kw_UTF8String; }
+       YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 139 "lex.l"
+{ return kw_UniversalString; }
+       YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 140 "lex.l"
+{ return kw_VideotexString; }
+       YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 141 "lex.l"
+{ return kw_VisibleString; }
+       YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 142 "lex.l"
+{ return kw_WITH; }
+       YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 143 "lex.l"
+{ return *yytext; }
+       YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 144 "lex.l"
+{ return *yytext; }
+       YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 145 "lex.l"
+{ return *yytext; }
+       YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 146 "lex.l"
+{ return EEQUAL; }
+       YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 147 "lex.l"
+{ handle_comment(0); }
+       YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 148 "lex.l"
+{ handle_comment(1); }
+       YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 149 "lex.l"
+{ yylval.name = handle_string(); return STRING; }
+       YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 151 "lex.l"
+{ char *e, *y = yytext;
+                         yylval.constant = strtol((const char *)yytext,
+                                                  &e, 0);
+                         if(e == y) 
+                           error_message("malformed constant (%s)", yytext); 
+                         else
+                           return NUMBER;
+                       }
+       YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 159 "lex.l"
+{
+                         yylval.name =  estrdup ((const char *)yytext);
+                         return IDENTIFIER;
+                       }
+       YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 163 "lex.l"
+;
+       YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 164 "lex.l"
+{ ++lineno; }
+       YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 165 "lex.l"
+{ return ELLIPSIS; }
+       YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 166 "lex.l"
+{ return RANGE; }
+       YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 167 "lex.l"
+{ error_message("Ignoring char(%c)\n", *yytext); }
+       YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 168 "lex.l"
+ECHO;
+       YY_BREAK
+#line 1485 "lex.yy.c"
+case YY_STATE_EOF(INITIAL):
+       yyterminate();
+
+       case YY_END_OF_BUFFER:
+               {
+               /* Amount of text matched not including the EOB char. */
+               int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
+
+               /* Undo the effects of YY_DO_BEFORE_ACTION. */
+               *yy_cp = yy_hold_char;
+               YY_RESTORE_YY_MORE_OFFSET
+
+               if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+                       {
+                       /* We're scanning a new file or input source.  It's
+                        * possible that this happened because the user
+                        * just pointed yyin at a new source and called
+                        * yylex().  If so, then we have to assure
+                        * consistency between yy_current_buffer and our
+                        * globals.  Here is the right place to do so, because
+                        * this is the first action (other than possibly a
+                        * back-up) that will match for the new input source.
+                        */
+                       yy_n_chars = yy_current_buffer->yy_n_chars;
+                       yy_current_buffer->yy_input_file = yyin;
+                       yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+                       }
+
+               /* Note that here we test for yy_c_buf_p "<=" to the position
+                * of the first EOB in the buffer, since yy_c_buf_p will
+                * already have been incremented past the NUL character
+                * (since all states make transitions on EOB to the
+                * end-of-buffer state).  Contrast this with the test
                 * in input().
                 */
-               if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+               if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
                        { /* This was really a NUL. */
                        yy_state_type yy_next_state;
 
-                       (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+                       yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
 
-                       yy_current_state = yy_get_previous_state(  );
+                       yy_current_state = yy_get_previous_state();
 
                        /* Okay, we're now positioned to make the NUL
                         * transition.  We couldn't have
@@ -1107,30 +1536,30 @@ case YY_STATE_EOF(INITIAL):
 
                        yy_next_state = yy_try_NUL_trans( yy_current_state );
 
-                       yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                       yy_bp = yytext_ptr + YY_MORE_ADJ;
 
                        if ( yy_next_state )
                                {
                                /* Consume the NUL. */
-                               yy_cp = ++(yy_c_buf_p);
+                               yy_cp = ++yy_c_buf_p;
                                yy_current_state = yy_next_state;
                                goto yy_match;
                                }
 
                        else
                                {
-                               yy_cp = (yy_c_buf_p);
+                               yy_cp = yy_c_buf_p;
                                goto yy_find_action;
                                }
                        }
 
-               else switch ( yy_get_next_buffer(  ) )
+               else switch ( yy_get_next_buffer() )
                        {
                        case EOB_ACT_END_OF_FILE:
                                {
-                               (yy_did_buffer_switch_on_eof) = 0;
+                               yy_did_buffer_switch_on_eof = 0;
 
-                               if ( yywrap( ) )
+                               if ( yywrap() )
                                        {
                                        /* Note: because we've taken care in
                                         * yy_get_next_buffer() to have set up
@@ -1141,7 +1570,7 @@ case YY_STATE_EOF(INITIAL):
                                         * YY_NULL, it'll still work - another
                                         * YY_NULL will get returned.
                                         */
-                                       (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+                                       yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
 
                                        yy_act = YY_STATE_EOF(YY_START);
                                        goto do_action;
@@ -1149,30 +1578,30 @@ case YY_STATE_EOF(INITIAL):
 
                                else
                                        {
-                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                       if ( ! yy_did_buffer_switch_on_eof )
                                                YY_NEW_FILE;
                                        }
                                break;
                                }
 
                        case EOB_ACT_CONTINUE_SCAN:
-                               (yy_c_buf_p) =
-                                       (yytext_ptr) + yy_amount_of_matched_text;
+                               yy_c_buf_p =
+                                       yytext_ptr + yy_amount_of_matched_text;
 
-                               yy_current_state = yy_get_previous_state(  );
+                               yy_current_state = yy_get_previous_state();
 
-                               yy_cp = (yy_c_buf_p);
-                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
                                goto yy_match;
 
                        case EOB_ACT_LAST_MATCH:
-                               (yy_c_buf_p) =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+                               yy_c_buf_p =
+                               &yy_current_buffer->yy_ch_buf[yy_n_chars];
 
-                               yy_current_state = yy_get_previous_state(  );
+                               yy_current_state = yy_get_previous_state();
 
-                               yy_cp = (yy_c_buf_p);
-                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
                                goto yy_find_action;
                        }
                break;
@@ -1183,7 +1612,8 @@ case YY_STATE_EOF(INITIAL):
                        "fatal flex scanner internal error--no action found" );
        } /* end of action switch */
                } /* end of scanning one token */
-} /* end of yylex */
+       } /* end of yylex */
+
 
 /* yy_get_next_buffer - try to read in a new buffer
  *
@@ -1192,20 +1622,21 @@ case YY_STATE_EOF(INITIAL):
  *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  *     EOB_ACT_END_OF_FILE - end of file
  */
-static int yy_get_next_buffer (void)
-{
-       register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-       register char *source = (yytext_ptr);
+
+static int yy_get_next_buffer()
+       {
+       register char *dest = yy_current_buffer->yy_ch_buf;
+       register char *source = yytext_ptr;
        register int number_to_move, i;
        int ret_val;
 
-       if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+       if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
                YY_FATAL_ERROR(
                "fatal flex scanner internal error--end of buffer missed" );
 
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+       if ( yy_current_buffer->yy_fill_buffer == 0 )
                { /* Don't try to fill the buffer, so this is an EOF. */
-               if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+               if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
                        {
                        /* We matched a single character, the EOB, so
                         * treat this as a final EOF.
@@ -1225,30 +1656,34 @@ static int yy_get_next_buffer (void)
        /* Try to read more data. */
 
        /* First move last chars to start of buffer. */
-       number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+       number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
 
        for ( i = 0; i < number_to_move; ++i )
                *(dest++) = *(source++);
 
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+       if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
                /* don't do the read, it's not guaranteed to return an EOF,
                 * just force an EOF
                 */
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+               yy_current_buffer->yy_n_chars = yy_n_chars = 0;
 
        else
                {
-                       size_t num_to_read =
-                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+               int num_to_read =
+                       yy_current_buffer->yy_buf_size - number_to_move - 1;
 
                while ( num_to_read <= 0 )
                        { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+                       YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
 
                        /* just a shorter name for the current buffer */
-                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+                       YY_BUFFER_STATE b = yy_current_buffer;
 
                        int yy_c_buf_p_offset =
-                               (int) ((yy_c_buf_p) - b->yy_ch_buf);
+                               (int) (yy_c_buf_p - b->yy_ch_buf);
 
                        if ( b->yy_is_our_buffer )
                                {
@@ -1261,7 +1696,8 @@ static int yy_get_next_buffer (void)
 
                                b->yy_ch_buf = (char *)
                                        /* Include room in for 2 EOB chars. */
-                                       yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+                                       yy_flex_realloc( (void *) b->yy_ch_buf,
+                                                        b->yy_buf_size + 2 );
                                }
                        else
                                /* Can't grow it, we don't own it. */
@@ -1271,35 +1707,35 @@ static int yy_get_next_buffer (void)
                                YY_FATAL_ERROR(
                                "fatal error - scanner input buffer overflow" );
 
-                       (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+                       yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
 
-                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+                       num_to_read = yy_current_buffer->yy_buf_size -
                                                number_to_move - 1;
-
+#endif
                        }
 
                if ( num_to_read > YY_READ_BUF_SIZE )
                        num_to_read = YY_READ_BUF_SIZE;
 
                /* Read in more data. */
-               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                       (yy_n_chars), num_to_read );
+               YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+                       yy_n_chars, num_to_read );
 
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               yy_current_buffer->yy_n_chars = yy_n_chars;
                }
 
-       if ( (yy_n_chars) == 0 )
+       if ( yy_n_chars == 0 )
                {
                if ( number_to_move == YY_MORE_ADJ )
                        {
                        ret_val = EOB_ACT_END_OF_FILE;
-                       yyrestart(yyin  );
+                       yyrestart( yyin );
                        }
 
                else
                        {
                        ret_val = EOB_ACT_LAST_MATCH;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+                       yy_current_buffer->yy_buffer_status =
                                YY_BUFFER_EOF_PENDING;
                        }
                }
@@ -1307,137 +1743,153 @@ static int yy_get_next_buffer (void)
        else
                ret_val = EOB_ACT_CONTINUE_SCAN;
 
-       (yy_n_chars) += number_to_move;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+       yy_n_chars += number_to_move;
+       yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+       yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
 
-       (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+       yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
 
        return ret_val;
-}
+       }
+
 
 /* yy_get_previous_state - get the state just before the EOB char was reached */
 
-    static yy_state_type yy_get_previous_state (void)
-{
+static yy_state_type yy_get_previous_state()
+       {
        register yy_state_type yy_current_state;
        register char *yy_cp;
-    
-       yy_current_state = (yy_start);
 
-       for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+       yy_current_state = yy_start;
+
+       for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
                {
                register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
                if ( yy_accept[yy_current_state] )
                        {
-                       (yy_last_accepting_state) = yy_current_state;
-                       (yy_last_accepting_cpos) = yy_cp;
+                       yy_last_accepting_state = yy_current_state;
+                       yy_last_accepting_cpos = yy_cp;
                        }
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 183 )
+                       if ( yy_current_state >= 568 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                }
 
        return yy_current_state;
-}
+       }
+
 
 /* yy_try_NUL_trans - try to make a transition on the NUL character
  *
  * synopsis
  *     next_state = yy_try_NUL_trans( current_state );
  */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
-{
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+       {
        register int yy_is_jam;
-       register char *yy_cp = (yy_c_buf_p);
+       register char *yy_cp = yy_c_buf_p;
 
        register YY_CHAR yy_c = 1;
        if ( yy_accept[yy_current_state] )
                {
-               (yy_last_accepting_state) = yy_current_state;
-               (yy_last_accepting_cpos) = yy_cp;
+               yy_last_accepting_state = yy_current_state;
+               yy_last_accepting_cpos = yy_cp;
                }
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 183 )
+               if ( yy_current_state >= 568 )
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 182);
+       yy_is_jam = (yy_current_state == 567);
 
        return yy_is_jam ? 0 : yy_current_state;
-}
+       }
 
-    static void yyunput (int c, register char * yy_bp )
-{
-       register char *yy_cp;
-    
-    yy_cp = (yy_c_buf_p);
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+       {
+       register char *yy_cp = yy_c_buf_p;
 
        /* undo effects of setting up yytext */
-       *yy_cp = (yy_hold_char);
+       *yy_cp = yy_hold_char;
 
-       if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+       if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
                { /* need to shift things up to make room */
                /* +2 for EOB chars. */
-               register int number_to_move = (yy_n_chars) + 2;
-               register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
-                                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+               register int number_to_move = yy_n_chars + 2;
+               register char *dest = &yy_current_buffer->yy_ch_buf[
+                                       yy_current_buffer->yy_buf_size + 2];
                register char *source =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+                               &yy_current_buffer->yy_ch_buf[number_to_move];
 
-               while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+               while ( source > yy_current_buffer->yy_ch_buf )
                        *--dest = *--source;
 
                yy_cp += (int) (dest - source);
                yy_bp += (int) (dest - source);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+               yy_current_buffer->yy_n_chars =
+                       yy_n_chars = yy_current_buffer->yy_buf_size;
 
-               if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+               if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
                        YY_FATAL_ERROR( "flex scanner push-back overflow" );
                }
 
        *--yy_cp = (char) c;
 
-       (yytext_ptr) = yy_bp;
-       (yy_hold_char) = *yy_cp;
-       (yy_c_buf_p) = yy_cp;
-}
+
+       yytext_ptr = yy_bp;
+       yy_hold_char = *yy_cp;
+       yy_c_buf_p = yy_cp;
+       }
+#endif /* ifndef YY_NO_UNPUT */
+
 
 #ifndef YY_NO_INPUT
 #ifdef __cplusplus
-    static int yyinput (void)
+static int yyinput()
 #else
-    static int input  (void)
+static int input()
 #endif
-
-{
+       {
        int c;
-    
-       *(yy_c_buf_p) = (yy_hold_char);
 
-       if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+       *yy_c_buf_p = yy_hold_char;
+
+       if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
                {
                /* yy_c_buf_p now points to the character we want to return.
                 * If this occurs *before* the EOB characters, then it's a
                 * valid NUL; if not, then we've hit the end of the buffer.
                 */
-               if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+               if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
                        /* This was really a NUL. */
-                       *(yy_c_buf_p) = '\0';
+                       *yy_c_buf_p = '\0';
 
                else
                        { /* need more input */
-                       int offset = (yy_c_buf_p) - (yytext_ptr);
-                       ++(yy_c_buf_p);
+                       int offset = yy_c_buf_p - yytext_ptr;
+                       ++yy_c_buf_p;
 
-                       switch ( yy_get_next_buffer(  ) )
+                       switch ( yy_get_next_buffer() )
                                {
                                case EOB_ACT_LAST_MATCH:
                                        /* This happens because yy_g_n_b()
@@ -1451,16 +1903,16 @@ static int yy_get_next_buffer (void)
                                         */
 
                                        /* Reset buffer status. */
-                                       yyrestart(yyin );
+                                       yyrestart( yyin );
 
-                                       /*FALLTHROUGH*/
+                                       /* fall through */
 
                                case EOB_ACT_END_OF_FILE:
                                        {
-                                       if ( yywrap( ) )
+                                       if ( yywrap() )
                                                return EOF;
 
-                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                       if ( ! yy_did_buffer_switch_on_eof )
                                                YY_NEW_FILE;
 #ifdef __cplusplus
                                        return yyinput();
@@ -1470,92 +1922,90 @@ static int yy_get_next_buffer (void)
                                        }
 
                                case EOB_ACT_CONTINUE_SCAN:
-                                       (yy_c_buf_p) = (yytext_ptr) + offset;
+                                       yy_c_buf_p = yytext_ptr + offset;
                                        break;
                                }
                        }
                }
 
-       c = *(unsigned char *) (yy_c_buf_p);    /* cast for 8-bit char's */
-       *(yy_c_buf_p) = '\0';   /* preserve yytext */
-       (yy_hold_char) = *++(yy_c_buf_p);
+       c = *(unsigned char *) yy_c_buf_p;      /* cast for 8-bit char's */
+       *yy_c_buf_p = '\0';     /* preserve yytext */
+       yy_hold_char = *++yy_c_buf_p;
+
 
        return c;
-}
-#endif /* ifndef YY_NO_INPUT */
+       }
+#endif /* YY_NO_INPUT */
 
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * 
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void yyrestart  (FILE * input_file )
-{
-    
-       if ( ! YY_CURRENT_BUFFER ){
-        yyensure_buffer_stack ();
-               YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer(yyin,YY_BUF_SIZE );
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+       {
+       if ( ! yy_current_buffer )
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+       yy_init_buffer( yy_current_buffer, input_file );
+       yy_load_buffer_state();
        }
 
-       yy_init_buffer(YY_CURRENT_BUFFER,input_file );
-       yy_load_buffer_state( );
-}
 
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * 
- */
-    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
-{
-    
-       /* TODO. We should be able to replace this entire function body
-        * with
-        *              yypop_buffer_state();
-        *              yypush_buffer_state(new_buffer);
-     */
-       yyensure_buffer_stack ();
-       if ( YY_CURRENT_BUFFER == new_buffer )
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+       {
+       if ( yy_current_buffer == new_buffer )
                return;
 
-       if ( YY_CURRENT_BUFFER )
+       if ( yy_current_buffer )
                {
                /* Flush out information for old buffer. */
-               *(yy_c_buf_p) = (yy_hold_char);
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               *yy_c_buf_p = yy_hold_char;
+               yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+               yy_current_buffer->yy_n_chars = yy_n_chars;
                }
 
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-       yy_load_buffer_state( );
+       yy_current_buffer = new_buffer;
+       yy_load_buffer_state();
 
        /* We don't actually know whether we did this switch during
         * EOF (yywrap()) processing, but the only time this flag
         * is looked at is after yywrap() is called, so it's safe
         * to go ahead and always set it.
         */
-       (yy_did_buffer_switch_on_eof) = 1;
-}
+       yy_did_buffer_switch_on_eof = 1;
+       }
 
-static void yy_load_buffer_state  (void)
-{
-       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-       (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-       (yy_hold_char) = *(yy_c_buf_p);
-}
 
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * 
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
-{
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+       {
+       yy_n_chars = yy_current_buffer->yy_n_chars;
+       yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+       yyin = yy_current_buffer->yy_input_file;
+       yy_hold_char = *yy_c_buf_p;
+       }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+       {
        YY_BUFFER_STATE b;
-    
-       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
@@ -1564,75 +2014,75 @@ static void yy_load_buffer_state  (void)
        /* yy_ch_buf has to be 2 characters longer than the size given because
         * we need to put in 2 end-of-buffer characters.
         */
-       b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+       b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
        if ( ! b->yy_ch_buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
        b->yy_is_our_buffer = 1;
 
-       yy_init_buffer(b,file );
+       yy_init_buffer( b, file );
 
        return b;
-}
+       }
 
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- * 
- */
-    void yy_delete_buffer (YY_BUFFER_STATE  b )
-{
-    
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+       {
        if ( ! b )
                return;
 
-       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+       if ( b == yy_current_buffer )
+               yy_current_buffer = (YY_BUFFER_STATE) 0;
 
        if ( b->yy_is_our_buffer )
-               yyfree((void *) b->yy_ch_buf  );
+               yy_flex_free( (void *) b->yy_ch_buf );
 
-       yyfree((void *) b  );
-}
+       yy_flex_free( (void *) b );
+       }
 
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-    
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
-    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
 
-{
-       int oerrno = errno;
-    
-       yy_flush_buffer(b );
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+       {
+       yy_flush_buffer( b );
 
        b->yy_input_file = file;
        b->yy_fill_buffer = 1;
 
-    /* If b is the current buffer, then yy_init_buffer was _probably_
-     * called from yyrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
+#if YY_ALWAYS_INTERACTIVE
+       b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+       b->yy_is_interactive = 0;
+#else
+       b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+       }
 
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-    
-       errno = oerrno;
-}
 
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * 
- */
-    void yy_flush_buffer (YY_BUFFER_STATE  b )
-{
-       if ( ! b )
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+       {
+       if ( ! b )
                return;
 
        b->yy_n_chars = 0;
@@ -1649,121 +2099,29 @@ extern int isatty (int );
        b->yy_at_bol = 1;
        b->yy_buffer_status = YY_BUFFER_NEW;
 
-       if ( b == YY_CURRENT_BUFFER )
-               yy_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
-       if (new_buffer == NULL)
-               return;
-
-       yyensure_buffer_stack();
-
-       /* This block is copied from yy_switch_to_buffer. */
-       if ( YY_CURRENT_BUFFER )
-               {
-               /* Flush out information for old buffer. */
-               *(yy_c_buf_p) = (yy_hold_char);
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-               }
-
-       /* Only push if top exists. Otherwise, replace top. */
-       if (YY_CURRENT_BUFFER)
-               (yy_buffer_stack_top)++;
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-       /* copied from yy_switch_to_buffer. */
-       yy_load_buffer_state( );
-       (yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  
- */
-void yypop_buffer_state (void)
-{
-       if (!YY_CURRENT_BUFFER)
-               return;
-
-       yy_delete_buffer(YY_CURRENT_BUFFER );
-       YY_CURRENT_BUFFER_LVALUE = NULL;
-       if ((yy_buffer_stack_top) > 0)
-               --(yy_buffer_stack_top);
-
-       if (YY_CURRENT_BUFFER) {
-               yy_load_buffer_state( );
-               (yy_did_buffer_switch_on_eof) = 1;
+       if ( b == yy_current_buffer )
+               yy_load_buffer_state();
        }
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
-       int num_to_alloc;
-    
-       if (!(yy_buffer_stack)) {
-
-               /* First allocation is just for 2 elements, since we don't know if this
-                * scanner will even need a stack. We use 2 instead of 1 to avoid an
-                * immediate realloc on the next call.
-         */
-               num_to_alloc = 1;
-               (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
-                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               );
-               
-               memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-                               
-               (yy_buffer_stack_max) = num_to_alloc;
-               (yy_buffer_stack_top) = 0;
-               return;
-       }
-
-       if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
-               /* Increase the buffer to prepare for a possible push. */
-               int grow_size = 8 /* arbitrary grow size */;
-
-               num_to_alloc = (yy_buffer_stack_max) + grow_size;
-               (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
-                                                               ((yy_buffer_stack),
-                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               );
 
-               /* zero only the new slots.*/
-               memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
-               (yy_buffer_stack_max) = num_to_alloc;
-       }
-}
 
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * 
- * @return the newly allocated buffer state object. 
- */
-YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
-{
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+       {
        YY_BUFFER_STATE b;
-    
+
        if ( size < 2 ||
             base[size-2] != YY_END_OF_BUFFER_CHAR ||
             base[size-1] != YY_END_OF_BUFFER_CHAR )
                /* They forgot to leave room for the EOB's. */
                return 0;
 
-       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
 
@@ -1777,42 +2135,47 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
        b->yy_fill_buffer = 0;
        b->yy_buffer_status = YY_BUFFER_NEW;
 
-       yy_switch_to_buffer( );
+       yy_switch_to_buffer( b );
 
        return b;
-}
+       }
+#endif
 
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
- * 
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yy_str )
-{
-    
-       return yy_scan_bytes(yy_str,strlen(yy_str) );
-}
 
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * bytes, int  len )
-{
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+       {
+       int len;
+       for ( len = 0; yy_str[len]; ++len )
+               ;
+
+       return yy_scan_bytes( yy_str, len );
+       }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+       {
        YY_BUFFER_STATE b;
        char *buf;
        yy_size_t n;
        int i;
-    
+
        /* Get memory for full buffer, including space for trailing EOB's. */
        n = len + 2;
-       buf = (char *) yyalloc(n  );
+       buf = (char *) yy_flex_alloc( n );
        if ( ! buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
 
@@ -1821,7 +2184,7 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * bytes, int  len )
 
        buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
 
-       b = yy_scan_buffer(buf,n );
+       b = yy_scan_buffer( buf, n );
        if ( ! b )
                YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
 
@@ -1831,164 +2194,148 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * bytes, int  len )
        b->yy_is_our_buffer = 1;
 
        return b;
-}
+       }
+#endif
 
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
 #endif
+       {
+       if ( yy_start_stack_ptr >= yy_start_stack_depth )
+               {
+               yy_size_t new_size;
 
-static void yy_fatal_error (yyconst char* msg )
-{
-       (void) fprintf( stderr, "%s\n", msg );
-       exit( YY_EXIT_FAILURE );
-}
+               yy_start_stack_depth += YY_START_STACK_INCR;
+               new_size = yy_start_stack_depth * sizeof( int );
 
-/* Redefine yyless() so it works in section 3 code. */
+               if ( ! yy_start_stack )
+                       yy_start_stack = (int *) yy_flex_alloc( new_size );
 
-#undef yyless
-#define yyless(n) \
-       do \
-               { \
-               /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               yytext[yyleng] = (yy_hold_char); \
-               (yy_c_buf_p) = yytext + yyless_macro_arg; \
-               (yy_hold_char) = *(yy_c_buf_p); \
-               *(yy_c_buf_p) = '\0'; \
-               yyleng = yyless_macro_arg; \
-               } \
-       while ( 0 )
+               else
+                       yy_start_stack = (int *) yy_flex_realloc(
+                                       (void *) yy_start_stack, new_size );
 
-/* Accessor  methods (get/set functions) to struct members. */
+               if ( ! yy_start_stack )
+                       YY_FATAL_ERROR(
+                       "out of memory expanding start-condition stack" );
+               }
 
-/** Get the current line number.
- * 
- */
-int yyget_lineno  (void)
-{
-        
-    return yylineno;
-}
+       yy_start_stack[yy_start_stack_ptr++] = YY_START;
 
-/** Get the input stream.
- * 
- */
-FILE *yyget_in  (void)
-{
-        return yyin;
-}
+       BEGIN(new_state);
+       }
+#endif
 
-/** Get the output stream.
- * 
- */
-FILE *yyget_out  (void)
-{
-        return yyout;
-}
 
-/** Get the length of the current token.
- * 
- */
-int yyget_leng  (void)
-{
-        return yyleng;
-}
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+       {
+       if ( --yy_start_stack_ptr < 0 )
+               YY_FATAL_ERROR( "start-condition stack underflow" );
 
-/** Get the current token.
- * 
- */
+       BEGIN(yy_start_stack[yy_start_stack_ptr]);
+       }
+#endif
 
-char *yyget_text  (void)
-{
-        return yytext;
-}
 
-/** Set the current line number.
- * @param line_number
- * 
- */
-void yyset_lineno (int  line_number )
-{
-    
-    yylineno = line_number;
-}
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+       {
+       return yy_start_stack[yy_start_stack_ptr - 1];
+       }
+#endif
 
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * 
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE *  in_str )
-{
-        yyin = in_str ;
-}
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
 
-void yyset_out (FILE *  out_str )
-{
-        yyout = out_str ;
-}
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+       {
+       (void) fprintf( stderr, "%s\n", msg );
+       exit( YY_EXIT_FAILURE );
+       }
 
-int yyget_debug  (void)
-{
-        return yy_flex_debug;
-}
 
-void yyset_debug (int  bdebug )
-{
-        yy_flex_debug = bdebug ;
-}
 
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy  (void)
-{
-    
-    /* Pop the buffer stack, destroying each element. */
-       while(YY_CURRENT_BUFFER){
-               yy_delete_buffer(YY_CURRENT_BUFFER  );
-               YY_CURRENT_BUFFER_LVALUE = NULL;
-               yypop_buffer_state();
-       }
+/* Redefine yyless() so it works in section 3 code. */
 
-       /* Destroy the stack itself. */
-       yyfree((yy_buffer_stack) );
-       (yy_buffer_stack) = NULL;
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+               yytext[yyleng] = yy_hold_char; \
+               yy_c_buf_p = yytext + n; \
+               yy_hold_char = *yy_c_buf_p; \
+               *yy_c_buf_p = '\0'; \
+               yyleng = n; \
+               } \
+       while ( 0 )
 
-    return 0;
-}
 
-/*
- * Internal utility routines.
- */
+/* Internal utility routines. */
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+       {
        register int i;
-       for ( i = 0; i < n; ++i )
+       for ( i = 0; i < n; ++i )
                s1[i] = s2[i];
-}
+       }
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+       {
        register int n;
-       for ( n = 0; s[n]; ++n )
+       for ( n = 0; s[n]; ++n )
                ;
 
        return n;
-}
+       }
 #endif
 
-void *yyalloc (yy_size_t  size )
-{
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+       {
        return (void *) malloc( size );
-}
+       }
 
-void *yyrealloc  (void * ptr, yy_size_t  size )
-{
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+       {
        /* The cast to (char *) in the following accommodates both
         * implementations that use char* generic pointers, and those
         * that use void* generic pointers.  It works with the latter
@@ -1997,29 +2344,26 @@ void *yyrealloc  (void * ptr, yy_size_t  size )
         * as though doing an assignment.
         */
        return (void *) realloc( (char *) ptr, size );
-}
-
-void yyfree (void * ptr )
-{
-       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef yytext_ptr
-#undef YY_DO_BEFORE_ACTION
+       }
 
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
 #endif
-#line 112 "lex.l"
+       {
+       free( ptr );
+       }
 
+#if YY_MAIN
+int main()
+       {
+       yylex();
+       return 0;
+       }
+#endif
+#line 168 "lex.l"
 
 
 #ifndef yywrap /* XXX */
@@ -2039,6 +2383,7 @@ error_message (const char *format, ...)
      fprintf (stderr, "%s:%d: ", get_filename(), lineno);
      vfprintf (stderr, format, args);
      va_end (args);
+     error_flag++;
 }
 
 static void
@@ -2076,6 +2421,12 @@ handle_comment(int type)
                seen_slash = 1;
                continue;
            }
+           if(seen_star && c == '/') {
+               if(--level == 0)
+                   return;
+               seen_star = 0;
+               continue;
+           }
            if(c == '*') {
                if(seen_slash) {
                    level++;
@@ -2096,3 +2447,49 @@ handle_comment(int type)
        error_message("unterminated comment, possibly started on line %d\n", start_lineno);
 }
 
+static char *
+handle_string(void)
+{
+    int start_lineno = lineno;
+    int c;
+    char buf[1024];
+    char *p = buf;
+    int f = 0;
+    int skip_ws = 0;
+
+    while((c = input()) != EOF) {
+       if(isspace(c) && skip_ws) {
+           if(c == '\n')
+               lineno++;
+           continue;
+       }
+       skip_ws = 0;
+
+       if(c == '"') {
+           if(f) {
+               *p++ = '"';
+               f = 0;
+           } else
+               f = 1;
+           continue;
+       }
+       if(f == 1) {
+           unput(c);
+           break;
+       }
+       if(c == '\n') {
+           lineno++;
+           while(p > buf && isspace((unsigned char)p[-1]))
+               p--;
+           skip_ws = 1;
+           continue;
+       }
+       *p++ = c;
+    }
+    if(c == EOF)
+       error_message("unterminated string, possibly started on line %d\n", start_lineno);
+    *p++ = '\0';
+    fprintf(stderr, "string -- %s\n", buf);
+    return estrdup(buf);
+}
+    
index 9f5cadf92b84077172c95e84d836bcde3bfbe428..2d9e6745c5a611b9f21d24e2e697dc999d0adc5a 100644 (file)
  * SUCH DAMAGE. 
  */
 
-/* $Id: lex.h,v 1.5 2000/07/01 20:21:34 assar Exp $ */
+/* $Id: lex.h,v 1.6 2005/07/12 06:27:33 lha Exp $ */
 
 #include <roken.h>
 
 void error_message (const char *, ...)
 __attribute__ ((format (printf, 1, 2)));
+extern int error_flag;
 
 int yylex(void);
index f0c123404a4ee4e2f60f67986e72798ff361573d..cb6512f36f4a3ad3170045800dd8bb05944bf3a6 100644 (file)
@@ -1,6 +1,6 @@
 %{
 /*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -32,7 +32,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: lex.l,v 1.25 2005/06/16 19:58:35 lha Exp $ */
+/* $Id: lex.l,v 1.26 2005/07/12 06:27:33 lha Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 
 static unsigned lineno = 1;
 
-#define YY_NO_UNPUT
-
 #undef ECHO
 
 static void handle_comment(int type);
-
+static char *handle_string(void);
 %}
 
 
 %%
-INTEGER                        { return INTEGER; }
-BOOLEAN                        { return BOOLEAN; }
-IMPORTS                        { return IMPORTS; }
-FROM                   { return FROM; }
-SEQUENCE               { return SEQUENCE; }
-CHOICE                 { return CHOICE; }
-OF                     { return OF; }
-OCTET                  { return OCTET; }
-STRING                 { return STRING; }
-GeneralizedTime                { return GeneralizedTime; }
-GeneralString          { return GeneralString; }
-UTF8String             { return UTF8String; }
-NULL                   { return NULLTYPE; }
-BIT                    { return BIT; }
-APPLICATION            { return APPLICATION; }
-OPTIONAL               { return OPTIONAL; }
-BEGIN                  { return TBEGIN; }
-END                    { return END; }
-DEFAULT                        { return DEFAULT; }
-DEFINITIONS            { return DEFINITIONS; }
-ENUMERATED             { return ENUMERATED; }
-EXTERNAL               { return EXTERNAL; }
-OBJECT                 { return OBJECT; }
-IDENTIFIER             { return IDENTIFIER; }
-[-,;{}()|\"]           { return *yytext; }
+ABSENT                 { return kw_ABSENT; }
+ABSTRACT-SYNTAX                { return kw_ABSTRACT_SYNTAX; }
+ALL                    { return kw_ALL; }
+APPLICATION            { return kw_APPLICATION; }
+AUTOMATIC              { return kw_AUTOMATIC; }
+BEGIN                  { return kw_BEGIN; }
+BIT                    { return kw_BIT; }
+BMPString              { return kw_BMPString; }
+BOOLEAN                        { return kw_BOOLEAN; }
+BY                     { return kw_BY; }
+CHARACTER              { return kw_CHARACTER; }
+CHOICE                 { return kw_CHOICE; }
+CLASS                  { return kw_CLASS; }
+COMPONENT              { return kw_COMPONENT; }
+COMPONENTS             { return kw_COMPONENTS; }
+CONSTRAINED            { return kw_CONSTRAINED; }
+CONTAINING             { return kw_CONTAINING; }
+DEFAULT                        { return kw_DEFAULT; }
+DEFINITIONS            { return kw_DEFINITIONS; }
+EMBEDDED               { return kw_EMBEDDED; }
+ENCODED                        { return kw_ENCODED; }
+END                    { return kw_END; }
+ENUMERATED             { return kw_ENUMERATED; }
+EXCEPT                 { return kw_EXCEPT; }
+EXPLICIT               { return kw_EXPLICIT; }
+EXPORTS                        { return kw_EXPORTS; }
+EXTENSIBILITY          { return kw_EXTENSIBILITY; }
+EXTERNAL               { return kw_EXTERNAL; }
+FALSE                  { return kw_FALSE; }
+FROM                   { return kw_FROM; }
+GeneralString          { return kw_GeneralString; }
+GeneralizedTime                { return kw_GeneralizedTime; }
+GraphicString          { return kw_GraphicString; }
+IA5String              { return kw_IA5String; }
+IDENTIFIER             { return kw_IDENTIFIER; }
+IMPLICIT               { return kw_IMPLICIT; }
+IMPLIED                        { return kw_IMPLIED; }
+IMPORTS                        { return kw_IMPORTS; }
+INCLUDES               { return kw_INCLUDES; }
+INSTANCE               { return kw_INSTANCE; }
+INTEGER                        { return kw_INTEGER; }
+INTERSECTION           { return kw_INTERSECTION; }
+ISO646String           { return kw_ISO646String; }
+MAX                    { return kw_MAX; }
+MIN                    { return kw_MIN; }
+MINUS-INFINITY         { return kw_MINUS_INFINITY; }
+NULL                   { return kw_NULL; }
+NumericString          { return kw_NumericString; }
+OBJECT                 { return kw_OBJECT; }
+OCTET                  { return kw_OCTET; }
+OF                     { return kw_OF; }
+OPTIONAL               { return kw_OPTIONAL; }
+ObjectDescriptor       { return kw_ObjectDescriptor; }
+PATTERN                        { return kw_PATTERN; }
+PDV                    { return kw_PDV; }
+PLUS-INFINITY          { return kw_PLUS_INFINITY; }
+PRESENT                        { return kw_PRESENT; }
+PRIVATE                        { return kw_PRIVATE; }
+PrintableString                { return kw_PrintableString; }
+REAL                   { return kw_REAL; }
+RELATIVE_OID           { return kw_RELATIVE_OID; }
+SEQUENCE               { return kw_SEQUENCE; }
+SET                    { return kw_SET; }
+SIZE                   { return kw_SIZE; }
+STRING                 { return kw_STRING; }
+SYNTAX                 { return kw_SYNTAX; }
+T61String              { return kw_T61String; }
+TAGS                   { return kw_TAGS; }
+TRUE                   { return kw_TRUE; }
+TYPE-IDENTIFIER                { return kw_TYPE_IDENTIFIER; }
+TeletexString          { return kw_TeletexString; }
+UNION                  { return kw_UNION; }
+UNIQUE                 { return kw_UNIQUE; }
+UNIVERSAL              { return kw_UNIVERSAL; }
+UTCTime                        { return kw_UTCTime; }
+UTF8String             { return kw_UTF8String; }
+UniversalString                { return kw_UniversalString; }
+VideotexString         { return kw_VideotexString; }
+VisibleString          { return kw_VisibleString; }
+WITH                   { return kw_WITH; }
+[-,;{}()|]             { return *yytext; }
 "["                    { return *yytext; }
 "]"                    { return *yytext; }
 ::=                    { return EEQUAL; }
 --                     { handle_comment(0); }
 \/\*                   { handle_comment(1); }
-0x[0-9A-Fa-f]+|[0-9]+  { char *e, *y = yytext;
+"\""                   { yylval.name = handle_string(); return STRING; }
+
+-?0x[0-9A-Fa-f]+|-?[0-9]+ { char *e, *y = yytext;
                          yylval.constant = strtol((const char *)yytext,
                                                   &e, 0);
                          if(e == y) 
                            error_message("malformed constant (%s)", yytext); 
                          else
-                           return CONSTANT;
+                           return NUMBER;
                        }
 [A-Za-z][-A-Za-z0-9_]* {
-                         yylval.name =  strdup ((const char *)yytext);
-                         return IDENT;
+                         yylval.name =  estrdup ((const char *)yytext);
+                         return IDENTIFIER;
                        }
 [ \t]                  ;
 \n                     { ++lineno; }
-\.\.\.                 { return DOTDOTDOT; }
-\.\.                   { return DOTDOT; }
+\.\.\.                 { return ELLIPSIS; }
+\.\.                   { return RANGE; }
 .                      { error_message("Ignoring char(%c)\n", *yytext); }
 %%
 
@@ -128,6 +184,7 @@ error_message (const char *format, ...)
      fprintf (stderr, "%s:%d: ", get_filename(), lineno);
      vfprintf (stderr, format, args);
      va_end (args);
+     error_flag++;
 }
 
 static void
@@ -165,6 +222,12 @@ handle_comment(int type)
                seen_slash = 1;
                continue;
            }
+           if(seen_star && c == '/') {
+               if(--level == 0)
+                   return;
+               seen_star = 0;
+               continue;
+           }
            if(c == '*') {
                if(seen_slash) {
                    level++;
@@ -184,3 +247,50 @@ handle_comment(int type)
     if(c == EOF)
        error_message("unterminated comment, possibly started on line %d\n", start_lineno);
 }
+
+static char *
+handle_string(void)
+{
+    int start_lineno = lineno;
+    int c;
+    char buf[1024];
+    char *p = buf;
+    int f = 0;
+    int skip_ws = 0;
+
+    while((c = input()) != EOF) {
+       if(isspace(c) && skip_ws) {
+           if(c == '\n')
+               lineno++;
+           continue;
+       }
+       skip_ws = 0;
+
+       if(c == '"') {
+           if(f) {
+               *p++ = '"';
+               f = 0;
+           } else
+               f = 1;
+           continue;
+       }
+       if(f == 1) {
+           unput(c);
+           break;
+       }
+       if(c == '\n') {
+           lineno++;
+           while(p > buf && isspace((unsigned char)p[-1]))
+               p--;
+           skip_ws = 1;
+           continue;
+       }
+       *p++ = c;
+    }
+    if(c == EOF)
+       error_message("unterminated string, possibly started on line %d\n", start_lineno);
+    *p++ = '\0';
+    fprintf(stderr, "string -- %s\n", buf);
+    return estrdup(buf);
+}
+    
diff --git a/source4/heimdal/lib/asn1/libasn1.h b/source4/heimdal/lib/asn1/libasn1.h
new file mode 100644 (file)
index 0000000..8ccde9a
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * 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 above 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. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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. 
+ */
+
+/* $Id: libasn1.h,v 1.11 2005/07/12 06:27:34 lha Exp $ */
+
+#ifndef __LIBASN1_H__
+#define __LIBASN1_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "krb5_asn1.h"
+#include "der.h"
+#include "asn1_err.h"
+#include <parse_units.h>
+
+#endif /* __LIBASN1_H__ */
index afa164ea8151b1dc03ac05685d7f356e9a81b35d..088e8ebfa26aeb4abaa9fb84bcedf22d3f99f8f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
 
 #include "gen_locl.h"
 #include <getarg.h>
+#include "lex.h"
 
-RCSID("$Id: main.c,v 1.13 2005/06/16 20:05:31 lha Exp $");
+RCSID("$Id: main.c,v 1.14 2005/07/12 06:27:34 lha Exp $");
 
 extern FILE *yyin;
 
+static getarg_strings preserve;
+
+int
+preserve_type(const char *p)
+{
+    int i;
+    for (i = 0; i < preserve.num_strings; i++)
+       if (strcmp(preserve.strings[i], p) == 0)
+           return 1;
+    return 0;
+}
+
+int dce_fix;
+int rfc1510_bitstring;
 int version_flag;
 int help_flag;
 struct getargs args[] = {
+    { "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring },
+    { "decode-dce-ber", 0, arg_flag, &dce_fix },
+    { "preserve-binary", 0, arg_strings, &preserve },
     { "version", 0, arg_flag, &version_flag },
     { "help", 0, arg_flag, &help_flag }
 };
@@ -53,12 +71,14 @@ usage(int code)
     exit(code);
 }
 
+int error_flag;
+
 int
 main(int argc, char **argv)
 {
     int ret;
-    const char *file;
-    const char *name = NULL;
+    char *file;
+    char *name = NULL;
     int optidx = 0;
 
     setprogname(argv[0]);
@@ -79,12 +99,21 @@ main(int argc, char **argv)
        yyin = fopen (file, "r");
        if (yyin == NULL)
            err (1, "open %s", file);
-       name = argv[optidx + 1];
+       if (argc == optidx + 1) {
+           char *p;
+           name = estrdup(file);
+           p = strrchr(name, '.');
+           if (p)
+               *p = '\0';
+       } else
+           name = argv[optidx + 1];
     }
 
     init_generate (file, name);
     initsym ();
     ret = yyparse ();
+    if(ret != 0 || error_flag != 0)
+       exit(1);
     close_generate ();
-    return ret;
+    return 0;
 }
index 2f80f3258375e73056587136df656442c2ecc8b4..2d8697843bda4aeee623245cf864995c7c401e64 100644 (file)
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 1.875d.  */
+/* A Bison parser, made by GNU Bison 1.875c.  */
 
 /* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    /* Put the tokens into the symbol table, so that GDB and other debuggers
       know about them.  */
    enum yytokentype {
-     INTEGER = 258,
-     SEQUENCE = 259,
-     CHOICE = 260,
-     OF = 261,
-     OCTET = 262,
-     STRING = 263,
-     GeneralizedTime = 264,
-     GeneralString = 265,
-     BIT = 266,
-     APPLICATION = 267,
-     OPTIONAL = 268,
-     EEQUAL = 269,
-     TBEGIN = 270,
-     END = 271,
-     DEFINITIONS = 272,
-     ENUMERATED = 273,
-     UTF8String = 274,
-     NULLTYPE = 275,
-     EXTERNAL = 276,
-     DEFAULT = 277,
-     DOTDOT = 278,
-     DOTDOTDOT = 279,
-     BOOLEAN = 280,
-     IMPORTS = 281,
-     FROM = 282,
-     OBJECT = 283,
-     IDENTIFIER = 284,
-     IDENT = 285,
-     CONSTANT = 286
+     kw_ABSENT = 258,
+     kw_ABSTRACT_SYNTAX = 259,
+     kw_ALL = 260,
+     kw_APPLICATION = 261,
+     kw_AUTOMATIC = 262,
+     kw_BEGIN = 263,
+     kw_BIT = 264,
+     kw_BMPString = 265,
+     kw_BOOLEAN = 266,
+     kw_BY = 267,
+     kw_CHARACTER = 268,
+     kw_CHOICE = 269,
+     kw_CLASS = 270,
+     kw_COMPONENT = 271,
+     kw_COMPONENTS = 272,
+     kw_CONSTRAINED = 273,
+     kw_CONTAINING = 274,
+     kw_DEFAULT = 275,
+     kw_DEFINITIONS = 276,
+     kw_EMBEDDED = 277,
+     kw_ENCODED = 278,
+     kw_END = 279,
+     kw_ENUMERATED = 280,
+     kw_EXCEPT = 281,
+     kw_EXPLICIT = 282,
+     kw_EXPORTS = 283,
+     kw_EXTENSIBILITY = 284,
+     kw_EXTERNAL = 285,
+     kw_FALSE = 286,
+     kw_FROM = 287,
+     kw_GeneralString = 288,
+     kw_GeneralizedTime = 289,
+     kw_GraphicString = 290,
+     kw_IA5String = 291,
+     kw_IDENTIFIER = 292,
+     kw_IMPLICIT = 293,
+     kw_IMPLIED = 294,
+     kw_IMPORTS = 295,
+     kw_INCLUDES = 296,
+     kw_INSTANCE = 297,
+     kw_INTEGER = 298,
+     kw_INTERSECTION = 299,
+     kw_ISO646String = 300,
+     kw_MAX = 301,
+     kw_MIN = 302,
+     kw_MINUS_INFINITY = 303,
+     kw_NULL = 304,
+     kw_NumericString = 305,
+     kw_OBJECT = 306,
+     kw_OCTET = 307,
+     kw_OF = 308,
+     kw_OPTIONAL = 309,
+     kw_ObjectDescriptor = 310,
+     kw_PATTERN = 311,
+     kw_PDV = 312,
+     kw_PLUS_INFINITY = 313,
+     kw_PRESENT = 314,
+     kw_PRIVATE = 315,
+     kw_PrintableString = 316,
+     kw_REAL = 317,
+     kw_RELATIVE_OID = 318,
+     kw_SEQUENCE = 319,
+     kw_SET = 320,
+     kw_SIZE = 321,
+     kw_STRING = 322,
+     kw_SYNTAX = 323,
+     kw_T61String = 324,
+     kw_TAGS = 325,
+     kw_TRUE = 326,
+     kw_TYPE_IDENTIFIER = 327,
+     kw_TeletexString = 328,
+     kw_UNION = 329,
+     kw_UNIQUE = 330,
+     kw_UNIVERSAL = 331,
+     kw_UTCTime = 332,
+     kw_UTF8String = 333,
+     kw_UniversalString = 334,
+     kw_VideotexString = 335,
+     kw_VisibleString = 336,
+     kw_WITH = 337,
+     RANGE = 338,
+     EEQUAL = 339,
+     ELLIPSIS = 340,
+     IDENTIFIER = 341,
+     referencename = 342,
+     STRING = 343,
+     NUMBER = 344
    };
 #endif
-#define INTEGER 258
-#define SEQUENCE 259
-#define CHOICE 260
-#define OF 261
-#define OCTET 262
-#define STRING 263
-#define GeneralizedTime 264
-#define GeneralString 265
-#define BIT 266
-#define APPLICATION 267
-#define OPTIONAL 268
-#define EEQUAL 269
-#define TBEGIN 270
-#define END 271
-#define DEFINITIONS 272
-#define ENUMERATED 273
-#define UTF8String 274
-#define NULLTYPE 275
-#define EXTERNAL 276
-#define DEFAULT 277
-#define DOTDOT 278
-#define DOTDOTDOT 279
-#define BOOLEAN 280
-#define IMPORTS 281
-#define FROM 282
-#define OBJECT 283
-#define IDENTIFIER 284
-#define IDENT 285
-#define CONSTANT 286
+#define kw_ABSENT 258
+#define kw_ABSTRACT_SYNTAX 259
+#define kw_ALL 260
+#define kw_APPLICATION 261
+#define kw_AUTOMATIC 262
+#define kw_BEGIN 263
+#define kw_BIT 264
+#define kw_BMPString 265
+#define kw_BOOLEAN 266
+#define kw_BY 267
+#define kw_CHARACTER 268
+#define kw_CHOICE 269
+#define kw_CLASS 270
+#define kw_COMPONENT 271
+#define kw_COMPONENTS 272
+#define kw_CONSTRAINED 273
+#define kw_CONTAINING 274
+#define kw_DEFAULT 275
+#define kw_DEFINITIONS 276
+#define kw_EMBEDDED 277
+#define kw_ENCODED 278
+#define kw_END 279
+#define kw_ENUMERATED 280
+#define kw_EXCEPT 281
+#define kw_EXPLICIT 282
+#define kw_EXPORTS 283
+#define kw_EXTENSIBILITY 284
+#define kw_EXTERNAL 285
+#define kw_FALSE 286
+#define kw_FROM 287
+#define kw_GeneralString 288
+#define kw_GeneralizedTime 289
+#define kw_GraphicString 290
+#define kw_IA5String 291
+#define kw_IDENTIFIER 292
+#define kw_IMPLICIT 293
+#define kw_IMPLIED 294
+#define kw_IMPORTS 295
+#define kw_INCLUDES 296
+#define kw_INSTANCE 297
+#define kw_INTEGER 298
+#define kw_INTERSECTION 299
+#define kw_ISO646String 300
+#define kw_MAX 301
+#define kw_MIN 302
+#define kw_MINUS_INFINITY 303
+#define kw_NULL 304
+#define kw_NumericString 305
+#define kw_OBJECT 306
+#define kw_OCTET 307
+#define kw_OF 308
+#define kw_OPTIONAL 309
+#define kw_ObjectDescriptor 310
+#define kw_PATTERN 311
+#define kw_PDV 312
+#define kw_PLUS_INFINITY 313
+#define kw_PRESENT 314
+#define kw_PRIVATE 315
+#define kw_PrintableString 316
+#define kw_REAL 317
+#define kw_RELATIVE_OID 318
+#define kw_SEQUENCE 319
+#define kw_SET 320
+#define kw_SIZE 321
+#define kw_STRING 322
+#define kw_SYNTAX 323
+#define kw_T61String 324
+#define kw_TAGS 325
+#define kw_TRUE 326
+#define kw_TYPE_IDENTIFIER 327
+#define kw_TeletexString 328
+#define kw_UNION 329
+#define kw_UNIQUE 330
+#define kw_UNIVERSAL 331
+#define kw_UTCTime 332
+#define kw_UTF8String 333
+#define kw_UniversalString 334
+#define kw_VideotexString 335
+#define kw_VisibleString 336
+#define kw_WITH 337
+#define RANGE 338
+#define EEQUAL 339
+#define ELLIPSIS 340
+#define IDENTIFIER 341
+#define referencename 342
+#define STRING 343
+#define NUMBER 344
 
 
 
 #include "symbol.h"
 #include "lex.h"
 #include "gen_locl.h"
+#include "der.h"
 
-RCSID("$Id: parse.y,v 1.23 2004/10/13 17:41:48 lha Exp $");
+RCSID("$Id: parse.y,v 1.24 2005/07/12 06:27:35 lha Exp $");
 
 static Type *new_type (Typetype t);
+static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype);
 void yyerror (char *);
+static struct objid *new_objid(const char *label, int value);
+static void add_oid_to_tail(struct objid *, struct objid *);
+static void fix_labels(Symbol *s);
 
-static void append (Member *l, Member *r);
+struct string_list {
+    char *string;
+    struct string_list *next;
+};
 
 
 
 /* Enabling traces.  */
 #ifndef YYDEBUG
-# define YYDEBUG 0
+# define YYDEBUG 1
 #endif
 
 /* Enabling verbose error messages.  */
@@ -153,16 +277,22 @@ static void append (Member *l, Member *r);
 #endif
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 56 "parse.y"
+#line 64 "parse.y"
 typedef union YYSTYPE {
-  int constant;
-  char *name;
-  Type *type;
-  Member *member;
-  char *defval;
+    int constant;
+    struct value *value;
+    struct range range;
+    char *name;
+    Type *type;
+    Member *member;
+    struct objid *objid;
+    char *defval;
+    struct string_list *sl;
+    struct tagtype tag;
+    struct memhead *members;
 } YYSTYPE;
 /* Line 191 of yacc.c.  */
-#line 166 "$base.c"
+#line 296 "parse.c"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
@@ -174,7 +304,7 @@ typedef union YYSTYPE {
 
 
 /* Line 214 of yacc.c.  */
-#line 178 "$base.c"
+#line 308 "parse.c"
 
 #if ! defined (yyoverflow) || YYERROR_VERBOSE
 
@@ -222,7 +352,7 @@ typedef union YYSTYPE {
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  short int yyss;
+  short yyss;
   YYSTYPE yyvs;
   };
 
@@ -232,7 +362,7 @@ union yyalloc
 /* The size of an array large to enough to hold all stacks, each with
    N elements.  */
 # define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (short int) + sizeof (YYSTYPE))                    \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE))                                \
       + YYSTACK_GAP_MAXIMUM)
 
 /* Copy COUNT objects from FROM to TO.  The source and destination do
@@ -274,26 +404,26 @@ union yyalloc
 #if defined (__STDC__) || defined (__cplusplus)
    typedef signed char yysigned_char;
 #else
-   typedef short int yysigned_char;
+   typedef short yysigned_char;
 #endif
 
 /* YYFINAL -- State number of the termination state. */
 #define YYFINAL  4
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   107
+#define YYLAST   152
 
 /* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS  42
+#define YYNTOKENS  98
 /* YYNNTS -- Number of nonterminals. */
-#define YYNNTS  17
+#define YYNNTS  61
 /* YYNRULES -- Number of rules. */
-#define YYNRULES  48
+#define YYNRULES  120
 /* YYNRULES -- Number of states. */
-#define YYNSTATES  100
+#define YYNSTATES  181
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   286
+#define YYMAXUTOK   344
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -304,16 +434,16 @@ static const unsigned char yytranslate[] =
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,    40,     2,     2,     2,     2,     2,
-      34,    35,     2,     2,    32,    41,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,    33,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      92,    93,     2,     2,    91,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,    90,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,    38,     2,    39,     2,     2,     2,     2,     2,     2,
+       2,    96,     2,    97,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    36,     2,    37,     2,     2,     2,     2,
+       2,     2,     2,    94,     2,    95,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -329,51 +459,89 @@ static const unsigned char yytranslate[] =
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
+      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
+      85,    86,    87,    88,    89
 };
 
 #if YYDEBUG
 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
    YYRHS.  */
-static const unsigned char yyprhs[] =
+static const unsigned short yyprhs[] =
 {
-       0,     0,     3,    10,    11,    14,    16,    18,    20,    24,
-      26,    32,    36,    41,    43,    50,    55,    58,    63,    66,
-      68,    70,    72,    74,    78,    83,    88,    94,    96,   102,
-     104,   105,   107,   111,   115,   121,   124,   127,   129,   131,
-     134,   139,   140,   142,   146,   150,   155,   157,   160
+       0,     0,     3,    12,    15,    18,    21,    22,    25,    26,
+      29,    30,    34,    35,    37,    38,    40,    43,    48,    50,
+      53,    55,    57,    61,    63,    67,    69,    71,    73,    75,
+      77,    79,    81,    83,    85,    87,    89,    91,    93,    95,
+      97,    99,   101,   107,   109,   112,   117,   119,   123,   127,
+     132,   137,   139,   142,   148,   151,   154,   156,   161,   165,
+     169,   174,   178,   182,   187,   189,   191,   193,   195,   197,
+     201,   206,   207,   209,   211,   213,   214,   216,   218,   223,
+     225,   227,   229,   231,   233,   235,   237,   239,   243,   247,
+     250,   252,   255,   259,   261,   265,   270,   272,   273,   277,
+     278,   281,   286,   288,   290,   292,   294,   296,   298,   300,
+     302,   304,   306,   308,   310,   312,   314,   316,   318,   320,
+     322
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const yysigned_char yyrhs[] =
+static const short yyrhs[] =
 {
-      43,     0,    -1,    30,    17,    14,    15,    44,    16,    -1,
-      -1,    44,    45,    -1,    47,    -1,    48,    -1,    49,    -1,
-      30,    32,    46,    -1,    30,    -1,    26,    46,    27,    30,
-      33,    -1,    30,    14,    50,    -1,    30,    50,    14,    58,
-      -1,     3,    -1,     3,    34,    58,    23,    58,    35,    -1,
-       3,    36,    56,    37,    -1,    28,    29,    -1,    18,    36,
-      56,    37,    -1,     7,     8,    -1,    10,    -1,    19,    -1,
-      20,    -1,     9,    -1,     4,     6,    50,    -1,     4,    36,
-      51,    37,    -1,     5,    36,    51,    37,    -1,    11,     8,
-      36,    56,    37,    -1,    30,    -1,    38,    12,    58,    39,
-      50,    -1,    25,    -1,    -1,    53,    -1,    51,    32,    24,
-      -1,    51,    32,    53,    -1,    30,    38,    58,    39,    50,
-      -1,    52,    54,    -1,    52,    55,    -1,    52,    -1,    13,
-      -1,    22,    58,    -1,    22,    40,    30,    40,    -1,    -1,
-      57,    -1,    56,    32,    24,    -1,    56,    32,    57,    -1,
-      30,    34,    58,    35,    -1,    31,    -1,    41,    31,    -1,
-      30,    -1
+      99,     0,    -1,    86,    21,   100,   101,    84,     8,   102,
+      24,    -1,    27,    70,    -1,    38,    70,    -1,     7,    70,
+      -1,    -1,    29,    39,    -1,    -1,   103,   107,    -1,    -1,
+      40,   104,    90,    -1,    -1,   105,    -1,    -1,   106,    -1,
+     105,   106,    -1,   109,    32,    86,   144,    -1,   108,    -1,
+     108,   107,    -1,   110,    -1,   136,    -1,    86,    91,   109,
+      -1,    86,    -1,    86,    84,   111,    -1,   112,    -1,   129,
+      -1,   120,    -1,   113,    -1,   137,    -1,   128,    -1,   118,
+      -1,   115,    -1,   123,    -1,   121,    -1,   122,    -1,   124,
+      -1,   125,    -1,   126,    -1,   127,    -1,   132,    -1,    11,
+      -1,    92,   148,    83,   148,    93,    -1,    43,    -1,    43,
+     114,    -1,    43,    94,   116,    95,    -1,   117,    -1,   116,
+      91,   117,    -1,   116,    91,    85,    -1,    86,    92,   156,
+      93,    -1,    25,    94,   119,    95,    -1,   116,    -1,     9,
+      67,    -1,     9,    67,    94,   142,    95,    -1,    51,    37,
+      -1,    52,    67,    -1,    49,    -1,    64,    94,   139,    95,
+      -1,    64,    94,    95,    -1,    64,    53,   111,    -1,    65,
+      94,   139,    95,    -1,    65,    94,    95,    -1,    65,    53,
+     111,    -1,    14,    94,   139,    95,    -1,   130,    -1,   131,
+      -1,    86,    -1,    34,    -1,    77,    -1,   133,   135,   111,
+      -1,    96,   134,    89,    97,    -1,    -1,    76,    -1,     6,
+      -1,    60,    -1,    -1,    27,    -1,    38,    -1,    86,   111,
+      84,   148,    -1,   138,    -1,    33,    -1,    78,    -1,    61,
+      -1,    36,    -1,    10,    -1,    79,    -1,   141,    -1,   139,
+      91,   141,    -1,   139,    91,    85,    -1,    86,   111,    -1,
+     140,    -1,   140,    54,    -1,   140,    20,   148,    -1,   143,
+      -1,   142,    91,   143,    -1,    86,    92,    89,    93,    -1,
+     145,    -1,    -1,    94,   146,    95,    -1,    -1,   147,   146,
+      -1,    86,    92,    89,    93,    -1,    86,    -1,    89,    -1,
+     149,    -1,   150,    -1,   154,    -1,   153,    -1,   155,    -1,
+     158,    -1,   157,    -1,   151,    -1,   152,    -1,    86,    -1,
+      88,    -1,    71,    -1,    31,    -1,   156,    -1,    89,    -1,
+      49,    -1,   145,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const unsigned char yyrline[] =
+static const unsigned short yyrline[] =
 {
-       0,    85,    85,    88,    89,    92,    93,    94,    97,   102,
-     109,   113,   122,   131,   132,   140,   145,   146,   151,   152,
-     153,   154,   155,   156,   161,   166,   171,   176,   185,   191,
-     194,   195,   196,   197,   200,   215,   217,   219,   224,   227,
-     229,   233,   234,   235,   236,   239,   252,   253,   254
+       0,   222,   222,   229,   230,   232,   234,   237,   239,   242,
+     243,   246,   247,   250,   251,   254,   255,   258,   269,   270,
+     273,   274,   277,   283,   291,   301,   302,   305,   306,   307,
+     308,   309,   310,   311,   312,   313,   314,   315,   316,   317,
+     318,   321,   328,   338,   343,   350,   358,   364,   369,   373,
+     386,   394,   397,   404,   412,   418,   425,   432,   438,   446,
+     454,   460,   468,   476,   483,   484,   487,   498,   503,   510,
+     523,   532,   535,   539,   543,   550,   553,   557,   564,   575,
+     578,   583,   588,   593,   598,   603,   611,   617,   622,   633,
+     644,   650,   656,   664,   670,   677,   690,   691,   694,   701,
+     704,   715,   719,   730,   736,   737,   740,   741,   742,   743,
+     744,   747,   750,   753,   764,   772,   778,   786,   794,   797,
+     802
 };
 #endif
 
@@ -382,50 +550,97 @@ static const unsigned char yyrline[] =
    First, the terminals, then, starting at YYNTOKENS, nonterminals. */
 static const char *const yytname[] =
 {
-  "$end", "error", "$undefined", "INTEGER", "SEQUENCE", "CHOICE", "OF",
-  "OCTET", "STRING", "GeneralizedTime", "GeneralString", "BIT",
-  "APPLICATION", "OPTIONAL", "EEQUAL", "TBEGIN", "END", "DEFINITIONS",
-  "ENUMERATED", "UTF8String", "NULLTYPE", "EXTERNAL", "DEFAULT", "DOTDOT",
-  "DOTDOTDOT", "BOOLEAN", "IMPORTS", "FROM", "OBJECT", "IDENTIFIER",
-  "IDENT", "CONSTANT", "','", "';'", "'('", "')'", "'{'", "'}'", "'['",
-  "']'", "'\"'", "'-'", "$accept", "envelope", "specification",
-  "declaration", "referencenames", "imports_decl", "type_decl",
-  "constant_decl", "type", "memberdecls", "memberdeclstart", "memberdecl",
-  "optional2", "defvalue", "bitdecls", "bitdecl", "constant", 0
+  "$end", "error", "$undefined", "kw_ABSENT", "kw_ABSTRACT_SYNTAX",
+  "kw_ALL", "kw_APPLICATION", "kw_AUTOMATIC", "kw_BEGIN", "kw_BIT",
+  "kw_BMPString", "kw_BOOLEAN", "kw_BY", "kw_CHARACTER", "kw_CHOICE",
+  "kw_CLASS", "kw_COMPONENT", "kw_COMPONENTS", "kw_CONSTRAINED",
+  "kw_CONTAINING", "kw_DEFAULT", "kw_DEFINITIONS", "kw_EMBEDDED",
+  "kw_ENCODED", "kw_END", "kw_ENUMERATED", "kw_EXCEPT", "kw_EXPLICIT",
+  "kw_EXPORTS", "kw_EXTENSIBILITY", "kw_EXTERNAL", "kw_FALSE", "kw_FROM",
+  "kw_GeneralString", "kw_GeneralizedTime", "kw_GraphicString",
+  "kw_IA5String", "kw_IDENTIFIER", "kw_IMPLICIT", "kw_IMPLIED",
+  "kw_IMPORTS", "kw_INCLUDES", "kw_INSTANCE", "kw_INTEGER",
+  "kw_INTERSECTION", "kw_ISO646String", "kw_MAX", "kw_MIN",
+  "kw_MINUS_INFINITY", "kw_NULL", "kw_NumericString", "kw_OBJECT",
+  "kw_OCTET", "kw_OF", "kw_OPTIONAL", "kw_ObjectDescriptor", "kw_PATTERN",
+  "kw_PDV", "kw_PLUS_INFINITY", "kw_PRESENT", "kw_PRIVATE",
+  "kw_PrintableString", "kw_REAL", "kw_RELATIVE_OID", "kw_SEQUENCE",
+  "kw_SET", "kw_SIZE", "kw_STRING", "kw_SYNTAX", "kw_T61String", "kw_TAGS",
+  "kw_TRUE", "kw_TYPE_IDENTIFIER", "kw_TeletexString", "kw_UNION",
+  "kw_UNIQUE", "kw_UNIVERSAL", "kw_UTCTime", "kw_UTF8String",
+  "kw_UniversalString", "kw_VideotexString", "kw_VisibleString", "kw_WITH",
+  "RANGE", "EEQUAL", "ELLIPSIS", "IDENTIFIER", "referencename", "STRING",
+  "NUMBER", "';'", "','", "'('", "')'", "'{'", "'}'", "'['", "']'",
+  "$accept", "ModuleDefinition", "TagDefault", "ExtensionDefault",
+  "ModuleBody", "Imports", "SymbolsImported", "SymbolsFromModuleList",
+  "SymbolsFromModule", "AssignmentList", "Assignment", "referencenames",
+  "TypeAssignment", "Type", "BuiltinType", "BooleanType", "range",
+  "IntegerType", "NamedNumberList", "NamedNumber", "EnumeratedType",
+  "Enumerations", "BitStringType", "ObjectIdentifierType",
+  "OctetStringType", "NullType", "SequenceType", "SequenceOfType",
+  "SetType", "SetOfType", "ChoiceType", "ReferencedType", "DefinedType",
+  "UsefulType", "TaggedType", "Tag", "Class", "tagenv", "ValueAssignment",
+  "CharacterStringType", "RestrictedCharactedStringType",
+  "ComponentTypeList", "NamedType", "ComponentType", "NamedBitList",
+  "NamedBit", "objid_opt", "objid", "objid_list", "objid_element", "Value",
+  "BuiltinValue", "ReferencedValue", "DefinedValue", "Valuereference",
+  "CharacterStringValue", "BooleanValue", "IntegerValue", "SignedNumber",
+  "NullValue", "ObjectIdentifierValue", 0
 };
 #endif
 
 # ifdef YYPRINT
 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
    token YYLEX-NUM.  */
-static const unsigned short int yytoknum[] =
+static const unsigned short yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
-     285,   286,    44,    59,    40,    41,   123,   125,    91,    93,
-      34,    45
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
+     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
+     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
+     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
+     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
+      59,    44,    40,    41,   123,   125,    91,    93
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const unsigned char yyr1[] =
 {
-       0,    42,    43,    44,    44,    45,    45,    45,    46,    46,
-      47,    48,    49,    50,    50,    50,    50,    50,    50,    50,
-      50,    50,    50,    50,    50,    50,    50,    50,    50,    50,
-      51,    51,    51,    51,    52,    53,    53,    53,    54,    55,
-      55,    56,    56,    56,    56,    57,    58,    58,    58
+       0,    98,    99,   100,   100,   100,   100,   101,   101,   102,
+     102,   103,   103,   104,   104,   105,   105,   106,   107,   107,
+     108,   108,   109,   109,   110,   111,   111,   112,   112,   112,
+     112,   112,   112,   112,   112,   112,   112,   112,   112,   112,
+     112,   113,   114,   115,   115,   115,   116,   116,   116,   117,
+     118,   119,   120,   120,   121,   122,   123,   124,   124,   125,
+     126,   126,   127,   128,   129,   129,   130,   131,   131,   132,
+     133,   134,   134,   134,   134,   135,   135,   135,   136,   137,
+     138,   138,   138,   138,   138,   138,   139,   139,   139,   140,
+     141,   141,   141,   142,   142,   143,   144,   144,   145,   146,
+     146,   147,   147,   147,   148,   148,   149,   149,   149,   149,
+     149,   150,   151,   152,   153,   154,   154,   155,   156,   157,
+     158
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const unsigned char yyr2[] =
 {
-       0,     2,     6,     0,     2,     1,     1,     1,     3,     1,
-       5,     3,     4,     1,     6,     4,     2,     4,     2,     1,
-       1,     1,     1,     3,     4,     4,     5,     1,     5,     1,
-       0,     1,     3,     3,     5,     2,     2,     1,     1,     2,
-       4,     0,     1,     3,     3,     4,     1,     2,     1
+       0,     2,     8,     2,     2,     2,     0,     2,     0,     2,
+       0,     3,     0,     1,     0,     1,     2,     4,     1,     2,
+       1,     1,     3,     1,     3,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     5,     1,     2,     4,     1,     3,     3,     4,
+       4,     1,     2,     5,     2,     2,     1,     4,     3,     3,
+       4,     3,     3,     4,     1,     1,     1,     1,     1,     3,
+       4,     0,     1,     1,     1,     0,     1,     1,     4,     1,
+       1,     1,     1,     1,     1,     1,     1,     3,     3,     2,
+       1,     2,     3,     1,     3,     4,     1,     0,     3,     0,
+       2,     4,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -433,98 +648,145 @@ static const unsigned char yyr2[] =
    means the default is an error.  */
 static const unsigned char yydefact[] =
 {
-       0,     0,     0,     0,     1,     0,     3,     0,     2,     0,
-       0,     4,     5,     6,     7,     9,     0,    13,     0,     0,
-       0,    22,    19,     0,     0,     0,    20,    21,    29,     0,
-      27,     0,     0,     0,     0,     0,    41,     0,    30,    30,
-      18,     0,    11,    41,    16,     0,     0,     8,     0,    48,
-      46,     0,     0,     0,     0,    42,    23,     0,     0,    37,
-      31,     0,    41,     0,     0,    12,    10,    47,     0,     0,
-       0,    15,     0,     0,    24,    38,     0,    35,    36,    25,
-       0,    17,     0,     0,     0,    43,    44,     0,    32,    33,
-       0,    39,    26,    28,    14,    45,     0,     0,    34,    40
+       0,     0,     0,     6,     1,     0,     0,     0,     8,     5,
+       3,     4,     0,     0,     7,     0,    10,    14,     0,     0,
+      23,     0,    13,    15,     0,     2,     0,     9,    18,    20,
+      21,     0,    11,    16,     0,     0,    84,    41,     0,     0,
+      80,    67,    83,    43,    56,     0,     0,    82,     0,     0,
+      68,    81,    85,     0,    66,    71,     0,    25,    28,    32,
+      31,    27,    34,    35,    33,    36,    37,    38,    39,    30,
+      26,    64,    65,    40,    75,    29,    79,    19,    22,    97,
+      52,     0,     0,     0,     0,    44,    54,    55,     0,     0,
+       0,     0,    24,    73,    74,    72,     0,     0,    76,    77,
+       0,    99,    17,    96,     0,     0,     0,    90,    86,     0,
+      51,    46,     0,   116,   119,   115,   113,   114,   118,   120,
+       0,   104,   105,   111,   112,   107,   106,   108,   117,   110,
+     109,     0,    59,    58,     0,    62,    61,     0,     0,    78,
+      69,   102,   103,     0,    99,     0,     0,    93,    89,     0,
+      63,     0,    91,     0,     0,    50,     0,    45,    57,    60,
+      70,     0,    98,   100,     0,     0,    53,    88,    87,    92,
+       0,    48,    47,     0,     0,     0,    94,    49,    42,   101,
+      95
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
-static const yysigned_char yydefgoto[] =
+static const short yydefgoto[] =
 {
-      -1,     2,     7,    11,    16,    12,    13,    14,    32,    58,
-      59,    60,    77,    78,    54,    55,    52
+      -1,     2,     8,    13,    18,    19,    21,    22,    23,    27,
+      28,    24,    29,    56,    57,    58,    85,    59,   110,   111,
+      60,   112,    61,    62,    63,    64,    65,    66,    67,    68,
+      69,    70,    71,    72,    73,    74,    96,   100,    30,    75,
+      76,   106,   107,   108,   146,   147,   102,   119,   143,   144,
+     120,   121,   122,   123,   124,   125,   126,   127,   128,   129,
+     130
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -38
+#define YYPACT_NINF -94
 static const yysigned_char yypact[] =
 {
-     -26,    12,    22,    16,   -38,    32,   -38,     5,   -38,    20,
-      -2,   -38,   -38,   -38,   -38,    27,    41,    42,    13,    45,
-      69,   -38,   -38,    71,    35,    46,   -38,   -38,   -38,    54,
-     -38,    72,    73,    20,    55,    26,    56,    35,    58,    58,
-     -38,    53,   -38,    56,   -38,    26,    26,   -38,    57,   -38,
-     -38,    60,    70,    61,    -5,   -38,   -38,    59,    11,     2,
-     -38,    34,    56,    37,    62,   -38,   -38,   -38,    26,    26,
-     -10,   -38,    26,    40,   -38,   -38,    21,   -38,   -38,   -38,
-      43,   -38,    35,    63,    64,   -38,   -38,    65,   -38,   -38,
-      66,   -38,   -38,   -38,   -38,   -38,    35,    52,   -38,   -38
+     -49,     5,    60,     3,   -94,    -6,     1,    10,    43,   -94,
+     -94,   -94,    42,    -2,   -94,    76,   -33,     0,    64,     4,
+       7,     9,     0,   -94,    61,   -94,    -9,   -94,     4,   -94,
+     -94,     0,   -94,   -94,    14,    28,   -94,   -94,    12,    13,
+     -94,   -94,   -94,   -56,   -94,    66,    41,   -94,   -50,   -47,
+     -94,   -94,   -94,    40,   -94,     2,    25,   -94,   -94,   -94,
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+     -94,   -94,   -94,   -94,   -18,   -94,   -94,   -94,   -94,    16,
+      17,    26,    27,     8,    27,   -94,   -94,   -94,    40,   -73,
+      40,   -72,   -94,   -94,   -94,   -94,    34,     8,   -94,   -94,
+      40,   -41,   -94,   -94,    29,    40,   -80,    -8,   -94,    22,
+      30,   -94,    21,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+      44,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+     -94,   -74,   -94,   -94,   -63,   -94,   -94,   -62,    31,   -94,
+     -94,    33,   -94,    35,   -41,    37,   -60,   -94,   -94,   -67,
+     -94,     8,   -94,    45,   -19,   -94,     8,   -94,   -94,   -94,
+     -94,    46,   -94,   -94,    49,    29,   -94,   -94,   -94,   -94,
+      38,   -94,   -94,    47,    48,    50,   -94,   -94,   -94,   -94,
+     -94
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yysigned_char yypgoto[] =
 {
-     -38,   -38,   -38,   -38,    67,   -38,   -38,   -38,   -24,    68,
-     -38,    29,   -38,   -38,   -37,    24,   -35
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   102,   105,
+     -94,   108,   -94,    32,   -94,   -94,   -94,   -94,    58,   -10,
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+     -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,   -94,
+     -94,   -30,   -94,    -4,   -94,   -17,   -94,    67,     6,   -94,
+     -93,   -94,   -94,   -94,   -94,   -94,   -94,   -94,    -1,   -94,
+     -94
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -1
-static const unsigned char yytable[] =
+#define YYTABLE_NINF -13
+static const short yytable[] =
 {
-      42,    17,    18,    19,     1,    20,    63,    21,    22,    23,
-      64,    65,    24,    56,    85,    75,    25,    26,    27,    37,
-      53,     8,     4,    28,    76,    80,    29,    70,    30,     3,
-       5,     9,    71,    83,    84,    10,    31,    87,    17,    18,
-      19,    91,    20,    73,    21,    22,    23,     6,    74,    38,
-      15,    49,    50,    25,    26,    27,    49,    50,    93,    33,
-      28,    90,    51,    29,    88,    30,    73,    51,    34,    70,
-      57,    79,    98,    31,    81,    70,    35,    40,    36,    41,
-      92,    39,    43,    44,    45,    48,    53,    46,    57,    62,
-      66,    67,    99,    68,    86,    69,    97,    72,    94,    95,
-      47,    82,    89,     0,    96,     0,     0,    61
+      35,    36,    37,    88,   139,    38,    90,    17,    93,    98,
+       5,   149,   151,   105,   105,   150,    39,   154,   167,   105,
+      99,   157,   133,   136,    40,    41,     3,    42,   149,   149,
+       6,   165,   158,   159,    43,   166,    83,     1,    84,   113,
+      44,     7,    45,    46,    89,   141,   152,    91,   142,    35,
+      36,    37,    47,   -12,    38,    48,    49,   114,   169,   134,
+       4,   137,    94,   173,     9,    39,   171,   109,    50,    51,
+      52,    10,    12,    40,    41,    53,    42,    54,    95,   115,
+      11,    14,    15,    43,    16,    92,    20,    55,    25,    44,
+      26,    45,    46,    34,   116,    80,   117,   118,    31,    32,
+      79,    47,   101,    86,    48,    49,    81,    82,    87,    97,
+     101,   104,   105,   109,   153,   145,   155,    50,    51,    52,
+     132,   154,   135,   138,    33,   161,    54,   156,   160,   164,
+     162,   177,   140,    77,   118,   174,    55,   148,   175,    78,
+     178,   179,   131,   180,   172,   168,   103,     0,   176,     0,
+     163,     0,   170
 };
 
-static const yysigned_char yycheck[] =
+static const short yycheck[] =
 {
-      24,     3,     4,     5,    30,     7,    43,     9,    10,    11,
-      45,    46,    14,    37,    24,    13,    18,    19,    20,     6,
-      30,    16,     0,    25,    22,    62,    28,    32,    30,    17,
-      14,    26,    37,    68,    69,    30,    38,    72,     3,     4,
-       5,    76,     7,    32,     9,    10,    11,    15,    37,    36,
-      30,    30,    31,    18,    19,    20,    30,    31,    82,    32,
-      25,    40,    41,    28,    24,    30,    32,    41,    27,    32,
-      30,    37,    96,    38,    37,    32,    34,     8,    36,     8,
-      37,    36,    36,    29,    12,    30,    30,    14,    30,    36,
-      33,    31,    40,    23,    70,    34,    30,    38,    35,    35,
-      33,    39,    73,    -1,    39,    -1,    -1,    39
+       9,    10,    11,    53,    97,    14,    53,    40,     6,    27,
+       7,    91,    20,    86,    86,    95,    25,    91,    85,    86,
+      38,    95,    95,    95,    33,    34,    21,    36,    91,    91,
+      27,    91,    95,    95,    43,    95,    92,    86,    94,    31,
+      49,    38,    51,    52,    94,    86,    54,    94,    89,     9,
+      10,    11,    61,    86,    14,    64,    65,    49,   151,    89,
+       0,    91,    60,   156,    70,    25,    85,    86,    77,    78,
+      79,    70,    29,    33,    34,    84,    36,    86,    76,    71,
+      70,    39,    84,    43,     8,    53,    86,    96,    24,    49,
+      86,    51,    52,    32,    86,    67,    88,    89,    91,    90,
+      86,    61,    94,    37,    64,    65,    94,    94,    67,    84,
+      94,    94,    86,    86,    92,    86,    95,    77,    78,    79,
+      88,    91,    90,    89,    22,    92,    86,    83,    97,    92,
+      95,    93,   100,    28,    89,    89,    96,   105,    89,    31,
+      93,    93,    84,    93,   154,   149,    79,    -1,   165,    -1,
+     144,    -1,   153
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const unsigned char yystos[] =
 {
-       0,    30,    43,    17,     0,    14,    15,    44,    16,    26,
-      30,    45,    47,    48,    49,    30,    46,     3,     4,     5,
-       7,     9,    10,    11,    14,    18,    19,    20,    25,    28,
-      30,    38,    50,    32,    27,    34,    36,     6,    36,    36,
-       8,     8,    50,    36,    29,    12,    14,    46,    30,    30,
-      31,    41,    58,    30,    56,    57,    50,    30,    51,    52,
-      53,    51,    36,    56,    58,    58,    33,    31,    23,    34,
-      32,    37,    38,    32,    37,    13,    22,    54,    55,    37,
-      56,    37,    39,    58,    58,    24,    57,    58,    24,    53,
-      40,    58,    37,    50,    35,    35,    39,    30,    50,    40
+       0,    86,    99,    21,     0,     7,    27,    38,   100,    70,
+      70,    70,    29,   101,    39,    84,     8,    40,   102,   103,
+      86,   104,   105,   106,   109,    24,    86,   107,   108,   110,
+     136,    91,    90,   106,    32,     9,    10,    11,    14,    25,
+      33,    34,    36,    43,    49,    51,    52,    61,    64,    65,
+      77,    78,    79,    84,    86,    96,   111,   112,   113,   115,
+     118,   120,   121,   122,   123,   124,   125,   126,   127,   128,
+     129,   130,   131,   132,   133,   137,   138,   107,   109,    86,
+      67,    94,    94,    92,    94,   114,    37,    67,    53,    94,
+      53,    94,   111,     6,    60,    76,   134,    84,    27,    38,
+     135,    94,   144,   145,    94,    86,   139,   140,   141,    86,
+     116,   117,   119,    31,    49,    71,    86,    88,    89,   145,
+     148,   149,   150,   151,   152,   153,   154,   155,   156,   157,
+     158,   116,   111,    95,   139,   111,    95,   139,    89,   148,
+     111,    86,    89,   146,   147,    86,   142,   143,   111,    91,
+      95,    20,    54,    92,    91,    95,    83,    95,    95,    95,
+      97,    92,    95,   146,    92,    91,    95,    85,   141,   148,
+     156,    85,   117,   148,    89,    89,   143,    93,    93,    93,
+      93
 };
 
 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
@@ -638,12 +900,12 @@ do {                                                              \
 
 #if defined (__STDC__) || defined (__cplusplus)
 static void
-yy_stack_print (short int *bottom, short int *top)
+yy_stack_print (short *bottom, short *top)
 #else
 static void
 yy_stack_print (bottom, top)
-    short int *bottom;
-    short int *top;
+    short *bottom;
+    short *top;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
@@ -910,9 +1172,9 @@ yyparse ()
      to reallocate them elsewhere.  */
 
   /* The state stack.  */
-  short int yyssa[YYINITDEPTH];
-  short int *yyss = yyssa;
-  register short int *yyssp;
+  short        yyssa[YYINITDEPTH];
+  short *yyss = yyssa;
+  register short *yyssp;
 
   /* The semantic value stack.  */
   YYSTYPE yyvsa[YYINITDEPTH];
@@ -949,7 +1211,6 @@ yyparse ()
   yyssp = yyss;
   yyvsp = yyvs;
 
-
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -975,7 +1236,7 @@ yyparse ()
           these so that the &'s don't force the real ones into
           memory.  */
        YYSTYPE *yyvs1 = yyvs;
-       short int *yyss1 = yyss;
+       short *yyss1 = yyss;
 
 
        /* Each stack pointer address is followed by the size of the
@@ -1003,7 +1264,7 @@ yyparse ()
        yystacksize = YYMAXDEPTH;
 
       {
-       short int *yyss1 = yyss;
+       short *yyss1 = yyss;
        union yyalloc *yyptr =
          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
        if (! yyptr)
@@ -1136,298 +1397,650 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 85 "parse.y"
-    {}
+#line 224 "parse.y"
+    {
+                       checkundefined();
+               }
     break;
 
-  case 8:
-#line 98 "parse.y"
-    {
-                       Symbol *s = addsym(yyvsp[-2].name);
+  case 4:
+#line 231 "parse.y"
+    { error_message("implicit tagging is not supported"); }
+    break;
+
+  case 5:
+#line 233 "parse.y"
+    { error_message("automatic tagging is not supported"); }
+    break;
+
+  case 7:
+#line 238 "parse.y"
+    { error_message("no extensibility options supported"); }
+    break;
+
+  case 17:
+#line 259 "parse.y"
+    { 
+                   struct string_list *sl;
+                   for(sl = yyvsp[-3].sl; sl != NULL; sl = sl->next) {
+                       Symbol *s = addsym(sl->string);
                        s->stype = Stype;
+                   }
+                   add_import(yyvsp[-1].name);
                }
     break;
 
-  case 9:
-#line 103 "parse.y"
+  case 22:
+#line 278 "parse.y"
     {
-                       Symbol *s = addsym(yyvsp[0].name);
-                       s->stype = Stype;
+                   yyval.sl = emalloc(sizeof(*yyval.sl));
+                   yyval.sl->string = yyvsp[-2].name;
+                   yyval.sl->next = yyvsp[0].sl;
                }
     break;
 
-  case 10:
-#line 110 "parse.y"
-    { add_import(yyvsp[-1].name); }
+  case 23:
+#line 284 "parse.y"
+    {
+                   yyval.sl = emalloc(sizeof(*yyval.sl));
+                   yyval.sl->string = yyvsp[0].name;
+                   yyval.sl->next = NULL;
+               }
     break;
 
-  case 11:
-#line 114 "parse.y"
+  case 24:
+#line 292 "parse.y"
     {
-                 Symbol *s = addsym (yyvsp[-2].name);
-                 s->stype = Stype;
-                 s->type = yyvsp[0].type;
-                 generate_type (s);
+                   Symbol *s = addsym (yyvsp[-2].name);
+                   s->stype = Stype;
+                   s->type = yyvsp[0].type;
+                   fix_labels(s);
+                   generate_type (s);
                }
     break;
 
-  case 12:
-#line 123 "parse.y"
+  case 41:
+#line 322 "parse.y"
     {
-                 Symbol *s = addsym (yyvsp[-3].name);
-                 s->stype = SConstant;
-                 s->constant = yyvsp[0].constant;
-                 generate_constant (s);
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_Boolean, 
+                                    TE_EXPLICIT, new_type(TBoolean));
                }
     break;
 
-  case 13:
-#line 131 "parse.y"
-    { yyval.type = new_type(TInteger); }
+  case 42:
+#line 329 "parse.y"
+    {
+                       if(yyvsp[-3].value->type != integervalue || 
+                          yyvsp[-1].value->type != integervalue)
+                               error_message("Non-integer value used in range");
+                       yyval.range.min = yyvsp[-3].value->u.integervalue;
+                       yyval.range.max = yyvsp[-1].value->u.integervalue;
+               }
     break;
 
-  case 14:
-#line 132 "parse.y"
+  case 43:
+#line 339 "parse.y"
     {
-                   if(yyvsp[-3].constant != 0)
-                       error_message("Only 0 supported as low range");
-                   if(yyvsp[-1].constant != INT_MIN && yyvsp[-1].constant != UINT_MAX && yyvsp[-1].constant != INT_MAX)
-                       error_message("Only %u supported as high range",
-                                     UINT_MAX);
-                   yyval.type = new_type(TUInteger);
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_Integer, 
+                                    TE_EXPLICIT, new_type(TInteger));
                }
     break;
 
-  case 15:
-#line 141 "parse.y"
+  case 44:
+#line 344 "parse.y"
     {
                        yyval.type = new_type(TInteger);
-                       yyval.type->members = yyvsp[-1].member;
-                }
+                       yyval.type->range = emalloc(sizeof(*yyval.type->range));
+                       *(yyval.type->range) = yyvsp[0].range;
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, yyval.type);
+               }
+    break;
+
+  case 45:
+#line 351 "parse.y"
+    {
+                 yyval.type = new_type(TInteger);
+                 yyval.type->members = yyvsp[-1].members;
+                 yyval.type = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, yyval.type);
+               }
     break;
 
-  case 16:
-#line 145 "parse.y"
-    { yyval.type = new_type(TOID); }
+  case 46:
+#line 359 "parse.y"
+    {
+                       yyval.members = emalloc(sizeof(*yyval.members));
+                       ASN1_TAILQ_INIT(yyval.members);
+                       ASN1_TAILQ_INSERT_HEAD(yyval.members, yyvsp[0].member, members);
+               }
     break;
 
-  case 17:
-#line 147 "parse.y"
+  case 47:
+#line 365 "parse.y"
+    {
+                       ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, yyvsp[0].member, members);
+                       yyval.members = yyvsp[-2].members;
+               }
+    break;
+
+  case 48:
+#line 370 "parse.y"
+    { yyval.members = yyvsp[-2].members; }
+    break;
+
+  case 49:
+#line 374 "parse.y"
     {
-                       yyval.type = new_type(TEnumerated);
-                       yyval.type->members = yyvsp[-1].member;
+                       yyval.member = emalloc(sizeof(*yyval.member));
+                       yyval.member->name = yyvsp[-3].name;
+                       yyval.member->gen_name = estrdup(yyvsp[-3].name);
+                       output_name (yyval.member->gen_name);
+                       yyval.member->val = yyvsp[-1].constant;
+                       yyval.member->optional = 0;
+                       yyval.member->ellipsis = 0;
+                       yyval.member->type = NULL;
                }
     break;
 
-  case 18:
-#line 151 "parse.y"
-    { yyval.type = new_type(TOctetString); }
+  case 50:
+#line 387 "parse.y"
+    {
+                 yyval.type = new_type(TInteger);
+                 yyval.type->members = yyvsp[-1].members;
+                 yyval.type = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, yyval.type);
+               }
     break;
 
-  case 19:
-#line 152 "parse.y"
-    { yyval.type = new_type(TGeneralString); }
+  case 52:
+#line 398 "parse.y"
+    {
+                 yyval.type = new_type(TBitString);
+                 yyval.type->members = emalloc(sizeof(*yyval.type->members));
+                 ASN1_TAILQ_INIT(yyval.type->members);
+                 yyval.type = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, yyval.type);
+               }
     break;
 
-  case 20:
-#line 153 "parse.y"
-    { yyval.type = new_type(TUTF8String); }
+  case 53:
+#line 405 "parse.y"
+    {
+                 yyval.type = new_type(TBitString);
+                 yyval.type->members = yyvsp[-1].members;
+                 yyval.type = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, yyval.type);
+               }
     break;
 
-  case 21:
-#line 154 "parse.y"
-    { yyval.type = new_type(TNull); }
+  case 54:
+#line 413 "parse.y"
+    {
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_OID, 
+                                    TE_EXPLICIT, new_type(TOID));
+               }
     break;
 
-  case 22:
-#line 155 "parse.y"
-    { yyval.type = new_type(TGeneralizedTime); }
+  case 55:
+#line 419 "parse.y"
+    {
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_OctetString, 
+                                    TE_EXPLICIT, new_type(TOctetString));
+               }
     break;
 
-  case 23:
-#line 157 "parse.y"
+  case 56:
+#line 426 "parse.y"
+    {
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_Null, 
+                                    TE_EXPLICIT, new_type(TNull));
+               }
+    break;
+
+  case 57:
+#line 433 "parse.y"
+    {
+                 yyval.type = new_type(TSequence);
+                 yyval.type->members = yyvsp[-1].members;
+                 yyval.type = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, yyval.type);
+               }
+    break;
+
+  case 58:
+#line 439 "parse.y"
+    {
+                 yyval.type = new_type(TSequence);
+                 yyval.type->members = NULL;
+                 yyval.type = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, yyval.type);
+               }
+    break;
+
+  case 59:
+#line 447 "parse.y"
     {
                  yyval.type = new_type(TSequenceOf);
                  yyval.type->subtype = yyvsp[0].type;
+                 yyval.type = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, yyval.type);
                }
     break;
 
-  case 24:
-#line 162 "parse.y"
+  case 60:
+#line 455 "parse.y"
     {
-                 yyval.type = new_type(TSequence);
-                 yyval.type->members = yyvsp[-1].member;
+                 yyval.type = new_type(TSet);
+                 yyval.type->members = yyvsp[-1].members;
+                 yyval.type = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, yyval.type);
                }
     break;
 
-  case 25:
-#line 167 "parse.y"
+  case 61:
+#line 461 "parse.y"
     {
-                 yyval.type = new_type(TChoice);
-                 yyval.type->members = yyvsp[-1].member;
+                 yyval.type = new_type(TSet);
+                 yyval.type->members = NULL;
+                 yyval.type = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, yyval.type);
                }
     break;
 
-  case 26:
-#line 172 "parse.y"
+  case 62:
+#line 469 "parse.y"
     {
-                 yyval.type = new_type(TBitString);
-                 yyval.type->members = yyvsp[-1].member;
+                 yyval.type = new_type(TSetOf);
+                 yyval.type->subtype = yyvsp[0].type;
+                 yyval.type = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, yyval.type);
                }
     break;
 
-  case 27:
-#line 177 "parse.y"
+  case 63:
+#line 477 "parse.y"
+    {
+                 yyval.type = new_type(TChoice);
+                 yyval.type->members = yyvsp[-1].members;
+               }
+    break;
+
+  case 66:
+#line 488 "parse.y"
     {
                  Symbol *s = addsym(yyvsp[0].name);
                  yyval.type = new_type(TType);
-                 if(s->stype != Stype)
+                 if(s->stype != Stype && s->stype != SUndefined)
                    error_message ("%s is not a type\n", yyvsp[0].name);
                  else
                    yyval.type->symbol = s;
                }
     break;
 
-  case 28:
-#line 186 "parse.y"
+  case 67:
+#line 499 "parse.y"
     {
-                 yyval.type = new_type(TApplication);
-                 yyval.type->subtype = yyvsp[0].type;
-                 yyval.type->application = yyvsp[-2].constant;
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_GeneralizedTime, 
+                                    TE_EXPLICIT, new_type(TGeneralizedTime));
                }
     break;
 
-  case 29:
-#line 191 "parse.y"
-    { yyval.type = new_type(TBoolean); }
+  case 68:
+#line 504 "parse.y"
+    {
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_UTCTime, 
+                                    TE_EXPLICIT, new_type(TUTCTime));
+               }
     break;
 
-  case 30:
-#line 194 "parse.y"
-    { yyval.member = NULL; }
+  case 69:
+#line 511 "parse.y"
+    {
+                       yyval.type = new_type(TTag);
+                       yyval.type->tag = yyvsp[-2].tag;
+                       yyval.type->tag.tagenv = yyvsp[-1].constant;
+                       if(yyvsp[0].type->type == TTag && yyvsp[-1].constant == TE_IMPLICIT) {
+                               yyval.type->subtype = yyvsp[0].type->subtype;
+                               free(yyvsp[0].type);
+                       } else
+                               yyval.type->subtype = yyvsp[0].type;
+               }
     break;
 
-  case 31:
-#line 195 "parse.y"
-    { yyval.member = yyvsp[0].member; }
+  case 70:
+#line 524 "parse.y"
+    {
+                       yyval.tag.tagclass = yyvsp[-2].constant;
+                       yyval.tag.tagvalue = yyvsp[-1].constant;
+                       yyval.tag.tagenv = TE_EXPLICIT;
+               }
     break;
 
-  case 32:
-#line 196 "parse.y"
-    { yyval.member = yyvsp[-2].member; }
+  case 71:
+#line 532 "parse.y"
+    {
+                       yyval.constant = ASN1_C_CONTEXT;
+               }
     break;
 
-  case 33:
-#line 197 "parse.y"
-    { yyval.member = yyvsp[-2].member; append(yyval.member, yyvsp[0].member); }
+  case 72:
+#line 536 "parse.y"
+    {
+                       yyval.constant = ASN1_C_UNIV;
+               }
     break;
 
-  case 34:
-#line 201 "parse.y"
+  case 73:
+#line 540 "parse.y"
     {
-                 yyval.member = malloc(sizeof(*yyval.member));
-                 yyval.member->name = yyvsp[-4].name;
-                 yyval.member->gen_name = strdup(yyvsp[-4].name);
-                 output_name (yyval.member->gen_name);
-                 yyval.member->val = yyvsp[-2].constant;
-                 yyval.member->optional = 0;
-                 yyval.member->defval = NULL;
-                 yyval.member->type = yyvsp[0].type;
-                 yyval.member->next = yyval.member->prev = yyval.member;
+                       yyval.constant = ASN1_C_APPL;
                }
     break;
 
-  case 35:
-#line 216 "parse.y"
-    { yyvsp[-1].member->optional = yyvsp[0].constant ; yyval.member = yyvsp[-1].member; }
+  case 74:
+#line 544 "parse.y"
+    {
+                       yyval.constant = ASN1_C_PRIVATE;
+               }
     break;
 
-  case 36:
-#line 218 "parse.y"
-    { yyvsp[-1].member->defval = yyvsp[0].defval ; yyval.member = yyvsp[-1].member; }
+  case 75:
+#line 550 "parse.y"
+    {
+                       yyval.constant = TE_EXPLICIT;
+               }
     break;
 
-  case 37:
-#line 220 "parse.y"
-    { yyval.member = yyvsp[0].member; }
+  case 76:
+#line 554 "parse.y"
+    {
+                       yyval.constant = TE_EXPLICIT;
+               }
     break;
 
-  case 38:
-#line 224 "parse.y"
-    { yyval.constant = 1; }
+  case 77:
+#line 558 "parse.y"
+    {
+                       yyval.constant = TE_IMPLICIT;
+               }
     break;
 
-  case 39:
-#line 228 "parse.y"
-    { asprintf(&yyval.defval, "%d", yyvsp[0].constant); }
+  case 78:
+#line 565 "parse.y"
+    {
+                       Symbol *s;
+                       s = addsym (yyvsp[-3].name);
+
+                       s->stype = SValue;
+                       s->value = yyvsp[0].value;
+                       generate_constant (s);
+               }
     break;
 
-  case 40:
-#line 230 "parse.y"
-    { yyval.defval = strdup (yyvsp[-1].name); }
+  case 80:
+#line 579 "parse.y"
+    {
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_GeneralString, 
+                                    TE_EXPLICIT, new_type(TGeneralString));
+               }
     break;
 
-  case 41:
-#line 233 "parse.y"
-    { yyval.member = NULL; }
+  case 81:
+#line 584 "parse.y"
+    {
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_UTF8String, 
+                                    TE_EXPLICIT, new_type(TUTF8String));
+               }
     break;
 
-  case 42:
-#line 234 "parse.y"
-    { yyval.member = yyvsp[0].member; }
+  case 82:
+#line 589 "parse.y"
+    {
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_PrintableString, 
+                                    TE_EXPLICIT, new_type(TPrintableString));
+               }
     break;
 
-  case 43:
-#line 235 "parse.y"
-    { yyval.member = yyvsp[-2].member; }
+  case 83:
+#line 594 "parse.y"
+    {
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_IA5String, 
+                                    TE_EXPLICIT, new_type(TIA5String));
+               }
     break;
 
-  case 44:
-#line 236 "parse.y"
-    { yyval.member = yyvsp[-2].member; append(yyval.member, yyvsp[0].member); }
+  case 84:
+#line 599 "parse.y"
+    {
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_BMPString, 
+                                    TE_EXPLICIT, new_type(TBMPString));
+               }
     break;
 
-  case 45:
-#line 240 "parse.y"
+  case 85:
+#line 604 "parse.y"
+    {
+                       yyval.type = new_tag(ASN1_C_UNIV, UT_UniversalString, 
+                                    TE_EXPLICIT, new_type(TUniversalString));
+               }
+    break;
+
+  case 86:
+#line 612 "parse.y"
+    {
+                       yyval.members = emalloc(sizeof(*yyval.members));
+                       ASN1_TAILQ_INIT(yyval.members);
+                       ASN1_TAILQ_INSERT_HEAD(yyval.members, yyvsp[0].member, members);
+               }
+    break;
+
+  case 87:
+#line 618 "parse.y"
     {
-                 yyval.member = malloc(sizeof(*yyval.member));
+                       ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, yyvsp[0].member, members);
+                       yyval.members = yyvsp[-2].members;
+               }
+    break;
+
+  case 88:
+#line 623 "parse.y"
+    {
+                       struct member *m = ecalloc(1, sizeof(*m));
+                       m->name = estrdup("...");
+                       m->gen_name = estrdup("asn1_ellipsis");
+                       m->ellipsis = 1;
+                       ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, m, members);
+                       yyval.members = yyvsp[-2].members;
+               }
+    break;
+
+  case 89:
+#line 634 "parse.y"
+    {
+                 yyval.member = emalloc(sizeof(*yyval.member));
+                 yyval.member->name = yyvsp[-1].name;
+                 yyval.member->gen_name = estrdup(yyvsp[-1].name);
+                 output_name (yyval.member->gen_name);
+                 yyval.member->type = yyvsp[0].type;
+                 yyval.member->ellipsis = 0;
+               }
+    break;
+
+  case 90:
+#line 645 "parse.y"
+    {
+                       yyval.member = yyvsp[0].member;
+                       yyval.member->optional = 0;
+                       yyval.member->defval = NULL;
+               }
+    break;
+
+  case 91:
+#line 651 "parse.y"
+    {
+                       yyval.member = yyvsp[-1].member;
+                       yyval.member->optional = 1;
+                       yyval.member->defval = NULL;
+               }
+    break;
+
+  case 92:
+#line 657 "parse.y"
+    {
+                       yyval.member = yyvsp[-2].member;
+                       yyval.member->optional = 0;
+                       yyval.member->defval = yyvsp[0].value;
+               }
+    break;
+
+  case 93:
+#line 665 "parse.y"
+    {
+                       yyval.members = emalloc(sizeof(*yyval.members));
+                       ASN1_TAILQ_INIT(yyval.members);
+                       ASN1_TAILQ_INSERT_HEAD(yyval.members, yyvsp[0].member, members);
+               }
+    break;
+
+  case 94:
+#line 671 "parse.y"
+    {
+                       ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, yyvsp[0].member, members);
+                       yyval.members = yyvsp[-2].members;
+               }
+    break;
+
+  case 95:
+#line 678 "parse.y"
+    {
+                 yyval.member = emalloc(sizeof(*yyval.member));
                  yyval.member->name = yyvsp[-3].name;
-                 yyval.member->gen_name = strdup(yyvsp[-3].name);
+                 yyval.member->gen_name = estrdup(yyvsp[-3].name);
                  output_name (yyval.member->gen_name);
                  yyval.member->val = yyvsp[-1].constant;
                  yyval.member->optional = 0;
+                 yyval.member->ellipsis = 0;
                  yyval.member->type = NULL;
-                 yyval.member->prev = yyval.member->next = yyval.member;
                }
     break;
 
-  case 46:
-#line 252 "parse.y"
-    { yyval.constant = yyvsp[0].constant; }
+  case 97:
+#line 691 "parse.y"
+    { yyval.objid = NULL; }
     break;
 
-  case 47:
-#line 253 "parse.y"
-    { yyval.constant = -yyvsp[0].constant; }
+  case 98:
+#line 695 "parse.y"
+    {
+                       yyval.objid = yyvsp[-1].objid;
+               }
     break;
 
-  case 48:
-#line 254 "parse.y"
+  case 99:
+#line 701 "parse.y"
+    {
+                       yyval.objid = NULL;
+               }
+    break;
+
+  case 100:
+#line 705 "parse.y"
+    {
+                       if (yyvsp[0].objid) {
+                               yyval.objid = yyvsp[0].objid;
+                               add_oid_to_tail(yyvsp[0].objid, yyvsp[-1].objid);
+                       } else {
+                               yyval.objid = yyvsp[-1].objid;
+                       }
+               }
+    break;
+
+  case 101:
+#line 716 "parse.y"
+    {
+                       yyval.objid = new_objid(yyvsp[-3].name, yyvsp[-1].constant);
+               }
+    break;
+
+  case 102:
+#line 720 "parse.y"
+    {
+                   Symbol *s = addsym(yyvsp[0].name);
+                   if(s->stype != SValue ||
+                      s->value->type != objectidentifiervalue) {
+                       error_message("%s is not an object identifier\n", 
+                                     s->name);
+                       exit(1);
+                   }
+                   yyval.objid = s->value->u.objectidentifiervalue;
+               }
+    break;
+
+  case 103:
+#line 731 "parse.y"
+    {
+                   yyval.objid = new_objid(NULL, yyvsp[0].constant);
+               }
+    break;
+
+  case 113:
+#line 754 "parse.y"
     {
-                                 Symbol *s = addsym(yyvsp[0].name);
-                                 if(s->stype != SConstant)
-                                   error_message ("%s is not a constant\n",
-                                                  s->name);
-                                 else
-                                   yyval.constant = s->constant;
-                               }
+                       Symbol *s = addsym(yyvsp[0].name);
+                       if(s->stype != SValue)
+                               error_message ("%s is not a value\n",
+                                               s->name);
+                       else
+                               yyval.value = s->value;
+               }
+    break;
+
+  case 114:
+#line 765 "parse.y"
+    {
+                       yyval.value = emalloc(sizeof(*yyval.value));
+                       yyval.value->type = stringvalue;
+                       yyval.value->u.stringvalue = yyvsp[0].name;
+               }
+    break;
+
+  case 115:
+#line 773 "parse.y"
+    {
+                       yyval.value = emalloc(sizeof(*yyval.value));
+                       yyval.value->type = booleanvalue;
+                       yyval.value->u.booleanvalue = 0;
+               }
+    break;
+
+  case 116:
+#line 779 "parse.y"
+    {
+                       yyval.value = emalloc(sizeof(*yyval.value));
+                       yyval.value->type = booleanvalue;
+                       yyval.value->u.booleanvalue = 0;
+               }
+    break;
+
+  case 117:
+#line 787 "parse.y"
+    {
+                       yyval.value = emalloc(sizeof(*yyval.value));
+                       yyval.value->type = integervalue;
+                       yyval.value->u.integervalue = yyvsp[0].constant;
+               }
+    break;
+
+  case 119:
+#line 798 "parse.y"
+    {
+               }
+    break;
+
+  case 120:
+#line 803 "parse.y"
+    {
+                       yyval.value = emalloc(sizeof(*yyval.value));
+                       yyval.value->type = objectidentifiervalue;
+                       yyval.value->u.objectidentifiervalue = yyvsp[0].objid;
+               }
     break;
 
 
     }
 
-/* Line 1010 of yacc.c.  */
-#line 1431 "$base.c"
+/* Line 1000 of yacc.c.  */
+#line 2044 "parse.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -1652,7 +2265,7 @@ yyreturn:
 }
 
 
-#line 263 "parse.y"
+#line 810 "parse.y"
 
 
 void
@@ -1661,29 +2274,82 @@ yyerror (char *s)
      error_message ("%s\n", s);
 }
 
+static Type *
+new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
+{
+    Type *t;
+    if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
+       t = oldtype;
+       oldtype = oldtype->subtype; /* XXX */
+    } else
+       t = new_type (TTag);
+    
+    t->tag.tagclass = tagclass;
+    t->tag.tagvalue = tagvalue;
+    t->tag.tagenv = tagenv;
+    t->subtype = oldtype;
+    return t;
+}
+
+static struct objid *
+new_objid(const char *label, int value)
+{
+    struct objid *s;
+    s = emalloc(sizeof(*s));
+    s->label = label;
+    s->value = value;
+    s->next = NULL;
+    return s;
+}
+
+static void
+add_oid_to_tail(struct objid *head, struct objid *tail)
+{
+    struct objid *o;
+    o = head;
+    while (o->next)
+       o = o->next;
+    o->next = tail;
+}
+
 static Type *
 new_type (Typetype tt)
 {
-  Type *t = malloc(sizeof(*t));
-  if (t == NULL) {
-      error_message ("out of memory in malloc(%lu)", 
-                    (unsigned long)sizeof(*t));
-      exit (1);
-  }
-  t->type = tt;
-  t->application = 0;
-  t->members = NULL;
-  t->subtype = NULL;
-  t->symbol  = NULL;
-  return t;
+    Type *t = ecalloc(1, sizeof(*t));
+    t->type = tt;
+    return t;
+}
+
+static void fix_labels2(Type *t, const char *prefix);
+static void fix_labels1(struct memhead *members, const char *prefix)
+{
+    Member *m;
+
+    if(members == NULL)
+       return;
+    ASN1_TAILQ_FOREACH(m, members, members) {
+       asprintf(&m->label, "%s_%s", prefix, m->gen_name);
+       if (m->label == NULL)
+           errx(1, "malloc");
+       if(m->type != NULL)
+           fix_labels2(m->type, m->label);
+    }
+}
+
+static void fix_labels2(Type *t, const char *prefix)
+{
+    for(; t; t = t->subtype)
+       fix_labels1(t->members, prefix);
 }
 
 static void
-append (Member *l, Member *r)
+fix_labels(Symbol *s)
 {
-  l->prev->next = r;
-  r->prev = l->prev;
-  l->prev = r;
-  r->next = l;
+    char *p;
+    asprintf(&p, "choice_%s", s->gen_name);
+    if (p == NULL)
+       errx(1, "malloc");
+    fix_labels2(s->type, p);
+    free(p);
 }
 
index 25808dca64ffce067e931ab2d0265563e72241dd..ad2ed3c4a2d2c7cd9ce4d0ebc184cdaf5e1cc165 100644 (file)
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 1.875d.  */
+/* A Bison parser, made by GNU Bison 1.875c.  */
 
 /* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    /* Put the tokens into the symbol table, so that GDB and other debuggers
       know about them.  */
    enum yytokentype {
-     INTEGER = 258,
-     SEQUENCE = 259,
-     CHOICE = 260,
-     OF = 261,
-     OCTET = 262,
-     STRING = 263,
-     GeneralizedTime = 264,
-     GeneralString = 265,
-     BIT = 266,
-     APPLICATION = 267,
-     OPTIONAL = 268,
-     EEQUAL = 269,
-     TBEGIN = 270,
-     END = 271,
-     DEFINITIONS = 272,
-     ENUMERATED = 273,
-     UTF8String = 274,
-     NULLTYPE = 275,
-     EXTERNAL = 276,
-     DEFAULT = 277,
-     DOTDOT = 278,
-     DOTDOTDOT = 279,
-     BOOLEAN = 280,
-     IMPORTS = 281,
-     FROM = 282,
-     OBJECT = 283,
-     IDENTIFIER = 284,
-     IDENT = 285,
-     CONSTANT = 286
+     kw_ABSENT = 258,
+     kw_ABSTRACT_SYNTAX = 259,
+     kw_ALL = 260,
+     kw_APPLICATION = 261,
+     kw_AUTOMATIC = 262,
+     kw_BEGIN = 263,
+     kw_BIT = 264,
+     kw_BMPString = 265,
+     kw_BOOLEAN = 266,
+     kw_BY = 267,
+     kw_CHARACTER = 268,
+     kw_CHOICE = 269,
+     kw_CLASS = 270,
+     kw_COMPONENT = 271,
+     kw_COMPONENTS = 272,
+     kw_CONSTRAINED = 273,
+     kw_CONTAINING = 274,
+     kw_DEFAULT = 275,
+     kw_DEFINITIONS = 276,
+     kw_EMBEDDED = 277,
+     kw_ENCODED = 278,
+     kw_END = 279,
+     kw_ENUMERATED = 280,
+     kw_EXCEPT = 281,
+     kw_EXPLICIT = 282,
+     kw_EXPORTS = 283,
+     kw_EXTENSIBILITY = 284,
+     kw_EXTERNAL = 285,
+     kw_FALSE = 286,
+     kw_FROM = 287,
+     kw_GeneralString = 288,
+     kw_GeneralizedTime = 289,
+     kw_GraphicString = 290,
+     kw_IA5String = 291,
+     kw_IDENTIFIER = 292,
+     kw_IMPLICIT = 293,
+     kw_IMPLIED = 294,
+     kw_IMPORTS = 295,
+     kw_INCLUDES = 296,
+     kw_INSTANCE = 297,
+     kw_INTEGER = 298,
+     kw_INTERSECTION = 299,
+     kw_ISO646String = 300,
+     kw_MAX = 301,
+     kw_MIN = 302,
+     kw_MINUS_INFINITY = 303,
+     kw_NULL = 304,
+     kw_NumericString = 305,
+     kw_OBJECT = 306,
+     kw_OCTET = 307,
+     kw_OF = 308,
+     kw_OPTIONAL = 309,
+     kw_ObjectDescriptor = 310,
+     kw_PATTERN = 311,
+     kw_PDV = 312,
+     kw_PLUS_INFINITY = 313,
+     kw_PRESENT = 314,
+     kw_PRIVATE = 315,
+     kw_PrintableString = 316,
+     kw_REAL = 317,
+     kw_RELATIVE_OID = 318,
+     kw_SEQUENCE = 319,
+     kw_SET = 320,
+     kw_SIZE = 321,
+     kw_STRING = 322,
+     kw_SYNTAX = 323,
+     kw_T61String = 324,
+     kw_TAGS = 325,
+     kw_TRUE = 326,
+     kw_TYPE_IDENTIFIER = 327,
+     kw_TeletexString = 328,
+     kw_UNION = 329,
+     kw_UNIQUE = 330,
+     kw_UNIVERSAL = 331,
+     kw_UTCTime = 332,
+     kw_UTF8String = 333,
+     kw_UniversalString = 334,
+     kw_VideotexString = 335,
+     kw_VisibleString = 336,
+     kw_WITH = 337,
+     RANGE = 338,
+     EEQUAL = 339,
+     ELLIPSIS = 340,
+     IDENTIFIER = 341,
+     referencename = 342,
+     STRING = 343,
+     NUMBER = 344
    };
 #endif
-#define INTEGER 258
-#define SEQUENCE 259
-#define CHOICE 260
-#define OF 261
-#define OCTET 262
-#define STRING 263
-#define GeneralizedTime 264
-#define GeneralString 265
-#define BIT 266
-#define APPLICATION 267
-#define OPTIONAL 268
-#define EEQUAL 269
-#define TBEGIN 270
-#define END 271
-#define DEFINITIONS 272
-#define ENUMERATED 273
-#define UTF8String 274
-#define NULLTYPE 275
-#define EXTERNAL 276
-#define DEFAULT 277
-#define DOTDOT 278
-#define DOTDOTDOT 279
-#define BOOLEAN 280
-#define IMPORTS 281
-#define FROM 282
-#define OBJECT 283
-#define IDENTIFIER 284
-#define IDENT 285
-#define CONSTANT 286
+#define kw_ABSENT 258
+#define kw_ABSTRACT_SYNTAX 259
+#define kw_ALL 260
+#define kw_APPLICATION 261
+#define kw_AUTOMATIC 262
+#define kw_BEGIN 263
+#define kw_BIT 264
+#define kw_BMPString 265
+#define kw_BOOLEAN 266
+#define kw_BY 267
+#define kw_CHARACTER 268
+#define kw_CHOICE 269
+#define kw_CLASS 270
+#define kw_COMPONENT 271
+#define kw_COMPONENTS 272
+#define kw_CONSTRAINED 273
+#define kw_CONTAINING 274
+#define kw_DEFAULT 275
+#define kw_DEFINITIONS 276
+#define kw_EMBEDDED 277
+#define kw_ENCODED 278
+#define kw_END 279
+#define kw_ENUMERATED 280
+#define kw_EXCEPT 281
+#define kw_EXPLICIT 282
+#define kw_EXPORTS 283
+#define kw_EXTENSIBILITY 284
+#define kw_EXTERNAL 285
+#define kw_FALSE 286
+#define kw_FROM 287
+#define kw_GeneralString 288
+#define kw_GeneralizedTime 289
+#define kw_GraphicString 290
+#define kw_IA5String 291
+#define kw_IDENTIFIER 292
+#define kw_IMPLICIT 293
+#define kw_IMPLIED 294
+#define kw_IMPORTS 295
+#define kw_INCLUDES 296
+#define kw_INSTANCE 297
+#define kw_INTEGER 298
+#define kw_INTERSECTION 299
+#define kw_ISO646String 300
+#define kw_MAX 301
+#define kw_MIN 302
+#define kw_MINUS_INFINITY 303
+#define kw_NULL 304
+#define kw_NumericString 305
+#define kw_OBJECT 306
+#define kw_OCTET 307
+#define kw_OF 308
+#define kw_OPTIONAL 309
+#define kw_ObjectDescriptor 310
+#define kw_PATTERN 311
+#define kw_PDV 312
+#define kw_PLUS_INFINITY 313
+#define kw_PRESENT 314
+#define kw_PRIVATE 315
+#define kw_PrintableString 316
+#define kw_REAL 317
+#define kw_RELATIVE_OID 318
+#define kw_SEQUENCE 319
+#define kw_SET 320
+#define kw_SIZE 321
+#define kw_STRING 322
+#define kw_SYNTAX 323
+#define kw_T61String 324
+#define kw_TAGS 325
+#define kw_TRUE 326
+#define kw_TYPE_IDENTIFIER 327
+#define kw_TeletexString 328
+#define kw_UNION 329
+#define kw_UNIQUE 330
+#define kw_UNIVERSAL 331
+#define kw_UTCTime 332
+#define kw_UTF8String 333
+#define kw_UniversalString 334
+#define kw_VideotexString 335
+#define kw_VisibleString 336
+#define kw_WITH 337
+#define RANGE 338
+#define EEQUAL 339
+#define ELLIPSIS 340
+#define IDENTIFIER 341
+#define referencename 342
+#define STRING 343
+#define NUMBER 344
 
 
 
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 56 "parse.y"
+#line 64 "parse.y"
 typedef union YYSTYPE {
-  int constant;
-  char *name;
-  Type *type;
-  Member *member;
-  char *defval;
+    int constant;
+    struct value *value;
+    struct range range;
+    char *name;
+    Type *type;
+    Member *member;
+    struct objid *objid;
+    char *defval;
+    struct string_list *sl;
+    struct tagtype tag;
+    struct memhead *members;
 } YYSTYPE;
-/* Line 1285 of yacc.c.  */
-#line 107 "parse.h"
+/* Line 1275 of yacc.c.  */
+#line 229 "parse.h"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
index ab83d451c5a41f010d63255a3bcfe1295026554c..def2bc2498f285b862d6bd56e81b80964f6140cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: parse.y,v 1.23 2004/10/13 17:41:48 lha Exp $ */
+/* $Id: parse.y,v 1.24 2005/07/12 06:27:35 lha Exp $ */
 
 %{
 #ifdef HAVE_CONFIG_H
 #include "symbol.h"
 #include "lex.h"
 #include "gen_locl.h"
+#include "der.h"
 
-RCSID("$Id: parse.y,v 1.23 2004/10/13 17:41:48 lha Exp $");
+RCSID("$Id: parse.y,v 1.24 2005/07/12 06:27:35 lha Exp $");
 
 static Type *new_type (Typetype t);
+static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype);
 void yyerror (char *);
+static struct objid *new_objid(const char *label, int value);
+static void add_oid_to_tail(struct objid *, struct objid *);
+static void fix_labels(Symbol *s);
 
-static void append (Member *l, Member *r);
+struct string_list {
+    char *string;
+    struct string_list *next;
+};
 
 %}
 
 %union {
-  int constant;
-  char *name;
-  Type *type;
-  Member *member;
-  char *defval;
+    int constant;
+    struct value *value;
+    struct range range;
+    char *name;
+    Type *type;
+    Member *member;
+    struct objid *objid;
+    char *defval;
+    struct string_list *sl;
+    struct tagtype tag;
+    struct memhead *members;
 }
 
-%token INTEGER SEQUENCE CHOICE OF OCTET STRING GeneralizedTime GeneralString 
-%token BIT APPLICATION OPTIONAL EEQUAL TBEGIN END DEFINITIONS ENUMERATED
-%token UTF8String NULLTYPE
-%token EXTERNAL DEFAULT
-%token DOTDOT DOTDOTDOT
-%token BOOLEAN
-%token IMPORTS FROM
-%token OBJECT IDENTIFIER
-%token <name> IDENT 
-%token <constant> CONSTANT
+%token kw_ABSENT
+%token kw_ABSTRACT_SYNTAX
+%token kw_ALL
+%token kw_APPLICATION
+%token kw_AUTOMATIC
+%token kw_BEGIN
+%token kw_BIT
+%token kw_BMPString
+%token kw_BOOLEAN
+%token kw_BY
+%token kw_CHARACTER
+%token kw_CHOICE
+%token kw_CLASS
+%token kw_COMPONENT
+%token kw_COMPONENTS
+%token kw_CONSTRAINED
+%token kw_CONTAINING
+%token kw_DEFAULT
+%token kw_DEFINITIONS
+%token kw_EMBEDDED
+%token kw_ENCODED
+%token kw_END
+%token kw_ENUMERATED
+%token kw_EXCEPT
+%token kw_EXPLICIT
+%token kw_EXPORTS
+%token kw_EXTENSIBILITY
+%token kw_EXTERNAL
+%token kw_FALSE
+%token kw_FROM
+%token kw_GeneralString
+%token kw_GeneralizedTime
+%token kw_GraphicString
+%token kw_IA5String
+%token kw_IDENTIFIER
+%token kw_IMPLICIT
+%token kw_IMPLIED
+%token kw_IMPORTS
+%token kw_INCLUDES
+%token kw_INSTANCE
+%token kw_INTEGER
+%token kw_INTERSECTION
+%token kw_ISO646String
+%token kw_MAX
+%token kw_MIN
+%token kw_MINUS_INFINITY
+%token kw_NULL
+%token kw_NumericString
+%token kw_OBJECT
+%token kw_OCTET
+%token kw_OF
+%token kw_OPTIONAL
+%token kw_ObjectDescriptor
+%token kw_PATTERN
+%token kw_PDV
+%token kw_PLUS_INFINITY
+%token kw_PRESENT
+%token kw_PRIVATE
+%token kw_PrintableString
+%token kw_REAL
+%token kw_RELATIVE_OID
+%token kw_SEQUENCE
+%token kw_SET
+%token kw_SIZE
+%token kw_STRING
+%token kw_SYNTAX
+%token kw_T61String
+%token kw_TAGS
+%token kw_TRUE
+%token kw_TYPE_IDENTIFIER
+%token kw_TeletexString
+%token kw_UNION
+%token kw_UNIQUE
+%token kw_UNIVERSAL
+%token kw_UTCTime
+%token kw_UTF8String
+%token kw_UniversalString
+%token kw_VideotexString
+%token kw_VisibleString
+%token kw_WITH
+
+%token RANGE
+%token EEQUAL
+%token ELLIPSIS
+
+%token <name> IDENTIFIER  referencename
+%token <name> STRING
+
+%token <constant> NUMBER
+%type <constant> SignedNumber
+%type <constant> Class tagenv
+
+%type <value> Value
+%type <value> BuiltinValue
+%type <value> IntegerValue
+%type <value> BooleanValue
+%type <value> ObjectIdentifierValue
+%type <value> CharacterStringValue
+%type <value> NullValue
+%type <value> DefinedValue
+%type <value> ReferencedValue
+%type <value> Valuereference
+
+%type <type> Type
+%type <type> BuiltinType
+%type <type> BitStringType
+%type <type> BooleanType
+%type <type> ChoiceType
+%type <type> EnumeratedType
+%type <type> IntegerType
+%type <type> NullType
+%type <type> OctetStringType
+%type <type> SequenceType
+%type <type> SequenceOfType
+%type <type> SetType
+%type <type> SetOfType
+%type <type> TaggedType
+%type <type> ReferencedType
+%type <type> DefinedType
+%type <type> UsefulType
+%type <type> ObjectIdentifierType
+%type <type> CharacterStringType
+%type <type> RestrictedCharactedStringType
+
+%type <tag> Tag
+
+%type <member> ComponentType
+%type <member> NamedBit
+%type <member> NamedNumber
+%type <member> NamedType
+%type <members> ComponentTypeList 
+%type <members> Enumerations
+%type <members> NamedBitList
+%type <members> NamedNumberList
+
+%type <objid> objid objid_list objid_element objid_opt
+%type <range> range
+
+%type <sl> referencenames
+
+%start ModuleDefinition
 
-%type <constant> constant optional2
-%type <type> type
-%type <member> memberdecls memberdecl memberdeclstart bitdecls bitdecl
+%%
 
-%type <defval> defvalue
+ModuleDefinition: IDENTIFIER kw_DEFINITIONS TagDefault ExtensionDefault
+                       EEQUAL kw_BEGIN ModuleBody kw_END
+               {
+                       checkundefined();
+               }
+               ;
 
-%start envelope
+TagDefault     : kw_EXPLICIT kw_TAGS
+               | kw_IMPLICIT kw_TAGS
+                     { error_message("implicit tagging is not supported"); }
+               | kw_AUTOMATIC kw_TAGS
+                     { error_message("automatic tagging is not supported"); }
+               | /* empty */
+               ;
 
-%%
+ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
+                     { error_message("no extensibility options supported"); }
+               | /* empty */
+               ;
 
-envelope       : IDENT DEFINITIONS EEQUAL TBEGIN specification END {}
+ModuleBody     : /* Exports */ Imports AssignmentList
+               | /* empty */
                ;
 
-specification  :
-               | specification declaration
+Imports                : kw_IMPORTS SymbolsImported ';'
+               | /* empty */
                ;
 
-declaration    : imports_decl
-               | type_decl
-               | constant_decl
+SymbolsImported        : SymbolsFromModuleList
+               | /* empty */
                ;
 
-referencenames : IDENT ',' referencenames
-               {
-                       Symbol *s = addsym($1);
+SymbolsFromModuleList: SymbolsFromModule
+               | SymbolsFromModuleList SymbolsFromModule
+               ;
+
+SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
+               { 
+                   struct string_list *sl;
+                   for(sl = $1; sl != NULL; sl = sl->next) {
+                       Symbol *s = addsym(sl->string);
                        s->stype = Stype;
+                   }
+                   add_import($3);
                }
-               | IDENT
+               ;
+
+AssignmentList : Assignment
+               | Assignment AssignmentList
+               ;
+
+Assignment     : TypeAssignment
+               | ValueAssignment
+               ;
+
+referencenames : IDENTIFIER ',' referencenames
                {
-                       Symbol *s = addsym($1);
-                       s->stype = Stype;
+                   $$ = emalloc(sizeof(*$$));
+                   $$->string = $1;
+                   $$->next = $3;
+               }
+               | IDENTIFIER
+               {
+                   $$ = emalloc(sizeof(*$$));
+                   $$->string = $1;
+                   $$->next = NULL;
                }
                ;
 
-imports_decl   : IMPORTS referencenames FROM IDENT ';'
-               { add_import($4); }
+TypeAssignment : IDENTIFIER EEQUAL Type
+               {
+                   Symbol *s = addsym ($1);
+                   s->stype = Stype;
+                   s->type = $3;
+                   fix_labels(s);
+                   generate_type (s);
+               }
                ;
 
-type_decl      : IDENT EEQUAL type
+Type           : BuiltinType
+               | ReferencedType
+               ;
+
+BuiltinType    : BitStringType
+               | BooleanType
+               | CharacterStringType
+               | ChoiceType
+               | EnumeratedType
+               | IntegerType
+               | NullType
+               | ObjectIdentifierType
+               | OctetStringType
+               | SequenceType
+               | SequenceOfType
+               | SetType
+               | SetOfType
+               | TaggedType
+               ;
+
+BooleanType    : kw_BOOLEAN
                {
-                 Symbol *s = addsym ($1);
-                 s->stype = Stype;
-                 s->type = $3;
-                 generate_type (s);
+                       $$ = new_tag(ASN1_C_UNIV, UT_Boolean, 
+                                    TE_EXPLICIT, new_type(TBoolean));
                }
                ;
 
-constant_decl  : IDENT type EEQUAL constant
+range          : '(' Value RANGE Value ')'
                {
-                 Symbol *s = addsym ($1);
-                 s->stype = SConstant;
-                 s->constant = $4;
-                 generate_constant (s);
+                       if($2->type != integervalue || 
+                          $4->type != integervalue)
+                               error_message("Non-integer value used in range");
+                       $$.min = $2->u.integervalue;
+                       $$.max = $4->u.integervalue;
                }
                ;
 
-type           : INTEGER     { $$ = new_type(TInteger); }
-               | INTEGER '(' constant DOTDOT constant ')' {
-                   if($3 != 0)
-                       error_message("Only 0 supported as low range");
-                   if($5 != INT_MIN && $5 != UINT_MAX && $5 != INT_MAX)
-                       error_message("Only %u supported as high range",
-                                     UINT_MAX);
-                   $$ = new_type(TUInteger);
+IntegerType    : kw_INTEGER
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_Integer, 
+                                    TE_EXPLICIT, new_type(TInteger));
                }
-                | INTEGER '{' bitdecls '}'
-                {
+               | kw_INTEGER range
+               {
                        $$ = new_type(TInteger);
-                       $$->members = $3;
-                }
-               | OBJECT IDENTIFIER { $$ = new_type(TOID); }
-               | ENUMERATED '{' bitdecls '}'
+                       $$->range = emalloc(sizeof(*$$->range));
+                       *($$->range) = $2;
+                       $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
+               }
+               | kw_INTEGER '{' NamedNumberList '}'
                {
-                       $$ = new_type(TEnumerated);
-                       $$->members = $3;
+                 $$ = new_type(TInteger);
+                 $$->members = $3;
+                 $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
                }
-               | OCTET STRING { $$ = new_type(TOctetString); }
-               | GeneralString { $$ = new_type(TGeneralString); }
-               | UTF8String { $$ = new_type(TUTF8String); }
-                | NULLTYPE { $$ = new_type(TNull); }
-               | GeneralizedTime { $$ = new_type(TGeneralizedTime); }
-               | SEQUENCE OF type
+               ;
+
+NamedNumberList        : NamedNumber
                {
-                 $$ = new_type(TSequenceOf);
-                 $$->subtype = $3;
+                       $$ = emalloc(sizeof(*$$));
+                       ASN1_TAILQ_INIT($$);
+                       ASN1_TAILQ_INSERT_HEAD($$, $1, members);
                }
-               | SEQUENCE '{' memberdecls '}'
+               | NamedNumberList ',' NamedNumber
                {
-                 $$ = new_type(TSequence);
-                 $$->members = $3;
+                       ASN1_TAILQ_INSERT_TAIL($1, $3, members);
+                       $$ = $1;
                }
-               | CHOICE '{' memberdecls '}'
+               | NamedNumberList ',' ELLIPSIS
+                       { $$ = $1; } /* XXX used for Enumerations */
+               ;
+
+NamedNumber    : IDENTIFIER '(' SignedNumber ')'
                {
-                 $$ = new_type(TChoice);
+                       $$ = emalloc(sizeof(*$$));
+                       $$->name = $1;
+                       $$->gen_name = estrdup($1);
+                       output_name ($$->gen_name);
+                       $$->val = $3;
+                       $$->optional = 0;
+                       $$->ellipsis = 0;
+                       $$->type = NULL;
+               }
+               ;
+
+EnumeratedType : kw_ENUMERATED '{' Enumerations '}'
+               {
+                 $$ = new_type(TInteger);
                  $$->members = $3;
+                 $$ = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, $$);
+               }
+               ;
+
+Enumerations   : NamedNumberList /* XXX */
+               ;
+
+BitStringType  : kw_BIT kw_STRING
+               {
+                 $$ = new_type(TBitString);
+                 $$->members = emalloc(sizeof(*$$->members));
+                 ASN1_TAILQ_INIT($$->members);
+                 $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
                }
-               | BIT STRING '{' bitdecls '}'
+               | kw_BIT kw_STRING '{' NamedBitList '}'
                {
                  $$ = new_type(TBitString);
                  $$->members = $4;
+                 $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
                }
-               | IDENT
+               ;
+
+ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_OID, 
+                                    TE_EXPLICIT, new_type(TOID));
+               }
+               ;
+OctetStringType        : kw_OCTET kw_STRING
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_OctetString, 
+                                    TE_EXPLICIT, new_type(TOctetString));
+               }
+               ;
+
+NullType       : kw_NULL
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_Null, 
+                                    TE_EXPLICIT, new_type(TNull));
+               }
+               ;
+
+SequenceType   : kw_SEQUENCE '{' /* ComponentTypeLists */ ComponentTypeList '}'
+               {
+                 $$ = new_type(TSequence);
+                 $$->members = $3;
+                 $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
+               }
+               | kw_SEQUENCE '{' '}'
+               {
+                 $$ = new_type(TSequence);
+                 $$->members = NULL;
+                 $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
+               }
+               ;
+
+SequenceOfType : kw_SEQUENCE kw_OF Type
+               {
+                 $$ = new_type(TSequenceOf);
+                 $$->subtype = $3;
+                 $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
+               }
+               ;
+
+SetType                : kw_SET '{' /* ComponentTypeLists */ ComponentTypeList '}'
+               {
+                 $$ = new_type(TSet);
+                 $$->members = $3;
+                 $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
+               }
+               | kw_SET '{' '}'
+               {
+                 $$ = new_type(TSet);
+                 $$->members = NULL;
+                 $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
+               }
+               ;
+
+SetOfType      : kw_SET kw_OF Type
+               {
+                 $$ = new_type(TSetOf);
+                 $$->subtype = $3;
+                 $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
+               }
+               ;
+
+ChoiceType     : kw_CHOICE '{' /* AlternativeTypeLists */ ComponentTypeList '}'
+               {
+                 $$ = new_type(TChoice);
+                 $$->members = $3;
+               }
+               ;
+
+ReferencedType : DefinedType
+               | UsefulType
+               ;
+
+DefinedType    : IDENTIFIER
                {
                  Symbol *s = addsym($1);
                  $$ = new_type(TType);
-                 if(s->stype != Stype)
+                 if(s->stype != Stype && s->stype != SUndefined)
                    error_message ("%s is not a type\n", $1);
                  else
                    $$->symbol = s;
                }
-               | '[' APPLICATION constant ']' type
+               ;
+
+UsefulType     : kw_GeneralizedTime
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_GeneralizedTime, 
+                                    TE_EXPLICIT, new_type(TGeneralizedTime));
+               }
+               | kw_UTCTime
                {
-                 $$ = new_type(TApplication);
-                 $$->subtype = $5;
-                 $$->application = $3;
+                       $$ = new_tag(ASN1_C_UNIV, UT_UTCTime, 
+                                    TE_EXPLICIT, new_type(TUTCTime));
                }
-               | BOOLEAN     { $$ = new_type(TBoolean); }
                ;
 
-memberdecls    : { $$ = NULL; }
-               | memberdecl    { $$ = $1; }
-               | memberdecls  ',' DOTDOTDOT { $$ = $1; }
-               | memberdecls ',' memberdecl { $$ = $1; append($$, $3); }
+TaggedType     : Tag tagenv Type
+               {
+                       $$ = new_type(TTag);
+                       $$->tag = $1;
+                       $$->tag.tagenv = $2;
+                       if($3->type == TTag && $2 == TE_IMPLICIT) {
+                               $$->subtype = $3->subtype;
+                               free($3);
+                       } else
+                               $$->subtype = $3;
+               }
                ;
 
-memberdeclstart : IDENT '[' constant ']' type
+Tag            : '[' Class NUMBER ']'
                {
-                 $$ = malloc(sizeof(*$$));
-                 $$->name = $1;
-                 $$->gen_name = strdup($1);
-                 output_name ($$->gen_name);
-                 $$->val = $3;
-                 $$->optional = 0;
-                 $$->defval = NULL;
-                 $$->type = $5;
-                 $$->next = $$->prev = $$;
+                       $$.tagclass = $2;
+                       $$.tagvalue = $3;
+                       $$.tagenv = TE_EXPLICIT;
                }
                ;
 
+Class          : /* */
+               {
+                       $$ = ASN1_C_CONTEXT;
+               }
+               | kw_UNIVERSAL
+               {
+                       $$ = ASN1_C_UNIV;
+               }
+               | kw_APPLICATION
+               {
+                       $$ = ASN1_C_APPL;
+               }
+               | kw_PRIVATE
+               {
+                       $$ = ASN1_C_PRIVATE;
+               }
+               ;
+
+tagenv         : /* */
+               {
+                       $$ = TE_EXPLICIT;
+               }
+               | kw_EXPLICIT
+               {
+                       $$ = TE_EXPLICIT;
+               }
+               | kw_IMPLICIT
+               {
+                       $$ = TE_IMPLICIT;
+               }
+               ;
+
+
+ValueAssignment        : IDENTIFIER Type EEQUAL Value
+               {
+                       Symbol *s;
+                       s = addsym ($1);
+
+                       s->stype = SValue;
+                       s->value = $4;
+                       generate_constant (s);
+               }
+               ;
+
+CharacterStringType: RestrictedCharactedStringType
+               ;
+
+RestrictedCharactedStringType: kw_GeneralString
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_GeneralString, 
+                                    TE_EXPLICIT, new_type(TGeneralString));
+               }
+               | kw_UTF8String
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_UTF8String, 
+                                    TE_EXPLICIT, new_type(TUTF8String));
+               }
+               | kw_PrintableString
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_PrintableString, 
+                                    TE_EXPLICIT, new_type(TPrintableString));
+               }
+               | kw_IA5String
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_IA5String, 
+                                    TE_EXPLICIT, new_type(TIA5String));
+               }
+               | kw_BMPString
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_BMPString, 
+                                    TE_EXPLICIT, new_type(TBMPString));
+               }
+               | kw_UniversalString
+               {
+                       $$ = new_tag(ASN1_C_UNIV, UT_UniversalString, 
+                                    TE_EXPLICIT, new_type(TUniversalString));
+               }
 
-memberdecl     : memberdeclstart optional2
-               { $1->optional = $2 ; $$ = $1; }
-               | memberdeclstart defvalue
-               { $1->defval = $2 ; $$ = $1; }
-               | memberdeclstart
-               { $$ = $1; }
                ;
 
+ComponentTypeList: ComponentType
+               {
+                       $$ = emalloc(sizeof(*$$));
+                       ASN1_TAILQ_INIT($$);
+                       ASN1_TAILQ_INSERT_HEAD($$, $1, members);
+               }
+               | ComponentTypeList ',' ComponentType
+               {
+                       ASN1_TAILQ_INSERT_TAIL($1, $3, members);
+                       $$ = $1;
+               }
+               | ComponentTypeList ',' ELLIPSIS
+               {
+                       struct member *m = ecalloc(1, sizeof(*m));
+                       m->name = estrdup("...");
+                       m->gen_name = estrdup("asn1_ellipsis");
+                       m->ellipsis = 1;
+                       ASN1_TAILQ_INSERT_TAIL($1, m, members);
+                       $$ = $1;
+               }
+               ;
 
-optional2      : OPTIONAL { $$ = 1; }
+NamedType      : IDENTIFIER Type
+               {
+                 $$ = emalloc(sizeof(*$$));
+                 $$->name = $1;
+                 $$->gen_name = estrdup($1);
+                 output_name ($$->gen_name);
+                 $$->type = $2;
+                 $$->ellipsis = 0;
+               }
                ;
 
-defvalue       : DEFAULT constant
-               { asprintf(&$$, "%d", $2); }
-               | DEFAULT '"' IDENT '"'
-               { $$ = strdup ($3); }
+ComponentType  : NamedType
+               {
+                       $$ = $1;
+                       $$->optional = 0;
+                       $$->defval = NULL;
+               }
+               | NamedType kw_OPTIONAL
+               {
+                       $$ = $1;
+                       $$->optional = 1;
+                       $$->defval = NULL;
+               }
+               | NamedType kw_DEFAULT Value
+               {
+                       $$ = $1;
+                       $$->optional = 0;
+                       $$->defval = $3;
+               }
                ;
 
-bitdecls       : { $$ = NULL; }
-               | bitdecl { $$ = $1; }
-               | bitdecls ',' DOTDOTDOT { $$ = $1; }
-               | bitdecls ',' bitdecl { $$ = $1; append($$, $3); }
+NamedBitList   : NamedBit
+               {
+                       $$ = emalloc(sizeof(*$$));
+                       ASN1_TAILQ_INIT($$);
+                       ASN1_TAILQ_INSERT_HEAD($$, $1, members);
+               }
+               | NamedBitList ',' NamedBit
+               {
+                       ASN1_TAILQ_INSERT_TAIL($1, $3, members);
+                       $$ = $1;
+               }
                ;
 
-bitdecl                : IDENT '(' constant ')'
+NamedBit       : IDENTIFIER '(' NUMBER ')'
                {
-                 $$ = malloc(sizeof(*$$));
+                 $$ = emalloc(sizeof(*$$));
                  $$->name = $1;
-                 $$->gen_name = strdup($1);
+                 $$->gen_name = estrdup($1);
                  output_name ($$->gen_name);
                  $$->val = $3;
                  $$->optional = 0;
+                 $$->ellipsis = 0;
                  $$->type = NULL;
-                 $$->prev = $$->next = $$;
                }
                ;
 
-constant       : CONSTANT      { $$ = $1; }
-               | '-' CONSTANT  { $$ = -$2; }
-               | IDENT {
-                                 Symbol *s = addsym($1);
-                                 if(s->stype != SConstant)
-                                   error_message ("%s is not a constant\n",
-                                                  s->name);
-                                 else
-                                   $$ = s->constant;
-                               }
+objid_opt      : objid
+               | /* empty */ { $$ = NULL; }
+               ;
+
+objid          : '{' objid_list '}'
+               {
+                       $$ = $2;
+               }
+               ;
+
+objid_list     :  /* empty */
+               {
+                       $$ = NULL;
+               }
+               | objid_element objid_list
+               {
+                       if ($2) {
+                               $$ = $2;
+                               add_oid_to_tail($2, $1);
+                       } else {
+                               $$ = $1;
+                       }
+               }
+               ;
+
+objid_element  : IDENTIFIER '(' NUMBER ')'
+               {
+                       $$ = new_objid($1, $3);
+               }
+               | IDENTIFIER
+               {
+                   Symbol *s = addsym($1);
+                   if(s->stype != SValue ||
+                      s->value->type != objectidentifiervalue) {
+                       error_message("%s is not an object identifier\n", 
+                                     s->name);
+                       exit(1);
+                   }
+                   $$ = s->value->u.objectidentifiervalue;
+               }
+               | NUMBER
+               {
+                   $$ = new_objid(NULL, $1);
+               }
+               ;
+
+Value          : BuiltinValue
+               | ReferencedValue
+               ;
+
+BuiltinValue   : BooleanValue
+               | CharacterStringValue
+               | IntegerValue
+               | ObjectIdentifierValue
+               | NullValue
+               ;
+
+ReferencedValue        : DefinedValue
+               ;
+
+DefinedValue   : Valuereference
+               ;
+
+Valuereference : IDENTIFIER
+               {
+                       Symbol *s = addsym($1);
+                       if(s->stype != SValue)
+                               error_message ("%s is not a value\n",
+                                               s->name);
+                       else
+                               $$ = s->value;
+               }
+               ;
+
+CharacterStringValue: STRING
+               {
+                       $$ = emalloc(sizeof(*$$));
+                       $$->type = stringvalue;
+                       $$->u.stringvalue = $1;
+               }
+               ;
+
+BooleanValue   : kw_TRUE
+               {
+                       $$ = emalloc(sizeof(*$$));
+                       $$->type = booleanvalue;
+                       $$->u.booleanvalue = 0;
+               }
+               | kw_FALSE
+               {
+                       $$ = emalloc(sizeof(*$$));
+                       $$->type = booleanvalue;
+                       $$->u.booleanvalue = 0;
+               }
+               ;
+
+IntegerValue   : SignedNumber
+               {
+                       $$ = emalloc(sizeof(*$$));
+                       $$->type = integervalue;
+                       $$->u.integervalue = $1;
+               }
+               ;
+
+SignedNumber   : NUMBER
+               ;
+
+NullValue      : kw_NULL
+               {
+               }
                ;
+
+ObjectIdentifierValue: objid
+               {
+                       $$ = emalloc(sizeof(*$$));
+                       $$->type = objectidentifiervalue;
+                       $$->u.objectidentifiervalue = $1;
+               }
+               ;
+
 %%
 
 void
@@ -268,28 +815,81 @@ yyerror (char *s)
      error_message ("%s\n", s);
 }
 
+static Type *
+new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
+{
+    Type *t;
+    if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
+       t = oldtype;
+       oldtype = oldtype->subtype; /* XXX */
+    } else
+       t = new_type (TTag);
+    
+    t->tag.tagclass = tagclass;
+    t->tag.tagvalue = tagvalue;
+    t->tag.tagenv = tagenv;
+    t->subtype = oldtype;
+    return t;
+}
+
+static struct objid *
+new_objid(const char *label, int value)
+{
+    struct objid *s;
+    s = emalloc(sizeof(*s));
+    s->label = label;
+    s->value = value;
+    s->next = NULL;
+    return s;
+}
+
+static void
+add_oid_to_tail(struct objid *head, struct objid *tail)
+{
+    struct objid *o;
+    o = head;
+    while (o->next)
+       o = o->next;
+    o->next = tail;
+}
+
 static Type *
 new_type (Typetype tt)
 {
-  Type *t = malloc(sizeof(*t));
-  if (t == NULL) {
-      error_message ("out of memory in malloc(%lu)", 
-                    (unsigned long)sizeof(*t));
-      exit (1);
-  }
-  t->type = tt;
-  t->application = 0;
-  t->members = NULL;
-  t->subtype = NULL;
-  t->symbol  = NULL;
-  return t;
+    Type *t = ecalloc(1, sizeof(*t));
+    t->type = tt;
+    return t;
+}
+
+static void fix_labels2(Type *t, const char *prefix);
+static void fix_labels1(struct memhead *members, const char *prefix)
+{
+    Member *m;
+
+    if(members == NULL)
+       return;
+    ASN1_TAILQ_FOREACH(m, members, members) {
+       asprintf(&m->label, "%s_%s", prefix, m->gen_name);
+       if (m->label == NULL)
+           errx(1, "malloc");
+       if(m->type != NULL)
+           fix_labels2(m->type, m->label);
+    }
+}
+
+static void fix_labels2(Type *t, const char *prefix)
+{
+    for(; t; t = t->subtype)
+       fix_labels1(t->members, prefix);
 }
 
 static void
-append (Member *l, Member *r)
+fix_labels(Symbol *s)
 {
-  l->prev->next = r;
-  r->prev = l->prev;
-  l->prev = r;
-  r->next = l;
+    char *p;
+    asprintf(&p, "choice_%s", s->gen_name);
+    if (p == NULL)
+       errx(1, "malloc");
+    fix_labels2(s->type, p);
+    free(p);
 }
diff --git a/source4/heimdal/lib/asn1/pkcs12.asn1 b/source4/heimdal/lib/asn1/pkcs12.asn1
new file mode 100644 (file)
index 0000000..ff512e8
--- /dev/null
@@ -0,0 +1,81 @@
+-- $Id: pkcs12.asn1,v 1.3 2005/07/23 11:07:39 lha Exp $ --
+
+PKCS12 DEFINITIONS ::=
+
+BEGIN
+
+IMPORTS ContentInfo FROM cms
+       DigestInfo FROM rfc2459
+       heim_any, heim_any_set FROM heim;
+
+-- The PFX PDU
+
+id-pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+       rsadsi(113549) pkcs(1) pkcs-12(12) }
+
+id-pkcs-12PbeIds                   OBJECT IDENTIFIER ::= { id-pkcs-12 1}
+id-pbeWithSHAAnd128BitRC4          OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 1}
+id-pbeWithSHAAnd40BitRC4           OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 2}
+id-pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 3}
+id-pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 4}
+id-pbeWithSHAAnd128BitRC2-CBC      OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 5}
+id-pbewithSHAAnd40BitRC2-CBC       OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 6}
+
+id-pkcs12-bagtypes             OBJECT IDENTIFIER ::= { id-pkcs-12 10 1}
+
+id-pkcs12-keyBag               OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 1 }
+id-pkcs12-pkcs8ShroudedKeyBag  OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 2 }
+id-pkcs12-certBag              OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 3 }
+id-pkcs12-crlBag               OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 4 }
+id-pkcs12-secretBag            OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 5 }
+id-pkcs12-safeContentsBag      OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 6 }
+
+
+PKCS12-MacData ::= SEQUENCE {
+       mac             DigestInfo,
+       macSalt         OCTET STRING,
+       iterations      INTEGER OPTIONAL
+}
+
+PKCS12-PFX ::= SEQUENCE {
+       version         INTEGER,
+       authSafe        ContentInfo,
+       macData         PKCS12-MacData OPTIONAL
+}
+
+PKCS12-AuthenticatedSafe ::= SEQUENCE OF ContentInfo
+       -- Data if unencrypted
+       -- EncryptedData if password-encrypted
+       -- EnvelopedData if public key-encrypted
+
+PKCS12-Attribute ::= SEQUENCE {
+       attrId          OBJECT IDENTIFIER,
+       attrValues      -- SET OF -- heim_any_set 
+}
+
+PKCS12-Attributes ::= SET OF PKCS12-Attribute
+
+PKCS12-SafeBag ::= SEQUENCE {
+       bagId           OBJECT IDENTIFIER,
+       bagValue        [0] heim_any,
+       bagAttributes   PKCS12-Attributes OPTIONAL
+}
+
+PKCS12-SafeContents ::= SEQUENCE OF PKCS12-SafeBag
+
+PKCS12-CertBag ::= SEQUENCE {
+       certType        OBJECT IDENTIFIER,
+       certValue       [0] heim_any
+}
+
+PKCS12-PBEParams ::= SEQUENCE {
+       salt            OCTET STRING,
+       iterations      INTEGER (0..4294967295) OPTIONAL
+}
+
+PKCS12-OctetString ::= OCTET STRING
+
+-- KeyBag ::= PrivateKeyInfo
+-- PKCS8ShroudedKeyBag ::= EncryptedPrivateKeyInfo
+
+END
diff --git a/source4/heimdal/lib/asn1/pkcs8.asn1 b/source4/heimdal/lib/asn1/pkcs8.asn1
new file mode 100644 (file)
index 0000000..823e566
--- /dev/null
@@ -0,0 +1,30 @@
+-- $Id: pkcs8.asn1,v 1.2 2005/07/12 06:27:36 lha Exp $ --
+
+PKCS8 DEFINITIONS ::=
+
+BEGIN
+
+IMPORTS        Attribute, AlgorithmIdentifier FROM rfc2459
+       heim_any, heim_any_set FROM heim;
+
+PKCS8PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+
+PKCS8PrivateKey ::= OCTET STRING
+
+PKCS8Attributes ::= SET OF Attribute
+
+PKCS8PrivateKeyInfo ::= SEQUENCE {
+  version INTEGER,
+  privateKeyAlgorithm PKCS8PrivateKeyAlgorithmIdentifier,
+  privateKey PKCS8PrivateKey,
+  attributes [0] IMPLICIT PKCS8Attributes OPTIONAL
+}
+
+PKCS8EncryptedData ::= OCTET STRING
+
+PKCS8EncryptedPrivateKeyInfo ::= SEQUENCE {
+    encryptionAlgorithm AlgorithmIdentifier,
+    encryptedData PKCS8EncryptedData 
+}
+
+END
diff --git a/source4/heimdal/lib/asn1/pkcs9.asn1 b/source4/heimdal/lib/asn1/pkcs9.asn1
new file mode 100644 (file)
index 0000000..bcc8f50
--- /dev/null
@@ -0,0 +1,27 @@
+-- $Id: pkcs9.asn1,v 1.3 2005/07/23 10:38:28 lha Exp $ --
+
+PKCS9 DEFINITIONS ::=
+
+BEGIN
+
+-- The PFX PDU
+
+id-pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
+       rsadsi(113549) pkcs(1) pkcs-9(9) }
+
+id-pkcs9-contentType           OBJECT IDENTIFIER ::= {id-pkcs-9 3 }
+id-pkcs9-messageDigest         OBJECT IDENTIFIER ::= {id-pkcs-9 4 }
+id-pkcs9-signingTime           OBJECT IDENTIFIER ::= {id-pkcs-9 5 }
+id-pkcs9-countersignature      OBJECT IDENTIFIER ::= {id-pkcs-9 6 }
+
+id-pkcs-9-at-friendlyName      OBJECT IDENTIFIER ::= {id-pkcs-9 20}
+id-pkcs-9-at-localKeyId                OBJECT IDENTIFIER ::= {id-pkcs-9 21}
+id-pkcs-9-at-certTypes         OBJECT IDENTIFIER ::= {id-pkcs-9 22}
+id-pkcs-9-at-certTypes-x509    OBJECT IDENTIFIER ::= {id-pkcs-9-at-certTypes 1}
+
+PKCS9-BMPString ::= BMPString
+
+PKCS9-friendlyName ::= SET OF PKCS9-BMPString
+
+END
+
index 5f69c1092543c25be22061aaafd8f7ba69188649..a4e1ed48848c92a3aa1f56c1f09d8e5e534f1a7c 100644 (file)
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
  *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
+ * 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 above copyright 
- *    notice, this list of conditions and the following disclaimer. 
+ * 1. Redistributions of source code must retain the above 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. 
+ * 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. Neither the name of the Institute nor the names of its contributors 
- *    may be used to endorse or promote products derived from this software 
- *    without specific prior written permission. 
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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. 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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.
  */
 
 #include "gen_locl.h"
+#include "lex.h"
 
-RCSID("$Id: symbol.c,v 1.9 2001/09/25 13:39:27 assar Exp $");
+RCSID("$Id: symbol.c,v 1.10 2005/07/12 06:27:39 lha Exp $");
 
 static Hashtab *htab;
 
 static int
-cmp (void *a, void *b)
+cmp(void *a, void *b)
 {
-  Symbol *s1 = (Symbol *)a;
-  Symbol *s2 = (Symbol *)b;
+    Symbol *s1 = (Symbol *) a;
+    Symbol *s2 = (Symbol *) b;
 
-  return strcmp (s1->name, s2->name);
+    return strcmp(s1->name, s2->name);
 }
 
 static unsigned
-hash (void *a)
+hash(void *a)
 {
-  Symbol *s = (Symbol *)a;
+    Symbol *s = (Symbol *) a;
 
-  return hashjpw (s->name);
+    return hashjpw(s->name);
 }
 
 void
-initsym (void)
+initsym(void)
 {
-  htab = hashtabnew (101, cmp, hash);
+    htab = hashtabnew(101, cmp, hash);
 }
 
 
 void
-output_name (char *s)
+output_name(char *s)
 {
-  char *p;
+    char *p;
 
-  for (p = s; *p; ++p)
-    if (*p == '-')
-      *p = '_';
+    for (p = s; *p; ++p)
+       if (*p == '-')
+           *p = '_';
 }
 
-Symbol*
-addsym (char *name)
+Symbol *
+addsym(char *name)
 {
-  Symbol key, *s;
+    Symbol key, *s;
 
-  key.name = name;
-  s = (Symbol *)hashtabsearch (htab, (void *)&key);
-  if (s == NULL) {
-    s = (Symbol *)malloc (sizeof (*s));
-    s->name = name;
-    s->gen_name = strdup(name);
-    output_name (s->gen_name);
-    s->stype = SUndefined;
-    hashtabadd (htab, s);
-  }
-  return s;
+    key.name = name;
+    s = (Symbol *) hashtabsearch(htab, (void *) &key);
+    if (s == NULL) {
+       s = (Symbol *) emalloc(sizeof(*s));
+       s->name = name;
+       s->gen_name = estrdup(name);
+       output_name(s->gen_name);
+       s->stype = SUndefined;
+       hashtabadd(htab, s);
+    }
+    return s;
+}
+
+static int
+checkfunc(void *ptr, void *arg)
+{
+    Symbol *s = ptr;
+    if (s->stype == SUndefined) {
+       error_message("%s is still undefined\n", s->name);
+       *(int *) arg = 1;
+    }
+    return 0;
+}
+
+int
+checkundefined(void)
+{
+    int f = 0;
+    hashtabforeach(htab, checkfunc, &f);
+    return f;
 }
index 443935cc0552ac697524eae3f5f50b9d0128d634..83df57b77f18dd02c099b384f14b018883603060 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
  * SUCH DAMAGE. 
  */
 
-/* $Id: symbol.h,v 1.11 2003/10/03 00:28:29 lha Exp $ */
+/* $Id: symbol.h,v 1.12 2005/07/12 06:27:40 lha Exp $ */
 
 #ifndef _SYMBOL_H
 #define _SYMBOL_H
 
+#include "asn1_queue.h"
+
 enum typetype { 
-    TApplication,
     TBitString,
     TBoolean,
-    TChoice,
+    TChoice, 
     TEnumerated,
-    TGeneralString,
-    TGeneralizedTime,
+    TGeneralString, 
+    TGeneralizedTime, 
+    TIA5String,
     TInteger, 
     TNull,
-    TOID,
-    TOctetString,
-    TSequence,
+    TOID, 
+    TOctetString, 
+    TPrintableString,
+    TSequence, 
     TSequenceOf,
+    TSet, 
+    TSetOf,
+    TTag, 
     TType, 
-    TUInteger,
-    TUTF8String
+    TUTCTime, 
+    TUTF8String,
+    TBMPString,
+    TUniversalString
 };
 
 typedef enum typetype Typetype;
 
 struct type;
 
+struct value {
+    enum { booleanvalue, 
+          nullvalue, 
+          integervalue, 
+          stringvalue, 
+          objectidentifiervalue
+    } type;
+    union {
+       int booleanvalue;
+       int integervalue;
+       char *stringvalue;
+       struct objid *objectidentifiervalue;
+    } u;
+};
+
 struct member {
-  char *name;
-  char *gen_name;
-  int val;
-  int optional;
-  struct type *type;
-  struct member *next, *prev;
-  char *defval;
+    char *name;
+    char *gen_name;
+    char *label;
+    int val;
+    int optional;
+    int ellipsis;
+    struct type *type;
+    ASN1_TAILQ_ENTRY(member) members;
+    struct value *defval;
 };
 
 typedef struct member Member;
 
+ASN1_TAILQ_HEAD(memhead, member);
+
 struct symbol;
 
+struct tagtype {
+    int tagclass;
+    int tagvalue;
+    enum { TE_IMPLICIT, TE_EXPLICIT } tagenv;
+};
+
+struct range {
+    int min;
+    int max;
+};
+
 struct type {
-  Typetype type;
-  int application;
-  Member *members;
-  struct type *subtype;
-  struct symbol *symbol;
+    Typetype type;
+    struct memhead *members;
+    struct symbol *symbol;
+    struct type *subtype;
+    struct tagtype tag;
+    struct range *range;
 };
 
 typedef struct type Type;
 
+struct objid {
+    const char *label;
+    int value;
+    struct objid *next;
+};
+
 struct symbol {
-  char *name;
-  char *gen_name;
-  enum { SUndefined, SConstant, Stype } stype;
-  int constant;
-  Type *type;
+    char *name;
+    char *gen_name;
+    enum { SUndefined, SValue, Stype } stype;
+    struct value *value;
+    Type *type;
 };
 
 typedef struct symbol Symbol;
@@ -96,4 +141,5 @@ typedef struct symbol Symbol;
 void initsym (void);
 Symbol *addsym (char *);
 void output_name (char *);
+int checkundefined(void);
 #endif
diff --git a/source4/heimdal/lib/asn1/test.asn1 b/source4/heimdal/lib/asn1/test.asn1
new file mode 100644 (file)
index 0000000..0010c84
--- /dev/null
@@ -0,0 +1,48 @@
+-- $Id: test.asn1,v 1.5 2005/07/21 20:48:27 lha Exp $ --
+
+TEST DEFINITIONS ::=
+
+BEGIN
+
+TESTLargeTag ::= SEQUENCE {
+       foo[127] INTEGER (-2147483648..2147483647)
+}
+
+TESTSeq ::= SEQUENCE {
+       tag0[0] INTEGER (-2147483648..2147483647),
+       tag1[1] TESTLargeTag,
+       tagless INTEGER (-2147483648..2147483647),
+       tag3[2] INTEGER (-2147483648..2147483647)
+}
+
+TESTChoice1 ::= CHOICE {
+       i1[1]   INTEGER (-2147483648..2147483647),
+       i2[2]   INTEGER (-2147483648..2147483647),
+       ...     
+}
+
+TESTChoice2 ::= CHOICE {
+       i1[1]   INTEGER (-2147483648..2147483647),
+       ...     
+}
+
+TESTInteger ::= INTEGER (-2147483648..2147483647)
+
+TESTInteger2 ::= [4] IMPLICIT TESTInteger
+TESTInteger3 ::= [5] IMPLICIT TESTInteger2
+
+TESTImplicit ::= SEQUENCE {
+       ti1[0] IMPLICIT INTEGER (-2147483648..2147483647),
+       ti2[1] IMPLICIT SEQUENCE { 
+               foo[127] INTEGER (-2147483648..2147483647)
+       },
+       ti3[2] IMPLICIT [5] IMPLICIT [4] IMPLICIT INTEGER (-2147483648..2147483647)
+}
+
+TESTImplicit2 ::= SEQUENCE {
+       ti1[0] IMPLICIT TESTInteger,
+       ti2[1] IMPLICIT TESTLargeTag,
+       ti3[2] IMPLICIT TESTInteger3
+}
+
+END
diff --git a/source4/heimdal/lib/asn1/test.gen b/source4/heimdal/lib/asn1/test.gen
new file mode 100644 (file)
index 0000000..9a1f354
--- /dev/null
@@ -0,0 +1,14 @@
+# $Id: test.gen,v 1.2 2005/07/12 06:27:41 lha Exp $
+# Sample for TESTSeq in test.asn1
+#
+
+UNIV CONS Sequence 23
+  CONTEXT CONS 0 3
+    UNIV PRIM Integer 1 01
+   CONTEXT CONS 1 8
+     UNIV CONS Sequence 6
+       CONTEXT CONS 127 3
+         UNIV PRIM Integer 1 01
+   UNIV PRIM Integer 1 01
+   CONTEXT CONS 2 3
+     UNIV PRIM Integer 1 01
index d0440762a91b27f1bb029a7558b3fbd75a762b76..925615f244c4756a1b89a7588feb75ac44c357e9 100644 (file)
@@ -1,85 +1,32 @@
-
-#line 3 "lex.yy.c"
-
-#define  YY_INT_ALIGNED short int
-
 /* A lexical scanner generated by flex */
 
+/* Scanner skeleton version:
+ * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $
+ */
+
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 31
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
 
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
 #include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+#include <unistd.h>
 
-#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
 
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
 #endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
 #endif
 
-#endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
 
+#include <stdlib.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
 /* The "const" storage-class-modifier is valid. */
 #define YY_USE_CONST
 
@@ -87,17 +34,34 @@ typedef unsigned int flex_uint32_t;
 
 #if __STDC__
 
+#define YY_USE_PROTOS
 #define YY_USE_CONST
 
 #endif /* __STDC__ */
 #endif /* ! __cplusplus */
 
+#ifdef __TURBOC__
+ #pragma warn -rch
+ #pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
 #ifdef YY_USE_CONST
 #define yyconst const
 #else
 #define yyconst
 #endif
 
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
 /* Returned upon end-of-file. */
 #define YY_NULL 0
 
@@ -112,71 +76,71 @@ typedef unsigned int flex_uint32_t;
  * but we do it the disgusting crufty way forced on us by the ()-less
  * definition of BEGIN.
  */
-#define BEGIN (yy_start) = 1 + 2 *
+#define BEGIN yy_start = 1 + 2 *
 
 /* Translate the current start state into a value that can be later handed
  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  * compatibility.
  */
-#define YY_START (((yy_start) - 1) / 2)
+#define YY_START ((yy_start - 1) / 2)
 #define YYSTATE YY_START
 
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
 
 /* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin  )
+#define YY_NEW_FILE yyrestart( yyin )
 
 #define YY_END_OF_BUFFER_CHAR 0
 
 /* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
 #define YY_BUF_SIZE 16384
-#endif
 
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
 
 extern int yyleng;
-
 extern FILE *yyin, *yyout;
 
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
 
-    #define YY_LESS_LINENO(n)
-    
-/* Return all but the first "n" matched characters back to the input stream. */
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator).  This
+ * avoids problems with code like:
+ *
+ *     if ( condition_holds )
+ *             yyless( 5 );
+ *     else
+ *             do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
 #define yyless(n) \
        do \
                { \
                /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               *yy_cp = (yy_hold_char); \
+               *yy_cp = yy_hold_char; \
                YY_RESTORE_YY_MORE_OFFSET \
-               (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+               yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
                YY_DO_BEFORE_ACTION; /* set up yytext again */ \
                } \
        while ( 0 )
 
-#define unput(c) yyunput( c, (yytext_ptr)  )
+#define unput(c) yyunput( c, yytext_ptr )
 
 /* The following is because we cannot portably get our hands on size_t
  * (without autoconf's help, which isn't available because we want
  * flex-generated scanners to compile on their own).
  */
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
 typedef unsigned int yy_size_t;
-#endif
 
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
+
 struct yy_buffer_state
        {
        FILE *yy_input_file;
@@ -213,16 +177,12 @@ struct yy_buffer_state
         */
        int yy_at_bol;
 
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-    
        /* Whether to try to fill the input buffer when we reach the
         * end of it.
         */
        int yy_fill_buffer;
 
        int yy_buffer_status;
-
 #define YY_BUFFER_NEW 0
 #define YY_BUFFER_NORMAL 1
        /* When an EOF's been seen but there's still some text to process
@@ -236,33 +196,23 @@ struct yy_buffer_state
         * just pointing yyin at a new input file.
         */
 #define YY_BUFFER_EOF_PENDING 2
-
        };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
 
-/* Stack of input buffers. */
-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+static YY_BUFFER_STATE yy_current_buffer = 0;
 
 /* We provide macros for accessing buffer states in case in the
  * future we want to put the buffer states in a more general
  * "scanner state".
- *
- * Returns the top of the stack, or NULL.
  */
-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
-                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
-                          : NULL)
+#define YY_CURRENT_BUFFER yy_current_buffer
 
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
 
 /* yy_hold_char holds the character lost when yytext is formed. */
 static char yy_hold_char;
+
 static int yy_n_chars;         /* number of characters read into yy_ch_buf */
+
+
 int yyleng;
 
 /* Points to current character in buffer. */
@@ -275,92 +225,66 @@ static int yy_start = 0;  /* start state number */
  */
 static int yy_did_buffer_switch_on_eof;
 
-void yyrestart (FILE *input_file  );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size  );
-void yy_delete_buffer (YY_BUFFER_STATE b  );
-void yy_flush_buffer (YY_BUFFER_STATE b  );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer  );
-void yypop_buffer_state (void );
+void yyrestart YY_PROTO(( FILE *input_file ));
 
-static void yyensure_buffer_stack (void );
-static void yy_load_buffer_state (void );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
 
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
+YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
 
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size  );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str  );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len  );
-
-void *yyalloc (yy_size_t  );
-void *yyrealloc (void *,yy_size_t  );
-void yyfree (void *  );
+static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
+static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
+static void yy_flex_free YY_PROTO(( void * ));
 
 #define yy_new_buffer yy_create_buffer
 
 #define yy_set_interactive(is_interactive) \
        { \
-       if ( ! YY_CURRENT_BUFFER ){ \
-        yyensure_buffer_stack (); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_is_interactive = is_interactive; \
        }
 
 #define yy_set_bol(at_bol) \
        { \
-       if ( ! YY_CURRENT_BUFFER ){\
-        yyensure_buffer_stack (); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+       if ( ! yy_current_buffer ) \
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       yy_current_buffer->yy_at_bol = at_bol; \
        }
 
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
 
 typedef unsigned char YY_CHAR;
-
 FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-
 typedef int yy_state_type;
-
-extern int yylineno;
-
-int yylineno = 1;
-
 extern char *yytext;
 #define yytext_ptr yytext
 
-static yy_state_type yy_get_previous_state (void );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
-static int yy_get_next_buffer (void );
-static void yy_fatal_error (yyconst char msg[]  );
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
 
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
  */
 #define YY_DO_BEFORE_ACTION \
-       (yytext_ptr) = yy_bp; \
-       yyleng = (size_t) (yy_cp - yy_bp); \
-       (yy_hold_char) = *yy_cp; \
+       yytext_ptr = yy_bp; \
+       yyleng = (int) (yy_cp - yy_bp); \
+       yy_hold_char = *yy_cp; \
        *yy_cp = '\0'; \
-       (yy_c_buf_p) = yy_cp;
+       yy_c_buf_p = yy_cp;
 
 #define YY_NUM_RULES 16
 #define YY_END_OF_BUFFER 17
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-       {
-       flex_int32_t yy_verify;
-       flex_int32_t yy_nxt;
-       };
-static yyconst flex_int16_t yy_accept[46] =
+static yyconst short int yy_accept[46] =
     {   0,
         0,    0,   17,   15,   11,   12,   13,   10,    9,   14,
        14,   14,   14,   10,    9,   14,    3,   14,   14,    1,
@@ -369,7 +293,7 @@ static yyconst flex_int16_t yy_accept[46] =
        14,    4,   14,    2,    0
     } ;
 
-static yyconst flex_int32_t yy_ec[256] =
+static yyconst int yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -401,14 +325,14 @@ static yyconst flex_int32_t yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[23] =
+static yyconst int yy_meta[23] =
     {   0,
         1,    1,    2,    1,    1,    3,    3,    3,    3,    3,
         3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
         3,    3
     } ;
 
-static yyconst flex_int16_t yy_base[48] =
+static yyconst short int yy_base[48] =
     {   0,
         0,    0,   56,   57,   57,   57,   57,    0,   49,    0,
        12,   13,   34,    0,   47,    0,    0,   40,   31,    0,
@@ -417,7 +341,7 @@ static yyconst flex_int16_t yy_base[48] =
        12,    0,   14,    0,   57,   34,   23
     } ;
 
-static yyconst flex_int16_t yy_def[48] =
+static yyconst short int yy_def[48] =
     {   0,
        45,    1,   45,   45,   45,   45,   45,   46,   47,   47,
        47,   47,   47,   46,   47,   47,   47,   47,   47,   47,
@@ -426,7 +350,7 @@ static yyconst flex_int16_t yy_def[48] =
        47,   47,   47,   47,    0,   45,   45
     } ;
 
-static yyconst flex_int16_t yy_nxt[80] =
+static yyconst short int yy_nxt[80] =
     {   0,
         4,    5,    6,    7,    8,    9,   10,   10,   10,   10,
        10,   10,   11,   10,   12,   10,   10,   10,   13,   10,
@@ -438,7 +362,7 @@ static yyconst flex_int16_t yy_nxt[80] =
        45,   45,   45,   45,   45,   45,   45,   45,   45
     } ;
 
-static yyconst flex_int16_t yy_chk[80] =
+static yyconst short int yy_chk[80] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -453,9 +377,6 @@ static yyconst flex_int16_t yy_chk[80] =
 static yy_state_type yy_last_accepting_state;
 static char *yy_last_accepting_cpos;
 
-extern int yy_flex_debug;
-int yy_flex_debug = 0;
-
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
  */
@@ -465,6 +386,7 @@ int yy_flex_debug = 0;
 #define YY_RESTORE_YY_MORE_OFFSET
 char *yytext;
 #line 1 "lex.l"
+#define INITIAL 0
 #line 2 "lex.l"
 /*
  * Copyright (c) 1998 - 2000 Kungliga Tekniska Högskolan
@@ -520,21 +442,7 @@ static int getstring(void);
 
 #undef ECHO
 
-#line 524 "lex.yy.c"
-
-#define INITIAL 0
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
+#line 446 "lex.yy.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -542,30 +450,65 @@ static int getstring(void);
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int yywrap (void );
+extern "C" int yywrap YY_PROTO(( void ));
 #else
-extern int yywrap (void );
+extern int yywrap YY_PROTO(( void ));
+#endif
 #endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
 #endif
 
-    static void yyunput (int c,char *buf_ptr  );
-    
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int );
+static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * );
+static int yy_flex_strlen YY_PROTO(( yyconst char * ));
 #endif
 
 #ifndef YY_NO_INPUT
-
 #ifdef __cplusplus
-static int yyinput (void );
+static int yyinput YY_PROTO(( void ));
 #else
-static int input (void );
+static int input YY_PROTO(( void ));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO(( int new_state ));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO(( void ));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO(( void ));
 #endif
 
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines.  This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
 #endif
 
 /* Amount of stuff to slurp up with each read. */
@@ -574,6 +517,7 @@ static int input (void );
 #endif
 
 /* Copy whatever the last rule matched to the standard output. */
+
 #ifndef ECHO
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
@@ -586,10 +530,9 @@ static int input (void );
  */
 #ifndef YY_INPUT
 #define YY_INPUT(buf,result,max_size) \
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+       if ( yy_current_buffer->yy_is_interactive ) \
                { \
-               int c = '*'; \
-               size_t n; \
+               int c = '*', n; \
                for ( n = 0; n < max_size && \
                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
                        buf[n] = (char) c; \
@@ -599,22 +542,9 @@ static int input (void );
                        YY_FATAL_ERROR( "input in flex scanner failed" ); \
                result = n; \
                } \
-       else \
-               { \
-               errno=0; \
-               while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
-                       { \
-                       if( errno != EINTR) \
-                               { \
-                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
-                               break; \
-                               } \
-                       errno=0; \
-                       clearerr(yyin); \
-                       } \
-               }\
-\
-
+       else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+                 && ferror( yyin ) ) \
+               YY_FATAL_ERROR( "input in flex scanner failed" );
 #endif
 
 /* No semi-colon after return; correct usage is to write "yyterminate();" -
@@ -635,18 +565,12 @@ static int input (void );
 #define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
 #endif
 
-/* end tables serialization structures and prototypes */
-
 /* Default declaration of generated scanner - a define so the user can
  * easily add parameters.
  */
 #ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex (void);
-
-#define YY_DECL int yylex (void)
-#endif /* !YY_DECL */
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
 
 /* Code executed at the beginning of each rule, after yytext and yyleng
  * have been set up.
@@ -663,28 +587,26 @@ extern int yylex (void);
 #define YY_RULE_SETUP \
        YY_USER_ACTION
 
-/** The main scanner function which does all the work.
- */
 YY_DECL
-{
+       {
        register yy_state_type yy_current_state;
-       register char *yy_cp, *yy_bp;
+       register char *yy_cp = NULL, *yy_bp = NULL;
        register int yy_act;
-    
+
 #line 59 "lex.l"
 
-#line 677 "lex.yy.c"
+#line 599 "lex.yy.c"
 
-       if ( (yy_init) )
+       if ( yy_init )
                {
-               (yy_init) = 0;
+               yy_init = 0;
 
 #ifdef YY_USER_INIT
                YY_USER_INIT;
 #endif
 
-               if ( ! (yy_start) )
-                       (yy_start) = 1; /* first start state */
+               if ( ! yy_start )
+                       yy_start = 1;   /* first start state */
 
                if ( ! yyin )
                        yyin = stdin;
@@ -692,36 +614,34 @@ YY_DECL
                if ( ! yyout )
                        yyout = stdout;
 
-               if ( ! YY_CURRENT_BUFFER ) {
-                       yyensure_buffer_stack ();
-                       YY_CURRENT_BUFFER_LVALUE =
-                               yy_create_buffer(yyin,YY_BUF_SIZE );
-               }
+               if ( ! yy_current_buffer )
+                       yy_current_buffer =
+                               yy_create_buffer( yyin, YY_BUF_SIZE );
 
-               yy_load_buffer_state( );
+               yy_load_buffer_state();
                }
 
        while ( 1 )             /* loops until end-of-file is reached */
                {
-               yy_cp = (yy_c_buf_p);
+               yy_cp = yy_c_buf_p;
 
                /* Support of yytext. */
-               *yy_cp = (yy_hold_char);
+               *yy_cp = yy_hold_char;
 
                /* yy_bp points to the position in yy_ch_buf of the start of
                 * the current run.
                 */
                yy_bp = yy_cp;
 
-               yy_current_state = (yy_start);
+               yy_current_state = yy_start;
 yy_match:
                do
                        {
                        register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
                        if ( yy_accept[yy_current_state] )
                                {
-                               (yy_last_accepting_state) = yy_current_state;
-                               (yy_last_accepting_cpos) = yy_cp;
+                               yy_last_accepting_state = yy_current_state;
+                               yy_last_accepting_cpos = yy_cp;
                                }
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
@@ -738,22 +658,24 @@ yy_find_action:
                yy_act = yy_accept[yy_current_state];
                if ( yy_act == 0 )
                        { /* have to back up */
-                       yy_cp = (yy_last_accepting_cpos);
-                       yy_current_state = (yy_last_accepting_state);
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
                        yy_act = yy_accept[yy_current_state];
                        }
 
                YY_DO_BEFORE_ACTION;
 
+
 do_action:     /* This label is used only to access EOF actions. */
 
+
                switch ( yy_act )
        { /* beginning of action switch */
                        case 0: /* must back up */
                        /* undo the effects of YY_DO_BEFORE_ACTION */
-                       *yy_cp = (yy_hold_char);
-                       yy_cp = (yy_last_accepting_cpos);
-                       yy_current_state = (yy_last_accepting_state);
+                       *yy_cp = yy_hold_char;
+                       yy_cp = yy_last_accepting_cpos;
+                       yy_current_state = yy_last_accepting_state;
                        goto yy_find_action;
 
 case 1:
@@ -812,7 +734,6 @@ YY_RULE_SETUP
 ;
        YY_BREAK
 case 12:
-/* rule 12 can match eol */
 YY_RULE_SETUP
 #line 71 "lex.l"
 { lineno++; }
@@ -837,33 +758,33 @@ YY_RULE_SETUP
 #line 75 "lex.l"
 ECHO;
        YY_BREAK
-#line 841 "lex.yy.c"
+#line 762 "lex.yy.c"
 case YY_STATE_EOF(INITIAL):
        yyterminate();
 
        case YY_END_OF_BUFFER:
                {
                /* Amount of text matched not including the EOB char. */
-               int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+               int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
 
                /* Undo the effects of YY_DO_BEFORE_ACTION. */
-               *yy_cp = (yy_hold_char);
+               *yy_cp = yy_hold_char;
                YY_RESTORE_YY_MORE_OFFSET
 
-               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+               if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
                        {
                        /* We're scanning a new file or input source.  It's
                         * possible that this happened because the user
                         * just pointed yyin at a new source and called
                         * yylex().  If so, then we have to assure
-                        * consistency between YY_CURRENT_BUFFER and our
+                        * consistency between yy_current_buffer and our
                         * globals.  Here is the right place to do so, because
                         * this is the first action (other than possibly a
                         * back-up) that will match for the new input source.
                         */
-                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+                       yy_n_chars = yy_current_buffer->yy_n_chars;
+                       yy_current_buffer->yy_input_file = yyin;
+                       yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
                        }
 
                /* Note that here we test for yy_c_buf_p "<=" to the position
@@ -873,13 +794,13 @@ case YY_STATE_EOF(INITIAL):
                 * end-of-buffer state).  Contrast this with the test
                 * in input().
                 */
-               if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+               if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
                        { /* This was really a NUL. */
                        yy_state_type yy_next_state;
 
-                       (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+                       yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
 
-                       yy_current_state = yy_get_previous_state(  );
+                       yy_current_state = yy_get_previous_state();
 
                        /* Okay, we're now positioned to make the NUL
                         * transition.  We couldn't have
@@ -892,30 +813,30 @@ case YY_STATE_EOF(INITIAL):
 
                        yy_next_state = yy_try_NUL_trans( yy_current_state );
 
-                       yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                       yy_bp = yytext_ptr + YY_MORE_ADJ;
 
                        if ( yy_next_state )
                                {
                                /* Consume the NUL. */
-                               yy_cp = ++(yy_c_buf_p);
+                               yy_cp = ++yy_c_buf_p;
                                yy_current_state = yy_next_state;
                                goto yy_match;
                                }
 
                        else
                                {
-                               yy_cp = (yy_c_buf_p);
+                               yy_cp = yy_c_buf_p;
                                goto yy_find_action;
                                }
                        }
 
-               else switch ( yy_get_next_buffer(  ) )
+               else switch ( yy_get_next_buffer() )
                        {
                        case EOB_ACT_END_OF_FILE:
                                {
-                               (yy_did_buffer_switch_on_eof) = 0;
+                               yy_did_buffer_switch_on_eof = 0;
 
-                               if ( yywrap( ) )
+                               if ( yywrap() )
                                        {
                                        /* Note: because we've taken care in
                                         * yy_get_next_buffer() to have set up
@@ -926,7 +847,7 @@ case YY_STATE_EOF(INITIAL):
                                         * YY_NULL, it'll still work - another
                                         * YY_NULL will get returned.
                                         */
-                                       (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+                                       yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
 
                                        yy_act = YY_STATE_EOF(YY_START);
                                        goto do_action;
@@ -934,30 +855,30 @@ case YY_STATE_EOF(INITIAL):
 
                                else
                                        {
-                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                       if ( ! yy_did_buffer_switch_on_eof )
                                                YY_NEW_FILE;
                                        }
                                break;
                                }
 
                        case EOB_ACT_CONTINUE_SCAN:
-                               (yy_c_buf_p) =
-                                       (yytext_ptr) + yy_amount_of_matched_text;
+                               yy_c_buf_p =
+                                       yytext_ptr + yy_amount_of_matched_text;
 
-                               yy_current_state = yy_get_previous_state(  );
+                               yy_current_state = yy_get_previous_state();
 
-                               yy_cp = (yy_c_buf_p);
-                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
                                goto yy_match;
 
                        case EOB_ACT_LAST_MATCH:
-                               (yy_c_buf_p) =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+                               yy_c_buf_p =
+                               &yy_current_buffer->yy_ch_buf[yy_n_chars];
 
-                               yy_current_state = yy_get_previous_state(  );
+                               yy_current_state = yy_get_previous_state();
 
-                               yy_cp = (yy_c_buf_p);
-                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               yy_cp = yy_c_buf_p;
+                               yy_bp = yytext_ptr + YY_MORE_ADJ;
                                goto yy_find_action;
                        }
                break;
@@ -968,7 +889,8 @@ case YY_STATE_EOF(INITIAL):
                        "fatal flex scanner internal error--no action found" );
        } /* end of action switch */
                } /* end of scanning one token */
-} /* end of yylex */
+       } /* end of yylex */
+
 
 /* yy_get_next_buffer - try to read in a new buffer
  *
@@ -977,20 +899,21 @@ case YY_STATE_EOF(INITIAL):
  *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  *     EOB_ACT_END_OF_FILE - end of file
  */
-static int yy_get_next_buffer (void)
-{
-       register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-       register char *source = (yytext_ptr);
+
+static int yy_get_next_buffer()
+       {
+       register char *dest = yy_current_buffer->yy_ch_buf;
+       register char *source = yytext_ptr;
        register int number_to_move, i;
        int ret_val;
 
-       if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+       if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
                YY_FATAL_ERROR(
                "fatal flex scanner internal error--end of buffer missed" );
 
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+       if ( yy_current_buffer->yy_fill_buffer == 0 )
                { /* Don't try to fill the buffer, so this is an EOF. */
-               if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+               if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
                        {
                        /* We matched a single character, the EOB, so
                         * treat this as a final EOF.
@@ -1010,30 +933,34 @@ static int yy_get_next_buffer (void)
        /* Try to read more data. */
 
        /* First move last chars to start of buffer. */
-       number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+       number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
 
        for ( i = 0; i < number_to_move; ++i )
                *(dest++) = *(source++);
 
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+       if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
                /* don't do the read, it's not guaranteed to return an EOF,
                 * just force an EOF
                 */
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+               yy_current_buffer->yy_n_chars = yy_n_chars = 0;
 
        else
                {
-                       size_t num_to_read =
-                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+               int num_to_read =
+                       yy_current_buffer->yy_buf_size - number_to_move - 1;
 
                while ( num_to_read <= 0 )
                        { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+                       YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
 
                        /* just a shorter name for the current buffer */
-                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+                       YY_BUFFER_STATE b = yy_current_buffer;
 
                        int yy_c_buf_p_offset =
-                               (int) ((yy_c_buf_p) - b->yy_ch_buf);
+                               (int) (yy_c_buf_p - b->yy_ch_buf);
 
                        if ( b->yy_is_our_buffer )
                                {
@@ -1046,7 +973,8 @@ static int yy_get_next_buffer (void)
 
                                b->yy_ch_buf = (char *)
                                        /* Include room in for 2 EOB chars. */
-                                       yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+                                       yy_flex_realloc( (void *) b->yy_ch_buf,
+                                                        b->yy_buf_size + 2 );
                                }
                        else
                                /* Can't grow it, we don't own it. */
@@ -1056,35 +984,35 @@ static int yy_get_next_buffer (void)
                                YY_FATAL_ERROR(
                                "fatal error - scanner input buffer overflow" );
 
-                       (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+                       yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
 
-                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+                       num_to_read = yy_current_buffer->yy_buf_size -
                                                number_to_move - 1;
-
+#endif
                        }
 
                if ( num_to_read > YY_READ_BUF_SIZE )
                        num_to_read = YY_READ_BUF_SIZE;
 
                /* Read in more data. */
-               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                       (yy_n_chars), num_to_read );
+               YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+                       yy_n_chars, num_to_read );
 
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               yy_current_buffer->yy_n_chars = yy_n_chars;
                }
 
-       if ( (yy_n_chars) == 0 )
+       if ( yy_n_chars == 0 )
                {
                if ( number_to_move == YY_MORE_ADJ )
                        {
                        ret_val = EOB_ACT_END_OF_FILE;
-                       yyrestart(yyin  );
+                       yyrestart( yyin );
                        }
 
                else
                        {
                        ret_val = EOB_ACT_LAST_MATCH;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+                       yy_current_buffer->yy_buffer_status =
                                YY_BUFFER_EOF_PENDING;
                        }
                }
@@ -1092,31 +1020,32 @@ static int yy_get_next_buffer (void)
        else
                ret_val = EOB_ACT_CONTINUE_SCAN;
 
-       (yy_n_chars) += number_to_move;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+       yy_n_chars += number_to_move;
+       yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+       yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
 
-       (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+       yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
 
        return ret_val;
-}
+       }
+
 
 /* yy_get_previous_state - get the state just before the EOB char was reached */
 
-    static yy_state_type yy_get_previous_state (void)
-{
+static yy_state_type yy_get_previous_state()
+       {
        register yy_state_type yy_current_state;
        register char *yy_cp;
-    
-       yy_current_state = (yy_start);
 
-       for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+       yy_current_state = yy_start;
+
+       for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
                {
                register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
                if ( yy_accept[yy_current_state] )
                        {
-                       (yy_last_accepting_state) = yy_current_state;
-                       (yy_last_accepting_cpos) = yy_cp;
+                       yy_last_accepting_state = yy_current_state;
+                       yy_last_accepting_cpos = yy_cp;
                        }
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
@@ -1128,23 +1057,30 @@ static int yy_get_next_buffer (void)
                }
 
        return yy_current_state;
-}
+       }
+
 
 /* yy_try_NUL_trans - try to make a transition on the NUL character
  *
  * synopsis
  *     next_state = yy_try_NUL_trans( current_state );
  */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
-{
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+       {
        register int yy_is_jam;
-       register char *yy_cp = (yy_c_buf_p);
+       register char *yy_cp = yy_c_buf_p;
 
        register YY_CHAR yy_c = 1;
        if ( yy_accept[yy_current_state] )
                {
-               (yy_last_accepting_state) = yy_current_state;
-               (yy_last_accepting_cpos) = yy_cp;
+               yy_last_accepting_state = yy_current_state;
+               yy_last_accepting_cpos = yy_cp;
                }
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
@@ -1156,73 +1092,81 @@ static int yy_get_next_buffer (void)
        yy_is_jam = (yy_current_state == 45);
 
        return yy_is_jam ? 0 : yy_current_state;
-}
+       }
 
-    static void yyunput (int c, register char * yy_bp )
-{
-       register char *yy_cp;
-    
-    yy_cp = (yy_c_buf_p);
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+       {
+       register char *yy_cp = yy_c_buf_p;
 
        /* undo effects of setting up yytext */
-       *yy_cp = (yy_hold_char);
+       *yy_cp = yy_hold_char;
 
-       if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+       if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
                { /* need to shift things up to make room */
                /* +2 for EOB chars. */
-               register int number_to_move = (yy_n_chars) + 2;
-               register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
-                                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+               register int number_to_move = yy_n_chars + 2;
+               register char *dest = &yy_current_buffer->yy_ch_buf[
+                                       yy_current_buffer->yy_buf_size + 2];
                register char *source =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+                               &yy_current_buffer->yy_ch_buf[number_to_move];
 
-               while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+               while ( source > yy_current_buffer->yy_ch_buf )
                        *--dest = *--source;
 
                yy_cp += (int) (dest - source);
                yy_bp += (int) (dest - source);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+               yy_current_buffer->yy_n_chars =
+                       yy_n_chars = yy_current_buffer->yy_buf_size;
 
-               if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+               if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
                        YY_FATAL_ERROR( "flex scanner push-back overflow" );
                }
 
        *--yy_cp = (char) c;
 
-       (yytext_ptr) = yy_bp;
-       (yy_hold_char) = *yy_cp;
-       (yy_c_buf_p) = yy_cp;
-}
+
+       yytext_ptr = yy_bp;
+       yy_hold_char = *yy_cp;
+       yy_c_buf_p = yy_cp;
+       }
+#endif /* ifndef YY_NO_UNPUT */
+
 
 #ifndef YY_NO_INPUT
 #ifdef __cplusplus
-    static int yyinput (void)
+static int yyinput()
 #else
-    static int input  (void)
+static int input()
 #endif
-
-{
+       {
        int c;
-    
-       *(yy_c_buf_p) = (yy_hold_char);
 
-       if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+       *yy_c_buf_p = yy_hold_char;
+
+       if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
                {
                /* yy_c_buf_p now points to the character we want to return.
                 * If this occurs *before* the EOB characters, then it's a
                 * valid NUL; if not, then we've hit the end of the buffer.
                 */
-               if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+               if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
                        /* This was really a NUL. */
-                       *(yy_c_buf_p) = '\0';
+                       *yy_c_buf_p = '\0';
 
                else
                        { /* need more input */
-                       int offset = (yy_c_buf_p) - (yytext_ptr);
-                       ++(yy_c_buf_p);
+                       int offset = yy_c_buf_p - yytext_ptr;
+                       ++yy_c_buf_p;
 
-                       switch ( yy_get_next_buffer(  ) )
+                       switch ( yy_get_next_buffer() )
                                {
                                case EOB_ACT_LAST_MATCH:
                                        /* This happens because yy_g_n_b()
@@ -1236,16 +1180,16 @@ static int yy_get_next_buffer (void)
                                         */
 
                                        /* Reset buffer status. */
-                                       yyrestart(yyin );
+                                       yyrestart( yyin );
 
-                                       /*FALLTHROUGH*/
+                                       /* fall through */
 
                                case EOB_ACT_END_OF_FILE:
                                        {
-                                       if ( yywrap( ) )
+                                       if ( yywrap() )
                                                return EOF;
 
-                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                       if ( ! yy_did_buffer_switch_on_eof )
                                                YY_NEW_FILE;
 #ifdef __cplusplus
                                        return yyinput();
@@ -1255,92 +1199,90 @@ static int yy_get_next_buffer (void)
                                        }
 
                                case EOB_ACT_CONTINUE_SCAN:
-                                       (yy_c_buf_p) = (yytext_ptr) + offset;
+                                       yy_c_buf_p = yytext_ptr + offset;
                                        break;
                                }
                        }
                }
 
-       c = *(unsigned char *) (yy_c_buf_p);    /* cast for 8-bit char's */
-       *(yy_c_buf_p) = '\0';   /* preserve yytext */
-       (yy_hold_char) = *++(yy_c_buf_p);
+       c = *(unsigned char *) yy_c_buf_p;      /* cast for 8-bit char's */
+       *yy_c_buf_p = '\0';     /* preserve yytext */
+       yy_hold_char = *++yy_c_buf_p;
+
 
        return c;
-}
-#endif /* ifndef YY_NO_INPUT */
+       }
+#endif /* YY_NO_INPUT */
 
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * 
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void yyrestart  (FILE * input_file )
-{
-    
-       if ( ! YY_CURRENT_BUFFER ){
-        yyensure_buffer_stack ();
-               YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer(yyin,YY_BUF_SIZE );
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+       {
+       if ( ! yy_current_buffer )
+               yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+       yy_init_buffer( yy_current_buffer, input_file );
+       yy_load_buffer_state();
        }
 
-       yy_init_buffer(YY_CURRENT_BUFFER,input_file );
-       yy_load_buffer_state( );
-}
 
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * 
- */
-    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
-{
-    
-       /* TODO. We should be able to replace this entire function body
-        * with
-        *              yypop_buffer_state();
-        *              yypush_buffer_state(new_buffer);
-     */
-       yyensure_buffer_stack ();
-       if ( YY_CURRENT_BUFFER == new_buffer )
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+       {
+       if ( yy_current_buffer == new_buffer )
                return;
 
-       if ( YY_CURRENT_BUFFER )
+       if ( yy_current_buffer )
                {
                /* Flush out information for old buffer. */
-               *(yy_c_buf_p) = (yy_hold_char);
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               *yy_c_buf_p = yy_hold_char;
+               yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+               yy_current_buffer->yy_n_chars = yy_n_chars;
                }
 
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-       yy_load_buffer_state( );
+       yy_current_buffer = new_buffer;
+       yy_load_buffer_state();
 
        /* We don't actually know whether we did this switch during
         * EOF (yywrap()) processing, but the only time this flag
         * is looked at is after yywrap() is called, so it's safe
         * to go ahead and always set it.
         */
-       (yy_did_buffer_switch_on_eof) = 1;
-}
+       yy_did_buffer_switch_on_eof = 1;
+       }
 
-static void yy_load_buffer_state  (void)
-{
-       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-       (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-       (yy_hold_char) = *(yy_c_buf_p);
-}
 
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * 
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )
-{
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+       {
+       yy_n_chars = yy_current_buffer->yy_n_chars;
+       yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+       yyin = yy_current_buffer->yy_input_file;
+       yy_hold_char = *yy_c_buf_p;
+       }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+       {
        YY_BUFFER_STATE b;
-    
-       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
@@ -1349,75 +1291,75 @@ static void yy_load_buffer_state  (void)
        /* yy_ch_buf has to be 2 characters longer than the size given because
         * we need to put in 2 end-of-buffer characters.
         */
-       b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+       b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
        if ( ! b->yy_ch_buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
 
        b->yy_is_our_buffer = 1;
 
-       yy_init_buffer(b,file );
+       yy_init_buffer( b, file );
 
        return b;
-}
+       }
 
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- * 
- */
-    void yy_delete_buffer (YY_BUFFER_STATE  b )
-{
-    
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+       {
        if ( ! b )
                return;
 
-       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+       if ( b == yy_current_buffer )
+               yy_current_buffer = (YY_BUFFER_STATE) 0;
 
        if ( b->yy_is_our_buffer )
-               yyfree((void *) b->yy_ch_buf  );
+               yy_flex_free( (void *) b->yy_ch_buf );
 
-       yyfree((void *) b  );
-}
+       yy_flex_free( (void *) b );
+       }
 
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-    
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
-    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
 
-{
-       int oerrno = errno;
-    
-       yy_flush_buffer(b );
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+
+
+       {
+       yy_flush_buffer( b );
 
        b->yy_input_file = file;
        b->yy_fill_buffer = 1;
 
-    /* If b is the current buffer, then yy_init_buffer was _probably_
-     * called from yyrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
+#if YY_ALWAYS_INTERACTIVE
+       b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+       b->yy_is_interactive = 0;
+#else
+       b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+#endif
+#endif
+       }
 
-        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-    
-       errno = oerrno;
-}
 
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * 
- */
-    void yy_flush_buffer (YY_BUFFER_STATE  b )
-{
-       if ( ! b )
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer( YY_BUFFER_STATE b )
+#else
+void yy_flush_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+
+       {
+       if ( ! b )
                return;
 
        b->yy_n_chars = 0;
@@ -1434,121 +1376,29 @@ extern int isatty (int );
        b->yy_at_bol = 1;
        b->yy_buffer_status = YY_BUFFER_NEW;
 
-       if ( b == YY_CURRENT_BUFFER )
-               yy_load_buffer_state( );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
-{
-       if (new_buffer == NULL)
-               return;
-
-       yyensure_buffer_stack();
-
-       /* This block is copied from yy_switch_to_buffer. */
-       if ( YY_CURRENT_BUFFER )
-               {
-               /* Flush out information for old buffer. */
-               *(yy_c_buf_p) = (yy_hold_char);
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
-               }
-
-       /* Only push if top exists. Otherwise, replace top. */
-       if (YY_CURRENT_BUFFER)
-               (yy_buffer_stack_top)++;
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-       /* copied from yy_switch_to_buffer. */
-       yy_load_buffer_state( );
-       (yy_did_buffer_switch_on_eof) = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  
- */
-void yypop_buffer_state (void)
-{
-       if (!YY_CURRENT_BUFFER)
-               return;
-
-       yy_delete_buffer(YY_CURRENT_BUFFER );
-       YY_CURRENT_BUFFER_LVALUE = NULL;
-       if ((yy_buffer_stack_top) > 0)
-               --(yy_buffer_stack_top);
-
-       if (YY_CURRENT_BUFFER) {
-               yy_load_buffer_state( );
-               (yy_did_buffer_switch_on_eof) = 1;
+       if ( b == yy_current_buffer )
+               yy_load_buffer_state();
        }
-}
 
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (void)
-{
-       int num_to_alloc;
-    
-       if (!(yy_buffer_stack)) {
-
-               /* First allocation is just for 2 elements, since we don't know if this
-                * scanner will even need a stack. We use 2 instead of 1 to avoid an
-                * immediate realloc on the next call.
-         */
-               num_to_alloc = 1;
-               (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
-                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               );
-               
-               memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-                               
-               (yy_buffer_stack_max) = num_to_alloc;
-               (yy_buffer_stack_top) = 0;
-               return;
-       }
-
-       if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
-
-               /* Increase the buffer to prepare for a possible push. */
-               int grow_size = 8 /* arbitrary grow size */;
 
-               num_to_alloc = (yy_buffer_stack_max) + grow_size;
-               (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
-                                                               ((yy_buffer_stack),
-                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               );
-
-               /* zero only the new slots.*/
-               memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
-               (yy_buffer_stack_max) = num_to_alloc;
-       }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * 
- * @return the newly allocated buffer state object. 
- */
-YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
-{
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
+#else
+YY_BUFFER_STATE yy_scan_buffer( base, size )
+char *base;
+yy_size_t size;
+#endif
+       {
        YY_BUFFER_STATE b;
-    
+
        if ( size < 2 ||
             base[size-2] != YY_END_OF_BUFFER_CHAR ||
             base[size-1] != YY_END_OF_BUFFER_CHAR )
                /* They forgot to leave room for the EOB's. */
                return 0;
 
-       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
        if ( ! b )
                YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
 
@@ -1562,42 +1412,47 @@ YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )
        b->yy_fill_buffer = 0;
        b->yy_buffer_status = YY_BUFFER_NEW;
 
-       yy_switch_to_buffer( );
+       yy_switch_to_buffer( b );
 
        return b;
-}
+       }
+#endif
 
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
- * 
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yy_str )
-{
-    
-       return yy_scan_bytes(yy_str,strlen(yy_str) );
-}
 
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- * 
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * bytes, int  len )
-{
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
+#else
+YY_BUFFER_STATE yy_scan_string( yy_str )
+yyconst char *yy_str;
+#endif
+       {
+       int len;
+       for ( len = 0; yy_str[len]; ++len )
+               ;
+
+       return yy_scan_bytes( yy_str, len );
+       }
+#endif
+
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
+#else
+YY_BUFFER_STATE yy_scan_bytes( bytes, len )
+yyconst char *bytes;
+int len;
+#endif
+       {
        YY_BUFFER_STATE b;
        char *buf;
        yy_size_t n;
        int i;
-    
+
        /* Get memory for full buffer, including space for trailing EOB's. */
        n = len + 2;
-       buf = (char *) yyalloc(n  );
+       buf = (char *) yy_flex_alloc( n );
        if ( ! buf )
                YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
 
@@ -1606,7 +1461,7 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * bytes, int  len )
 
        buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
 
-       b = yy_scan_buffer(buf,n );
+       b = yy_scan_buffer( buf, n );
        if ( ! b )
                YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
 
@@ -1616,164 +1471,148 @@ YY_BUFFER_STATE yy_scan_bytes  (yyconst char * bytes, int  len )
        b->yy_is_our_buffer = 1;
 
        return b;
-}
+       }
+#endif
 
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
 #endif
+       {
+       if ( yy_start_stack_ptr >= yy_start_stack_depth )
+               {
+               yy_size_t new_size;
 
-static void yy_fatal_error (yyconst char* msg )
-{
-       (void) fprintf( stderr, "%s\n", msg );
-       exit( YY_EXIT_FAILURE );
-}
+               yy_start_stack_depth += YY_START_STACK_INCR;
+               new_size = yy_start_stack_depth * sizeof( int );
 
-/* Redefine yyless() so it works in section 3 code. */
+               if ( ! yy_start_stack )
+                       yy_start_stack = (int *) yy_flex_alloc( new_size );
 
-#undef yyless
-#define yyless(n) \
-       do \
-               { \
-               /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               yytext[yyleng] = (yy_hold_char); \
-               (yy_c_buf_p) = yytext + yyless_macro_arg; \
-               (yy_hold_char) = *(yy_c_buf_p); \
-               *(yy_c_buf_p) = '\0'; \
-               yyleng = yyless_macro_arg; \
-               } \
-       while ( 0 )
+               else
+                       yy_start_stack = (int *) yy_flex_realloc(
+                                       (void *) yy_start_stack, new_size );
 
-/* Accessor  methods (get/set functions) to struct members. */
+               if ( ! yy_start_stack )
+                       YY_FATAL_ERROR(
+                       "out of memory expanding start-condition stack" );
+               }
 
-/** Get the current line number.
- * 
- */
-int yyget_lineno  (void)
-{
-        
-    return yylineno;
-}
+       yy_start_stack[yy_start_stack_ptr++] = YY_START;
 
-/** Get the input stream.
- * 
- */
-FILE *yyget_in  (void)
-{
-        return yyin;
-}
+       BEGIN(new_state);
+       }
+#endif
 
-/** Get the output stream.
- * 
- */
-FILE *yyget_out  (void)
-{
-        return yyout;
-}
 
-/** Get the length of the current token.
- * 
- */
-int yyget_leng  (void)
-{
-        return yyleng;
-}
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+       {
+       if ( --yy_start_stack_ptr < 0 )
+               YY_FATAL_ERROR( "start-condition stack underflow" );
 
-/** Get the current token.
- * 
- */
+       BEGIN(yy_start_stack[yy_start_stack_ptr]);
+       }
+#endif
 
-char *yyget_text  (void)
-{
-        return yytext;
-}
 
-/** Set the current line number.
- * @param line_number
- * 
- */
-void yyset_lineno (int  line_number )
-{
-    
-    yylineno = line_number;
-}
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+       {
+       return yy_start_stack[yy_start_stack_ptr - 1];
+       }
+#endif
 
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * 
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE *  in_str )
-{
-        yyin = in_str ;
-}
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
 
-void yyset_out (FILE *  out_str )
-{
-        yyout = out_str ;
-}
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( yyconst char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+       {
+       (void) fprintf( stderr, "%s\n", msg );
+       exit( YY_EXIT_FAILURE );
+       }
 
-int yyget_debug  (void)
-{
-        return yy_flex_debug;
-}
 
-void yyset_debug (int  bdebug )
-{
-        yy_flex_debug = bdebug ;
-}
 
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy  (void)
-{
-    
-    /* Pop the buffer stack, destroying each element. */
-       while(YY_CURRENT_BUFFER){
-               yy_delete_buffer(YY_CURRENT_BUFFER  );
-               YY_CURRENT_BUFFER_LVALUE = NULL;
-               yypop_buffer_state();
-       }
+/* Redefine yyless() so it works in section 3 code. */
 
-       /* Destroy the stack itself. */
-       yyfree((yy_buffer_stack) );
-       (yy_buffer_stack) = NULL;
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+               yytext[yyleng] = yy_hold_char; \
+               yy_c_buf_p = yytext + n; \
+               yy_hold_char = *yy_c_buf_p; \
+               *yy_c_buf_p = '\0'; \
+               yyleng = n; \
+               } \
+       while ( 0 )
 
-    return 0;
-}
 
-/*
- * Internal utility routines.
- */
+/* Internal utility routines. */
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
-{
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+yyconst char *s2;
+int n;
+#endif
+       {
        register int i;
-       for ( i = 0; i < n; ++i )
+       for ( i = 0; i < n; ++i )
                s1[i] = s2[i];
-}
+       }
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s )
-{
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen( yyconst char *s )
+#else
+static int yy_flex_strlen( s )
+yyconst char *s;
+#endif
+       {
        register int n;
-       for ( n = 0; s[n]; ++n )
+       for ( n = 0; s[n]; ++n )
                ;
 
        return n;
-}
+       }
 #endif
 
-void *yyalloc (yy_size_t  size )
-{
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( yy_size_t size )
+#else
+static void *yy_flex_alloc( size )
+yy_size_t size;
+#endif
+       {
        return (void *) malloc( size );
-}
+       }
 
-void *yyrealloc  (void * ptr, yy_size_t  size )
-{
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, yy_size_t size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+yy_size_t size;
+#endif
+       {
        /* The cast to (char *) in the following accommodates both
         * implementations that use char* generic pointers, and those
         * that use void* generic pointers.  It works with the latter
@@ -1782,31 +1621,28 @@ void *yyrealloc  (void * ptr, yy_size_t  size )
         * as though doing an assignment.
         */
        return (void *) realloc( (char *) ptr, size );
-}
-
-void yyfree (void * ptr )
-{
-       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
+       }
 
-#undef YY_NEW_FILE
-#undef YY_FLUSH_BUFFER
-#undef yy_set_bol
-#undef yy_new_buffer
-#undef yy_set_interactive
-#undef yytext_ptr
-#undef YY_DO_BEFORE_ACTION
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+       {
+       free( ptr );
+       }
 
-#ifdef YY_DECL_IS_OURS
-#undef YY_DECL_IS_OURS
-#undef YY_DECL
+#if YY_MAIN
+int main()
+       {
+       yylex();
+       return 0;
+       }
 #endif
 #line 75 "lex.l"
 
 
-
 #ifndef yywrap /* XXX */
 int
 yywrap () 
@@ -1859,4 +1695,3 @@ error_message (const char *format, ...)
      va_end (args);
      numerror++;
 }
-
index c732867d09a9ca924f63f5b8c78a0e001dbb08b3..42455097c97857734e8bd3af79c22ac414273ff5 100644 (file)
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 1.875d.  */
+/* A Bison parser, made by GNU Bison 1.875c.  */
 
 /* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -209,7 +209,7 @@ typedef union YYSTYPE {
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  short int yyss;
+  short yyss;
   YYSTYPE yyvs;
   };
 
@@ -219,7 +219,7 @@ union yyalloc
 /* The size of an array large to enough to hold all stacks, each with
    N elements.  */
 # define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (short int) + sizeof (YYSTYPE))                    \
+     ((N) * (sizeof (short) + sizeof (YYSTYPE))                                \
       + YYSTACK_GAP_MAXIMUM)
 
 /* Copy COUNT objects from FROM to TO.  The source and destination do
@@ -261,7 +261,7 @@ union yyalloc
 #if defined (__STDC__) || defined (__cplusplus)
    typedef signed char yysigned_char;
 #else
-   typedef short int yysigned_char;
+   typedef short yysigned_char;
 #endif
 
 /* YYFINAL -- State number of the termination state. */
@@ -358,7 +358,7 @@ static const char *const yytname[] =
 # ifdef YYPRINT
 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
    token YYLEX-NUM.  */
-static const unsigned short int yytoknum[] =
+static const unsigned short yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,    44
@@ -550,12 +550,12 @@ do {                                                              \
 
 #if defined (__STDC__) || defined (__cplusplus)
 static void
-yy_stack_print (short int *bottom, short int *top)
+yy_stack_print (short *bottom, short *top)
 #else
 static void
 yy_stack_print (bottom, top)
-    short int *bottom;
-    short int *top;
+    short *bottom;
+    short *top;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
@@ -822,9 +822,9 @@ yyparse ()
      to reallocate them elsewhere.  */
 
   /* The state stack.  */
-  short int yyssa[YYINITDEPTH];
-  short int *yyss = yyssa;
-  register short int *yyssp;
+  short        yyssa[YYINITDEPTH];
+  short *yyss = yyssa;
+  register short *yyssp;
 
   /* The semantic value stack.  */
   YYSTYPE yyvsa[YYINITDEPTH];
@@ -861,7 +861,6 @@ yyparse ()
   yyssp = yyss;
   yyvsp = yyvs;
 
-
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -887,7 +886,7 @@ yyparse ()
           these so that the &'s don't force the real ones into
           memory.  */
        YYSTYPE *yyvs1 = yyvs;
-       short int *yyss1 = yyss;
+       short *yyss1 = yyss;
 
 
        /* Each stack pointer address is followed by the size of the
@@ -915,7 +914,7 @@ yyparse ()
        yystacksize = YYMAXDEPTH;
 
       {
-       short int *yyss1 = yyss;
+       short *yyss1 = yyss;
        union yyalloc *yyptr =
          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
        if (! yyptr)
@@ -1134,8 +1133,8 @@ yyreduce:
 
     }
 
-/* Line 1010 of yacc.c.  */
-#line 1139 "$base.c"
+/* Line 1000 of yacc.c.  */
+#line 1138 "$base.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
index a9ee7c7c9bd1520c1626882daddb1e843ba4c3bf..309c272499cf1782aa04c4062348b8b7e5a91973 100644 (file)
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 1.875d.  */
+/* A Bison parser, made by GNU Bison 1.875c.  */
 
 /* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -57,7 +57,7 @@ typedef union YYSTYPE {
   char *string;
   int number;
 } YYSTYPE;
-/* Line 1285 of yacc.c.  */
+/* Line 1275 of yacc.c.  */
 #line 62 "parse.h"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
index 66d2bf4f4e297179dee7579938def81a57a64047..b615bbd30efca0add8de80c796559a6644239836 100644 (file)
@@ -45,7 +45,7 @@
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
-RCSID("$Id: des.c,v 1.14 2005/06/18 22:47:17 lha Exp $");
+RCSID("$Id: des.c,v 1.15 2005/07/20 10:49:22 lha Exp $");
 #endif
 
 #include <stdio.h>
@@ -267,9 +267,11 @@ DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
  */
 
 void
-DES_cbc_encrypt(unsigned char *input, unsigned char *output, long length,
+DES_cbc_encrypt(const void *in, void *out, long length,
                DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
 {
+    const unsigned char *input = in;
+    unsigned char *output = out;
     uint32_t u[2];
     uint32_t uiv[2];
 
@@ -328,9 +330,11 @@ DES_cbc_encrypt(unsigned char *input, unsigned char *output, long length,
  */
 
 void
-DES_pcbc_encrypt(unsigned char *input, unsigned char *output, long length,
+DES_pcbc_encrypt(const void *in, void *out, long length,
                 DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
 {
+    const unsigned char *input = in;
+    unsigned char *output = out;
     uint32_t u[2];
     uint32_t uiv[2];
 
@@ -430,11 +434,13 @@ DES_ecb3_encrypt(DES_cblock *input,
  */
 
 void
-DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
+DES_ede3_cbc_encrypt(const void *in, void *out,
                     long length, DES_key_schedule *ks1, 
                     DES_key_schedule *ks2, DES_key_schedule *ks3,
                     DES_cblock *iv, int forward_encrypt)
 {
+    const unsigned char *input = in;
+    unsigned char *output = out;
     uint32_t u[2];
     uint32_t uiv[2];
 
@@ -494,10 +500,12 @@ DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
  */
 
 void
-DES_cfb64_encrypt(unsigned char *input, unsigned char *output, 
+DES_cfb64_encrypt(const void *in, void *out, 
                  long length, DES_key_schedule *ks, DES_cblock *iv,
                  int *num, int forward_encrypt)
 {
+    const unsigned char *input = in;
+    unsigned char *output = out;
     unsigned char tmp[DES_CBLOCK_LEN];
     uint32_t uiv[2];
 
@@ -555,9 +563,10 @@ DES_cfb64_encrypt(unsigned char *input, unsigned char *output,
  */
 
 uint32_t
-DES_cbc_cksum(const unsigned char *input, DES_cblock *output,
+DES_cbc_cksum(const void *in, DES_cblock *output,
              long length, DES_key_schedule *ks, DES_cblock *iv)
 {
+    const unsigned char *input = in;
     uint32_t uiv[2];
     uint32_t u[2] = { 0, 0 };
 
index 378c77572cef011a05805216d5b7f323fa5389ea..887c2e14d446e4753a13ec1ed1b417a67b0582c8 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: des.h,v 1.23 2005/04/30 14:09:50 lha Exp $ */
+/* $Id: des.h,v 1.24 2005/07/20 10:49:23 lha Exp $ */
 
 #ifndef _DESperate_H
 #define _DESperate_H 1
@@ -59,10 +59,10 @@ int DES_read_password(DES_cblock *, char *, int);
 
 int    UI_UTIL_read_pw_string(char *, int, const char *, int); /* XXX */
 
-void   DES_rand_data(unsigned char *, int);
+void   DES_rand_data(void *, int);
 void   DES_set_random_generator_seed(DES_cblock *);
 void   DES_generate_random_block(DES_cblock *);
-void   DES_set_sequence_number(unsigned char *);
+void   DES_set_sequence_number(void *);
 void   DES_init_random_number_generator(DES_cblock *);
 void   DES_random_key(DES_cblock *);
 
@@ -71,18 +71,18 @@ void        DES_encrypt(uint32_t [2], DES_key_schedule *, int);
 void   DES_ecb_encrypt(DES_cblock *, DES_cblock *, DES_key_schedule *, int);
 void   DES_ecb3_encrypt(DES_cblock *,DES_cblock *, DES_key_schedule *,
                         DES_key_schedule *, DES_key_schedule *, int);
-void   DES_pcbc_encrypt(unsigned char *, unsigned char *, long,
+void   DES_pcbc_encrypt(const void *, void *, long,
                         DES_key_schedule *, DES_cblock *, int);
-void   DES_cbc_encrypt(unsigned char *, unsigned char *, long,
+void   DES_cbc_encrypt(const void *, void *, long,
                        DES_key_schedule *, DES_cblock *, int);
-void   DES_ede3_cbc_encrypt(const unsigned char *, unsigned char *, long, 
+void   DES_ede3_cbc_encrypt(const void *, void *, long, 
                             DES_key_schedule *, DES_key_schedule *, 
                             DES_key_schedule *, DES_cblock *, int);
-void DES_cfb64_encrypt(unsigned char *, unsigned char *, long,
+void DES_cfb64_encrypt(const void *, void *, long,
                       DES_key_schedule *, DES_cblock *, int *, int);
 
 
-uint32_t DES_cbc_cksum(const unsigned char *, DES_cblock *,
+uint32_t DES_cbc_cksum(const void *, DES_cblock *,
                      long, DES_key_schedule *, DES_cblock *);
 
 
index 49d8838a10887e05d7d6b9e80286b9f0e78e0c56..63dddeb8ce164213b5d6d86e454e236ad426bd94 100644 (file)
@@ -34,7 +34,7 @@
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 
-RCSID("$Id: rnd_keys.c,v 1.68 2005/06/29 22:28:10 lha Exp $");
+RCSID("$Id: rnd_keys.c,v 1.69 2005/07/20 10:49:24 lha Exp $");
 #endif
 
 #ifdef KRB5
@@ -240,8 +240,9 @@ static RETSIGTYPE
  * It's not neccessary to be root to run it.
  */
 void
-DES_rand_data(unsigned char *data, int size)
+DES_rand_data(void *outdata, int size)
 {
+    unsigned char *data = outdata;
     struct itimerval tv, otv;
     RETSIGTYPE (*osa)(int);
     int i, j;
@@ -388,7 +389,7 @@ memcpy((char *)sequence_index, (ll), sizeof(sequence_index));
  * Set the sequnce number to this value (a long long).
  */
 void
-DES_set_sequence_number(unsigned char *ll)
+DES_set_sequence_number(void *ll)
 {
     set_sequence_number(ll);
 }
index 6672f3fc67855c1896db149829e7df2a1e9c2937..2ba2415112a5bf580f93727b5f818f7d75c3cd84 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -1051,28 +1051,27 @@ spnego_accept_sec_context
 }
 
 OM_uint32
-gss_accept_sec_context(
-       OM_uint32 * minor_status,
-       gss_ctx_id_t * context_handle,
-       const gss_cred_id_t acceptor_cred_handle,
-       const gss_buffer_t input_token,
-       const gss_channel_bindings_t input_chan_bindings,
-       gss_name_t * src_name,
-       gss_OID * actual_mech_type,
-       gss_buffer_t output_token,
-       OM_uint32 * ret_flags,
-       OM_uint32 * time_rec,
-       gss_cred_id_t * delegated_cred_handle)
+gss_accept_sec_context
+           (OM_uint32 * minor_status,
+            gss_ctx_id_t * context_handle,
+            const gss_cred_id_t acceptor_cred_handle,
+            const gss_buffer_t input_token_buffer,
+            const gss_channel_bindings_t input_chan_bindings,
+            gss_name_t * src_name,
+            gss_OID * mech_type,
+            gss_buffer_t output_token,
+            OM_uint32 * ret_flags,
+            OM_uint32 * time_rec,
+            gss_cred_id_t * delegated_cred_handle
+           )
 {
-       ssize_t mech_len;
-       const u_char *p;
-
-       GSSAPI_KRB5_INIT ();
+    ssize_t mech_len;
+    const u_char *p;
 
-       *minor_status = 0;
+    *minor_status = 0;
 
        if (src_name)                   *src_name               = GSS_C_NO_NAME;
-       if (actual_mech_type)           *actual_mech_type       = GSS_C_NO_OID;
+    if (mech_type)             *mech_type      = GSS_C_NO_OID;
 
        output_token->length = 0;
        output_token->value  = NULL;
@@ -1081,8 +1080,8 @@ gss_accept_sec_context(
        if (time_rec)                   *time_rec               = 0;
        if (delegated_cred_handle)      *delegated_cred_handle  = NULL;
 
-       mech_len = gssapi_krb5_get_mech(input_token->value,
-                                       input_token->length,
+       mech_len = gssapi_krb5_get_mech(input_token_buffer->value,
+                                       input_token_buffer->length,
                                        &p);
 
        /* This could be 'dce style' kerberos, where the OID is missing :-( */
@@ -1091,10 +1090,10 @@ gss_accept_sec_context(
                return gsskrb5_accept_sec_context(minor_status,
                                                  context_handle,
                                                  acceptor_cred_handle,
-                                                 input_token,
+                                                 input_token_buffer,
                                                  input_chan_bindings,
                                                  src_name,
-                                                 actual_mech_type,
+                                                 mech_type,
                                                  output_token,
                                                  ret_flags,
                                                  time_rec,
@@ -1104,10 +1103,10 @@ gss_accept_sec_context(
                return spnego_accept_sec_context(minor_status,
                                                 context_handle,
                                                 acceptor_cred_handle,
-                                                input_token,
+                                                input_token_buffer,
                                                 input_chan_bindings,
                                                 src_name,
-                                                actual_mech_type,
+                                                mech_type,
                                                 output_token,
                                                 ret_flags,
                                                 time_rec,
index c7e4aa50d689aa7115860f6d50c2bf8c09e14f1b..0376ca30bf0ec3cceae397fbac1b5e0813798c42 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2003 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "gssapi_locl.h"
 
-RCSID("$Id: init_sec_context.c,v 1.57 2005/05/30 20:58:29 lha Exp $");
+RCSID("$Id: init_sec_context.c,v 1.58 2005/07/13 07:00:15 lha Exp $");
 
 /*
  * copy the addresses from `input_chan_bindings' (if any) to
@@ -41,9 +41,8 @@ RCSID("$Id: init_sec_context.c,v 1.57 2005/05/30 20:58:29 lha Exp $");
  */
 
 static OM_uint32
-gsskrb5_set_addresses(
-       krb5_auth_context ac,
-       const gss_channel_bindings_t input_chan_bindings)              
+set_addresses (krb5_auth_context ac,
+              const gss_channel_bindings_t input_chan_bindings)               
 {
     /* Port numbers are expected to be in application_data.value, 
      * initator's port first */ 
@@ -136,8 +135,8 @@ _gsskrb5_create_ctx(
                return GSS_S_FAILURE;
        }
 
-       kret = gsskrb5_set_addresses((*context_handle)->auth_context,
-                                    input_chan_bindings);
+       kret = set_addresses((*context_handle)->auth_context,
+                            input_chan_bindings);
        if (kret) {
                *minor_status = kret;
 
@@ -278,13 +277,12 @@ gsskrb5_initiator_ready(
  */
 
 static void
-gsskrb5_do_delegation(
-       krb5_auth_context ac,
-       krb5_ccache ccache,
-       krb5_creds *cred,
-       const gss_name_t target_name,
-       krb5_data *fwd_data,
-       int *flags)
+do_delegation (krb5_auth_context ac,
+              krb5_ccache ccache,
+              krb5_creds *cred,
+              const gss_name_t target_name,
+              krb5_data *fwd_data,
+              int *flags)
 {
     krb5_creds creds;
     krb5_kdc_flags fwd_flags;
@@ -292,7 +290,7 @@ gsskrb5_do_delegation(
        
     memset (&creds, 0, sizeof(creds));
     krb5_data_zero (fwd_data);
-
+       
     kret = krb5_cc_get_principal(gssapi_krb5_context, ccache, &creds.client);
     if (kret) 
        goto out;
@@ -342,34 +340,35 @@ gsskrb5_do_delegation(
  */
 
 static OM_uint32
-gsskrb5_initiator_start(
-       OM_uint32 * minor_status,
-       const gss_cred_id_t initiator_cred_handle,
-       gss_ctx_id_t * context_handle,
-       const gss_name_t target_name,
-       const gss_OID mech_type,
-       OM_uint32 req_flags,
-       OM_uint32 time_req,
-       const gss_channel_bindings_t input_chan_bindings,
-       const gss_buffer_t input_token,
-       gss_buffer_t output_token,
-       OM_uint32 * ret_flags,
-       OM_uint32 * time_rec)
+gsskrb5_initiator_start
+(OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec
+    )
 {
-       OM_uint32 ret = GSS_S_FAILURE;
-       krb5_error_code kret;
-       krb5_flags ap_options;
-       krb5_creds *cred = NULL;
-       krb5_data outbuf;
-       krb5_ccache ccache = NULL;
-       u_int32_t flags;
-       krb5_data authenticator;
-       Checksum cksum;
-       krb5_enctype enctype;
-       krb5_data fwd_data;
-
-       krb5_data_zero(&outbuf);
-       krb5_data_zero(&fwd_data);
+    OM_uint32 ret = GSS_S_FAILURE;
+    krb5_error_code kret;
+    krb5_flags ap_options;
+    krb5_creds *cred = NULL;
+    krb5_data outbuf;
+    krb5_ccache ccache = NULL;
+    u_int32_t flags;
+    krb5_data authenticator;
+    Checksum cksum;
+    krb5_enctype enctype;
+    krb5_data fwd_data;
+
+    krb5_data_zero(&outbuf);
+    krb5_data_zero(&fwd_data);
 
        (*context_handle)->more_flags |= LOCAL;
 
@@ -425,7 +424,7 @@ gsskrb5_initiator_start(
                ap_options = 0;
 
                if (req_flags & GSS_C_DELEG_FLAG) {
-                       gsskrb5_do_delegation((*context_handle)->auth_context,
+                       do_delegation((*context_handle)->auth_context,
                                              ccache, cred, target_name, &fwd_data, &flags);
                }
 
@@ -681,20 +680,21 @@ gsskrb5_initiator_wait_for_mutual(
 }
 
 static OM_uint32
-gsskrb5_init_sec_context(
-       OM_uint32 * minor_status,
-       const gss_cred_id_t initiator_cred_handle,
-       gss_ctx_id_t * context_handle,
-       const gss_name_t target_name,
-       const gss_OID mech_type,
-       OM_uint32 req_flags,
-       OM_uint32 time_req,
-       const gss_channel_bindings_t input_chan_bindings,
-       const gss_buffer_t input_token,
-       gss_OID * actual_mech_type,
-       gss_buffer_t output_token,
-       OM_uint32 * ret_flags,
-       OM_uint32 * time_rec)
+gsskrb5_init_sec_context
+           (OM_uint32 * minor_status,
+            const gss_cred_id_t initiator_cred_handle,
+            gss_ctx_id_t * context_handle,
+            const gss_name_t target_name,
+            const gss_OID mech_type,
+            OM_uint32 req_flags,
+            OM_uint32 time_req,
+            const gss_channel_bindings_t input_chan_bindings,
+            const gss_buffer_t input_token,
+            gss_OID * actual_mech_type,
+            gss_buffer_t output_token,
+            OM_uint32 * ret_flags,
+            OM_uint32 * time_rec
+          )
 {
        OM_uint32 ret;
 
@@ -1076,9 +1076,7 @@ spnego_initial
     ni.mechListMIC = NULL;
 
 
-#if 0
     {
-       int ret;
        NegotiationToken nt;
 
        nt.element = choice_NegotiationToken_negTokenInit;
@@ -1086,47 +1084,10 @@ spnego_initial
 
        ASN1_MALLOC_ENCODE(NegotiationToken, buf, buf_size,
                           &nt, &buf_len, ret);
-       if (buf_size != buf_len)
+       if (ret == 0 && buf_size != buf_len)
            abort();
     }
-#else
-    ni_len = length_NegTokenInit(&ni);
-    buf_size = 1 + length_len(ni_len) + ni_len;
 
-    buf = malloc(buf_size);
-    if (buf == NULL) {
-       free_NegTokenInit(&ni);
-       *minor_status = ENOMEM;
-       return GSS_S_FAILURE;
-    }
-
-    ret = encode_NegTokenInit(buf + buf_size - 1,
-                             ni_len,
-                             &ni, &buf_len);
-    if (ret == 0 && ni_len != buf_len)
-       abort();
-
-    if (ret == 0) {
-       size_t tmp;
-
-       ret = der_put_length_and_tag(buf + buf_size - buf_len - 1,
-                                    buf_size - buf_len,
-                                    buf_len,
-                                    ASN1_C_CONTEXT,
-                                    CONS,
-                                    0,
-                                    &tmp);
-       if (ret == 0 && tmp + buf_len != buf_size)
-           abort();
-    }
-    if (ret) {
-       *minor_status = ret;
-       free(buf);
-       free_NegTokenInit(&ni);
-       return GSS_S_FAILURE;
-    }
-
-#endif
     data.data   = buf;
     data.length = buf_size;
 
@@ -1197,65 +1158,68 @@ spnego_init_sec_context
  * gss_init_sec_context
  */
 
-OM_uint32 gss_init_sec_context(
-       OM_uint32 * minor_status,
-       const gss_cred_id_t initiator_cred_handle,
-       gss_ctx_id_t * context_handle,
-       const gss_name_t target_name,
-       const gss_OID mech_type,
-       OM_uint32 req_flags,
-       OM_uint32 time_req,
-       const gss_channel_bindings_t input_chan_bindings,
-       const gss_buffer_t input_token,
-       gss_OID * actual_mech_type,
-       gss_buffer_t output_token,
-       OM_uint32 * ret_flags,
-       OM_uint32 * time_rec)
+OM_uint32 gss_init_sec_context
+           (OM_uint32 * minor_status,
+            const gss_cred_id_t initiator_cred_handle,
+            gss_ctx_id_t * context_handle,
+            const gss_name_t target_name,
+            const gss_OID mech_type,
+            OM_uint32 req_flags,
+            OM_uint32 time_req,
+            const gss_channel_bindings_t input_chan_bindings,
+            const gss_buffer_t input_token,
+            gss_OID * actual_mech_type,
+            gss_buffer_t output_token,
+            OM_uint32 * ret_flags,
+            OM_uint32 * time_rec
+           )
 {
-       GSSAPI_KRB5_INIT ();
+    GSSAPI_KRB5_INIT ();
 
-       *minor_status = 0;
+    output_token->length = 0;
+    output_token->value  = NULL;
 
-       if (actual_mech_type)   *actual_mech_type       = GSS_C_NO_OID;
-
-       output_token->length = 0;
-       output_token->value  = NULL;
-
-       if (ret_flags)          *ret_flags              = 0;
-       if (time_rec)           *time_rec               = 0;
-
-       if (target_name == GSS_C_NO_NAME) return GSS_S_BAD_NAME;
-
-       if (mech_type == GSS_C_NO_OID ||
-           gss_oid_equal(mech_type, GSS_KRB5_MECHANISM)) {
-               return gsskrb5_init_sec_context(minor_status,
-                                               initiator_cred_handle,
-                                               context_handle,
-                                               target_name,
-                                               mech_type,
-                                               req_flags,
-                                               time_req,
-                                               input_chan_bindings,
-                                               input_token,
-                                               actual_mech_type,
-                                               output_token,
-                                               ret_flags,
-                                               time_rec);
-       } else if (gss_oid_equal(mech_type, GSS_SPNEGO_MECHANISM)) {
-               return spnego_init_sec_context (minor_status,
-                                               initiator_cred_handle,
-                                               context_handle,
-                                               target_name,
-                                               mech_type,
-                                               req_flags,
-                                               time_req,
-                                               input_chan_bindings,
-                                               input_token,
-                                               actual_mech_type,
-                                               output_token,
-                                               ret_flags,
-                                               time_rec);
-       }
+    if (ret_flags)
+       *ret_flags = 0;
+    if (time_rec)
+       *time_rec = 0;
 
+    if (target_name == GSS_C_NO_NAME) {
+       if (actual_mech_type)
+           *actual_mech_type = GSS_C_NO_OID;
+       *minor_status = 0;
+       return GSS_S_BAD_NAME;
+    }
+
+    if (mech_type == GSS_C_NO_OID || 
+       gss_oid_equal(mech_type,  GSS_KRB5_MECHANISM))
+       return gsskrb5_init_sec_context(minor_status,
+                                       initiator_cred_handle,
+                                       context_handle,
+                                       target_name,
+                                       mech_type,
+                                       req_flags,
+                                       time_req,
+                                       input_chan_bindings,
+                                       input_token,
+                                       actual_mech_type,
+                                       output_token,
+                                       ret_flags,
+                                       time_rec);
+    else if (gss_oid_equal(mech_type, GSS_SPNEGO_MECHANISM))
+       return spnego_init_sec_context (minor_status,
+                                       initiator_cred_handle,
+                                       context_handle,
+                                       target_name,
+                                       mech_type,
+                                       req_flags,
+                                       time_req,
+                                       input_chan_bindings,
+                                       input_token,
+                                       actual_mech_type,
+                                       output_token,
+                                       ret_flags,
+                                       time_rec);
+    else
        return GSS_S_BAD_MECH;
 }
index 653df8c45127734fb18aadacb46f1c7e40d5eb52..a2b96bb0472a2960162377e7e1354c636fc3becc 100644 (file)
@@ -5,10 +5,14 @@
 #include <stdarg.h>
 
 krb5_error_code
-_hdb_fetch(krb5_context context, HDB *db, unsigned flags,         
-          krb5_principal principal,
-          enum hdb_ent_type ent_type,
-          hdb_entry *entry);
+_hdb_fetch (
+       krb5_context /*context*/,
+       HDB */*db*/,
+       unsigned /*flags*/,
+       krb5_principal /*principal*/,
+       enum hdb_ent_type /*ent_type*/,
+       hdb_entry */*entry*/);
+
 krb5_error_code
 _hdb_remove (
        krb5_context /*context*/,
index 2b1ac3a5c422a5704358c443ed5baee27addb07d..c8fa556696d21cc5cd590c25f624a3a7797743f1 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #include "krb5_locl.h"
-RCSID("$Id: crypto.c,v 1.123 2005/06/29 22:20:33 lha Exp $");
+RCSID("$Id: crypto.c,v 1.128 2005/07/20 07:22:43 lha Exp $");
 
 #undef CRYPTO_DEBUG
 #ifdef CRYPTO_DEBUG
@@ -2124,7 +2124,8 @@ verify_checksum(krb5_context context,
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
     if(ct->checksumsize != cksum->checksum.length) {
-       krb5_clear_error_string (context);
+       krb5_set_error_string (context, "checksum length was %d, but should be %d for checksum type %s",
+                              cksum->checksum.length, ct->checksumsize, ct->name);
        return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */
     }
     keyed_checksum = (ct->flags & F_KEYED) != 0;
@@ -2145,8 +2146,11 @@ verify_checksum(krb5_context context,
 
     (*ct->checksum)(context, dkey, data, len, usage, &c);
 
-    if(c.checksum.length != cksum->checksum.length || 
-       memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) {
+    if(c.checksum.length != cksum->checksum.length) {
+       krb5_set_error_string (context, "(INTERNAL ERROR) our checksum length was %d, but should be %d for checksum type %s",
+                              c.checksum.length, ct->checksumsize, ct->name);
+       ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
+    } else if (memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) {
        krb5_clear_error_string (context);
        ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
     } else {
@@ -3246,7 +3250,7 @@ static krb5_error_code
 encrypt_internal_derived(krb5_context context,
                         krb5_crypto crypto,
                         unsigned usage,
-                        void *data,
+                        const void *data,
                         size_t len,
                         krb5_data *result,
                         void *ivec)
@@ -3315,7 +3319,7 @@ encrypt_internal_derived(krb5_context context,
 static krb5_error_code
 encrypt_internal(krb5_context context,
                 krb5_crypto crypto,
-                void *data,
+                const void *data,
                 size_t len,
                 krb5_data *result,
                 void *ivec)
@@ -3395,7 +3399,7 @@ static krb5_error_code
 encrypt_internal_special(krb5_context context,
                         krb5_crypto crypto,
                         int usage,
-                        void *data,
+                        const void *data,
                         size_t len,
                         krb5_data *result,
                         void *ivec)
@@ -3624,7 +3628,7 @@ krb5_error_code KRB5_LIB_FUNCTION
 krb5_encrypt_ivec(krb5_context context,
                  krb5_crypto crypto,
                  unsigned usage,
-                 void *data,
+                 const void *data,
                  size_t len,
                  krb5_data *result,
                  void *ivec)
@@ -3643,7 +3647,7 @@ krb5_error_code KRB5_LIB_FUNCTION
 krb5_encrypt(krb5_context context,
             krb5_crypto crypto,
             unsigned usage,
-            void *data,
+            const void *data,
             size_t len,
             krb5_data *result)
 {
@@ -4228,14 +4232,9 @@ wrapped_length (krb5_context context,
 {
     struct encryption_type *et = crypto->et;
     size_t padsize = et->padsize;
-    size_t checksumsize;
+    size_t checksumsize = CHECKSUMSIZE(et->checksum);
     size_t res;
 
-    if (et->keyed_checksum)
-       checksumsize = et->keyed_checksum->checksumsize;
-    else
-       checksumsize = et->checksum->checksumsize;
-
     res =  et->confoundersize + checksumsize + data_len;
     res =  (res + padsize - 1) / padsize * padsize;
     return res;
@@ -4306,6 +4305,65 @@ krb5_random_to_key(krb5_context context,
     return 0;
 }
 
+krb5_error_code
+_krb5_pk_octetstring2key(krb5_context context,
+                        krb5_enctype type,
+                        const void *dhdata,
+                        size_t dhsize,
+                        const heim_octet_string *c_n,
+                        const heim_octet_string *k_n,
+                        krb5_keyblock *key)
+{
+    struct encryption_type *et = _find_enctype(type);
+    krb5_error_code ret;
+    size_t keylen, offset;
+    void *keydata;
+    unsigned char counter;
+    unsigned char shaoutput[20];
+
+    if(et == NULL) {
+       krb5_set_error_string(context, "encryption type %d not supported",
+                             type);
+       return KRB5_PROG_ETYPE_NOSUPP;
+    }
+    keylen = (et->keytype->bits + 7) / 8;
+
+    keydata = malloc(keylen);
+    if (keydata == NULL) {
+       krb5_set_error_string(context, "malloc: out of memory");
+       return ENOMEM;
+    }
+
+    counter = 0;
+    offset = 0;
+    do {
+       SHA_CTX m;
+       
+       SHA1_Init(&m);
+       SHA1_Update(&m, &counter, 1);
+       SHA1_Update(&m, dhdata, dhsize);
+       if (c_n)
+           SHA1_Update(&m, c_n->data, c_n->length);
+       if (k_n)
+           SHA1_Update(&m, k_n->data, k_n->length);
+       SHA1_Final(shaoutput, &m);
+
+       memcpy((unsigned char *)keydata + offset,
+              shaoutput,
+              min(keylen - offset, sizeof(shaoutput)));
+
+       offset += sizeof(shaoutput);
+       counter++;
+    } while(offset < keylen);
+    memset(shaoutput, 0, sizeof(shaoutput));
+
+    ret = krb5_random_to_key(context, type, keydata, keylen, key);
+    memset(keydata, 0, sizeof(keylen));
+    free(keydata);
+    return ret;
+}
+
+
 #ifdef CRYPTO_DEBUG
 
 static krb5_error_code
index 63fb55608cfc76a7dddd16fe0ceb32bca4c3a5af..7043b8ae51ec499e2844d2c78e1178f0c701566c 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: get_cred.c,v 1.107 2005/06/16 22:57:14 lha Exp $");
+RCSID("$Id: get_cred.c,v 1.108 2005/07/13 07:38:02 lha Exp $");
 
 /*
  * Take the `body' and encode it into `padata' using the credentials
@@ -837,10 +837,6 @@ krb5_get_credentials_with_flags(krb5_context context,
     if (in_creds->session.keytype)
        options |= KRB5_TC_MATCH_KEYTYPE;
 
-    ret = krb5_cc_retrieve_cred(context,
-                               ccache,
-                               options,
-                               in_creds, res_creds);
     /* 
      * If we got a credential, check if credential is expired before
      * returning it.
index a4056641228e894eb7626944506f1e2c0e53070e..23f6685049dccaa6db4d0b031b0dbc0e1ee2b3ad 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab.c,v 1.60 2005/05/19 14:04:45 lha Exp $");
+RCSID("$Id: keytab.c,v 1.62 2005/07/06 01:14:42 lha Exp $");
 
 /*
  * Register a new keytab in `ops'
@@ -240,8 +240,8 @@ krb5_kt_get_name(krb5_context context,
 }
 
 /*
- * Finish using the keytab in `id'.  All resources will be released.
- * Return 0 or an error.
+ * Finish using the keytab in `id'.  All resources will be released,
+ * even on errors.  Return 0 or an error.
  */
 
 krb5_error_code KRB5_LIB_FUNCTION
@@ -251,8 +251,8 @@ krb5_kt_close(krb5_context context,
     krb5_error_code ret;
 
     ret = (*id->close)(context, id);
-    if(ret == 0)
-       free(id);
+    memset(id, 0, sizeof(*id));
+    free(id);
     return ret;
 }
 
@@ -302,8 +302,10 @@ krb5_kt_get_entry(krb5_context context,
        return (*id->get)(context, id, principal, kvno, enctype, entry);
 
     ret = krb5_kt_start_seq_get (context, id, &cursor);
-    if (ret)
+    if (ret) {
+       krb5_clear_error_string(context);
        return KRB5_KT_NOTFOUND; /* XXX i.e. file not found */
+    }
 
     entry->vno = 0;
     while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) {
index dca09ff6f3e7faddff9d1663ee6b0cc8c0534003..6ff2680ed12e4af602ed11511d87f203f72470ae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: keytab_file.c,v 1.18 2005/05/31 21:50:43 lha Exp $");
+RCSID("$Id: keytab_file.c,v 1.20 2005/07/13 06:08:07 lha Exp $");
 
 #define KRB5_KT_VNO_1 1
 #define KRB5_KT_VNO_2 2
@@ -332,6 +332,12 @@ fkt_start_seq_get_int(krb5_context context,
        return ret;
     }
     c->sp = krb5_storage_from_fd(c->fd);
+    if (c->sp == NULL) {
+       _krb5_xunlock(context, c->fd);
+       close(c->fd);
+       krb5_set_error_string (context, "malloc: out of memory");
+       return ENOMEM;
+    }
     krb5_storage_set_eof_code(c->sp, KRB5_KT_END);
     ret = krb5_ret_int8(c->sp, &pvno);
     if(ret) {
index e59cab8ca789ecbc4c71ae022883ce48d9aab422..b877de8cf25966651337a8afeb571bf2f9daa50e 100644 (file)
@@ -329,6 +329,14 @@ _krb5_put_int (
        unsigned long /*value*/,
        size_t /*size*/);
 
+krb5_error_code KRB5_LIB_FUNCTION
+_krb5_rd_rep_type (
+       krb5_context /*context*/,
+       krb5_auth_context /*auth_context*/,
+       const krb5_data */*inbuf*/,
+       krb5_ap_rep_enc_part **/*repl*/,
+       krb5_boolean /*dce_style_response*/);
+
 int
 _krb5_send_and_recv_tcp (
        int /*fd*/,
@@ -348,11 +356,4 @@ _krb5_xunlock (
        krb5_context /*context*/,
        int /*fd*/);
 
-krb5_error_code KRB5_LIB_FUNCTION
-_krb5_rd_rep_type(krb5_context context,
-                krb5_auth_context auth_context,
-                const krb5_data *inbuf,
-                krb5_ap_rep_enc_part **repl,
-                 krb5_boolean dce_style_response);
-
 #endif /* __krb5_private_h__ */
index cee8a02419acd70dbc985af02a3a353219553ab9..f306bf949f05fff4aa709ed7522750069956f4f9 100644 (file)
@@ -1305,7 +1305,7 @@ krb5_encrypt (
        krb5_context /*context*/,
        krb5_crypto /*crypto*/,
        unsigned /*usage*/,
-       void */*data*/,
+       const void */*data*/,
        size_t /*len*/,
        krb5_data */*result*/);
 
@@ -1324,7 +1324,7 @@ krb5_encrypt_ivec (
        krb5_context /*context*/,
        krb5_crypto /*crypto*/,
        unsigned /*usage*/,
-       void */*data*/,
+       const void */*data*/,
        size_t /*len*/,
        krb5_data */*result*/,
        void */*ivec*/);
@@ -2424,7 +2424,7 @@ krb5_principal_get_comp_string (
 const char* KRB5_LIB_FUNCTION
 krb5_principal_get_realm (
        krb5_context /*context*/,
-       krb5_const_principal /*principal*/);
+       krb5_principal /*principal*/);
 
 int KRB5_LIB_FUNCTION
 krb5_principal_get_type (
index 890a500caa694044b49243f2bbc147660f95caf1..5789bff2050980cd2a092003ab92758bead32e2e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden). 
  * All rights reserved. 
  *
@@ -31,7 +31,7 @@
  * SUCH DAMAGE. 
  */
 
-/* $Id: krb5.h,v 1.236 2005/06/11 00:05:24 lha Exp $ */
+/* $Id: krb5.h,v 1.237 2005/07/09 14:47:21 lha Exp $ */
 
 #ifndef __KRB5_H__
 #define __KRB5_H__
@@ -567,8 +567,8 @@ typedef struct krb5_auth_context_data {
   
     krb5_rcache rcache;
 
-    krb5_keytype keytype;      /* Â¿requested key type ? */
-    krb5_cksumtype cksumtype;  /* Â¡requested checksum type! */
+    krb5_keytype keytype;      /* Ã‚¿requested key type ? */
+    krb5_cksumtype cksumtype;  /* Ã‚¡requested checksum type! */
   
 }krb5_auth_context_data, *krb5_auth_context;
 
@@ -617,28 +617,28 @@ typedef struct _krb5_prompt {
     krb5_prompt_type type;
 } krb5_prompt;
 
-typedef int (*krb5_prompter_fct)(krb5_context context,
-                                void *data,
-                                const char *name,
-                                const char *banner,
-                                int num_prompts,
-                                krb5_prompt prompts[]);
-typedef krb5_error_code (*krb5_key_proc)(krb5_context context,
-                                        krb5_enctype type,
-                                        krb5_salt salt,
-                                        krb5_const_pointer keyseed,
-                                        krb5_keyblock **key);
-typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context context,
-                                            krb5_keyblock *key,
-                                            krb5_key_usage usage,
-                                            krb5_const_pointer decrypt_arg,
-                                            krb5_kdc_rep *dec_rep);
-typedef krb5_error_code (*krb5_s2k_proc)(krb5_context context,
-                                        krb5_enctype type,
-                                        krb5_const_pointer keyseed,
-                                        krb5_salt salt,
-                                        krb5_data *s2kparms,
-                                        krb5_keyblock **key);
+typedef int (*krb5_prompter_fct)(krb5_context /*context*/,
+                                void * /*data*/,
+                                const char * /*name*/,
+                                const char * /*banner*/,
+                                int /*num_prompts*/,
+                                krb5_prompt /*prompts*/[]);
+typedef krb5_error_code (*krb5_key_proc)(krb5_context /*context*/,
+                                        krb5_enctype /*type*/,
+                                        krb5_salt /*salt*/,
+                                        krb5_const_pointer /*keyseed*/,
+                                        krb5_keyblock ** /*key*/);
+typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context /*context*/,
+                                            krb5_keyblock * /*key*/,
+                                            krb5_key_usage /*usage*/,
+                                            krb5_const_pointer /*decrypt_arg*/,
+                                            krb5_kdc_rep * /*dec_rep*/);
+typedef krb5_error_code (*krb5_s2k_proc)(krb5_context /*context*/,
+                                        krb5_enctype /*type*/,
+                                        krb5_const_pointer /*keyseed*/,
+                                        krb5_salt /*salt*/,
+                                        krb5_data * /*s2kparms*/,
+                                        krb5_keyblock ** /*key*/);
 
 struct _krb5_get_init_creds_opt_private;
 
index 84db4fe544d9c5f780b226fd8b34fe3356a076d3..35a751c2915b3ac440c2ac4fc91296206a518d1c 100755 (executable)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: pkinit.c,v 1.55 2005/05/19 18:49:05 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.58 2005/07/23 10:42:01 lha Exp $");
 
 #ifdef PKINIT
 
@@ -407,34 +407,25 @@ _krb5_pk_create_sign(krb5_context context,
        goto out;
     }
 
-    sd.certificates->data = NULL;
-    sd.certificates->length = 0;
+    i = sk_X509_num(id->cert);
+    sd.certificates->val = malloc(sizeof(sd.certificates->val[0]) * i);
+    if (sd.certificates->val == NULL) {
+       krb5_clear_error_string(context);
+       ret = ENOMEM;
+       goto out;
+    }
+    sd.certificates->len = i;
 
     for (i = 0; i < sk_X509_num(id->cert); i++) {
-       void *data;
-
        OPENSSL_ASN1_MALLOC_ENCODE(X509, 
-                                  buf.data,
-                                  buf.length,
+                                  sd.certificates->val[i].data,
+                                  sd.certificates->val[i].length,
                                   sk_X509_value(id->cert, i),
                                   ret);
        if (ret) {
            krb5_clear_error_string(context);
            goto out;
        }
-       data = realloc(sd.certificates->data, 
-                      sd.certificates->length + buf.length);
-       if (data == NULL) {
-           free(buf.data);
-           krb5_clear_error_string(context);
-           ret = ENOMEM;
-           goto out;
-       }
-       memcpy(((char *)data) + sd.certificates->length,
-              buf.data, buf.length);
-       sd.certificates->length += buf.length;
-       sd.certificates->data = data;
-       free(buf.data);
     }
 
     ASN1_MALLOC_ENCODE(SignedData, sd_data->data, sd_data->length, 
@@ -563,7 +554,7 @@ build_auth_pack(krb5_context context,
     if (ret == 0 && dh) {
        DomainParameters dp;
        heim_integer dh_pub_key;
-       krb5_data buf;
+       krb5_data dhbuf;
        size_t size;
 
        ALLOC(a->clientPublicValue, 1);
@@ -615,25 +606,25 @@ build_auth_pack(krb5_context context,
        if (ret)
            return ret;
 
-       buf.length = length_heim_integer(&dh_pub_key);
-       buf.data = malloc(buf.length);
-       if (buf.data == NULL) {
+       dhbuf.length = length_heim_integer(&dh_pub_key);
+       dhbuf.data = malloc(dhbuf.length);
+       if (dhbuf.data == NULL) {
            free_heim_integer(&dh_pub_key);
            krb5_set_error_string(context, "malloc: out of memory");
            return ret;
        }
-       ret = der_put_heim_integer((char *)buf.data + buf.length - 1,
-                                  buf.length, &dh_pub_key, &size);
+       ret = der_put_heim_integer((char *)dhbuf.data + dhbuf.length - 1,
+                                  dhbuf.length, &dh_pub_key, &size);
        free_heim_integer(&dh_pub_key);
        if (ret) {
-           free(buf.data);
+           free(dhbuf.data);
            return ret;
        }
-       if (size != buf.length)
+       if (size != dhbuf.length)
            krb5_abortx(context, "asn1 internal error");
 
-       a->clientPublicValue->subjectPublicKey.length = buf.length * 8;
-       a->clientPublicValue->subjectPublicKey.data = buf.data;
+       a->clientPublicValue->subjectPublicKey.length = dhbuf.length * 8;
+       a->clientPublicValue->subjectPublicKey.data = dhbuf.data;
     }
 
     return ret;
@@ -894,7 +885,7 @@ _krb5_pk_mk_padata(krb5_context context,
 
     if (provisioning_server) {
        /* PacketCable requires the PROV-SRV-LOCATION authenticator */
-       const PROV_SRV_LOCATION prov_server = (char *)provisioning_server;
+       const PROV_SRV_LOCATION prov_server = rk_UNCONST(provisioning_server);
 
        ASN1_MALLOC_ENCODE(PROV_SRV_LOCATION, buf.data, buf.length,
                           &prov_server, &size, ret);
@@ -1104,7 +1095,7 @@ pk_verify_chain_standard(krb5_context context,
 }
 
 static int
-cert_to_X509(krb5_context context, CertificateSetReal *set,
+cert_to_X509(krb5_context context, CertificateSet *set,
             STACK_OF(X509_CRL) **certs)
 {
     krb5_error_code ret;
@@ -1112,6 +1103,9 @@ cert_to_X509(krb5_context context, CertificateSetReal *set,
 
     *certs = sk_X509_new_null();
 
+    if (set == NULL)
+       return 0;
+
     ret = 0;
     for (i = 0; i < set->len; i++) {
        unsigned char *p;
@@ -1134,45 +1128,6 @@ cert_to_X509(krb5_context context, CertificateSetReal *set,
     return ret;
 }
 
-static krb5_error_code
-any_to_CertificateSet(krb5_context context, heim_any *cert, 
-                     CertificateSetReal *set)
-{
-    size_t size, len, length;
-    heim_any *val;
-    int ret;
-    char *p;
-    
-    set->len = 0;
-    set->val = NULL;
-
-    len = 0;
-    p = cert->data;
-    length = cert->length;
-    while (len < cert->length) {
-       val = realloc(set->val, (set->len + 1) * sizeof(set->val[0]));
-       if (val == NULL) {
-           ret = ENOMEM;
-           goto out;
-       }
-       set->val = val;
-       ret = decode_heim_any(p, length, &set->val[set->len], &size);
-       if (ret)
-           goto out;
-       set->len++;
-
-       p += size;
-       len += size;
-       length -= size;
-    }
-    return 0;
- out:
-    krb5_clear_error_string(context);
-    free_CertificateSetReal(set);
-    set->val = NULL;
-    return ret;
-}
-
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_pk_verify_sign(krb5_context context,
                     const char *data,
@@ -1187,7 +1142,6 @@ _krb5_pk_verify_sign(krb5_context context,
     const EVP_MD *evp_type;
     EVP_PKEY *public_key;
     krb5_error_code ret;
-    CertificateSetReal set;
     EVP_MD_CTX md;
     X509 *cert;
     SignedData sd;
@@ -1227,15 +1181,14 @@ _krb5_pk_verify_sign(krb5_context context,
 
     signer_info = &sd.signerInfos.val[0];
   
-    ret = any_to_CertificateSet(context, sd.certificates, &set);
-    if (ret) {
-       krb5_set_error_string(context,
-                             "PKINIT: failed to decode CertificateSet");
-       goto out;
-    }
+    {
+       CertificateSet set;
+       set.val = sd.certificates->val;
+       set.len = sd.certificates->len;
 
-    ret = cert_to_X509(context, &set, &certificates);
-    free_CertificateSetReal(&set);
+       ret = cert_to_X509(context, &set, &certificates);
+       free_CertificateSet(&set);
+    }
     if (ret) {
        krb5_set_error_string(context,
                              "PKINIT: failed to decode Certificates");
@@ -1530,7 +1483,6 @@ pk_rd_pa_reply_enckey(krb5_context context,
     /* win2k uses ContentInfo */
     if (win2k_compat) {
        ContentInfo ci;
-       size_t size;
 
        ret = decode_ContentInfo(p, length, &ci, &size);
        if (ret) {
@@ -1604,6 +1556,8 @@ pk_rd_pa_reply_dh(krb5_context context,
                   ContentInfo *rep,
                  krb5_pk_init_ctx ctx,
                  krb5_enctype etype,
+                 const DHNonce *c_n,
+                 const DHNonce *k_n,
                   unsigned nonce,
                   PA_DATA *pa,
                   krb5_keyblock **key)
@@ -1666,6 +1620,30 @@ pk_rd_pa_reply_dh(krb5_context context,
        goto out;
     }
 
+    if (kdc_dh_info.dhKeyExpiration) {
+       if (k_n == NULL) {
+           krb5_set_error_string(context, "pkinit; got key expiration "
+                                 "without server nonce");
+           ret = KRB5KRB_ERR_GENERIC;
+           goto out;
+       }
+       if (c_n == NULL) {
+           krb5_set_error_string(context, "pkinit; got DH reuse but no "
+                                 "client nonce");
+           ret = KRB5KRB_ERR_GENERIC;
+           goto out;
+       }
+    } else {
+       if (k_n) {
+           krb5_set_error_string(context, "pkinit; got server nonce "
+                                 "without key expiration");
+           ret = KRB5KRB_ERR_GENERIC;
+           goto out;
+       }
+       c_n = NULL;
+    }
+
+
     p = kdc_dh_info.subjectPublicKey.data;
     size = (kdc_dh_info.subjectPublicKey.length + 7) / 8;
     dh_pub_key = d2i_ASN1_INTEGER(NULL, &p, size);
@@ -1684,14 +1662,21 @@ pk_rd_pa_reply_dh(krb5_context context,
        goto out;
     }
 
-    dh_gen_key = malloc(DH_size(ctx->dh));
+    dh_gen_keylen = DH_size(ctx->dh);
+    size = BN_num_bytes(ctx->dh->p);
+    if (size < dh_gen_keylen)
+       size = dh_gen_keylen;
+
+    dh_gen_key = malloc(size);
     if (dh_gen_key == NULL) {
        krb5_set_error_string(context, "malloc: out of memory");
        ret = ENOMEM;
        goto out;
     }
+    memset(dh_gen_key, 0, size - dh_gen_keylen);
 
-    dh_gen_keylen = DH_compute_key(dh_gen_key, kdc_dh_pubkey, ctx->dh);
+    dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen),
+                                  kdc_dh_pubkey, ctx->dh);
     if (dh_gen_keylen == -1) {
        krb5_set_error_string(context, 
                              "PKINIT: Can't compute Diffie-Hellman key (%s)",
@@ -1707,7 +1692,11 @@ pk_rd_pa_reply_dh(krb5_context context,
        goto out;
     }
 
-    ret = krb5_random_to_key(context, etype, dh_gen_key, dh_gen_keylen, *key);
+    ret = _krb5_pk_octetstring2key(context,
+                                  etype,
+                                  dh_gen_key, dh_gen_keylen,
+                                  c_n, k_n,
+                                  *key);
     if (ret) {
        krb5_set_error_string(context,
                              "PKINIT: can't create key from DH key");
@@ -1761,6 +1750,25 @@ _krb5_pk_rd_pa_reply(krb5_context context,
            return ret;
 
        switch (rep.element) {
+       case choice_PA_PK_AS_REP_dhInfo:
+           ret = decode_ContentInfo(rep.u.dhInfo.dhSignedData.data,
+                                    rep.u.dhInfo.dhSignedData.length,
+                                    &ci,
+                                    &size);
+           if (ret) {
+               krb5_set_error_string(context,
+                                     "PKINIT: -25 decoding failed DH "
+                                     "ContentInfo: %d", ret);
+
+               free_PA_PK_AS_REP(&rep);
+               break;
+           }
+           ret = pk_rd_pa_reply_dh(context, &ci, ctx,
+                                   etype, NULL, NULL, nonce, pa, key);
+           free_ContentInfo(&ci);
+           free_PA_PK_AS_REP(&rep);
+
+           break;
        case choice_PA_PK_AS_REP_encKeyPack:
            ret = decode_ContentInfo(rep.u.encKeyPack.data,
                                     rep.u.encKeyPack.length,
@@ -1799,7 +1807,8 @@ _krb5_pk_rd_pa_reply(krb5_context context,
            switch(rep19.element) {
            case choice_PA_PK_AS_REP_19_dhSignedData:
                ret = pk_rd_pa_reply_dh(context, &rep19.u.dhSignedData, ctx,
-                                       etype, nonce, pa, key);
+                                       etype, NULL, NULL, 
+                                       nonce, pa, key);
                break;
            case choice_PA_PK_AS_REP_19_encKeyPack:
                ret = pk_rd_pa_reply_enckey(context, 0,
@@ -2314,8 +2323,8 @@ _krb5_pk_load_openssl_id(krb5_context context,
     FILE *f;
     krb5_error_code (*load_pair)(krb5_context, 
                                 char *, 
-                                krb5_prompter_fct prompter,
-                                void * prompter_data,
+                                krb5_prompter_fct,
+                                void *,
                                 const char *,
                                 struct krb5_pk_identity *) = NULL;
 
@@ -2553,24 +2562,29 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context,
 
        dh = DH_new();
        if (dh == NULL) {
+           krb5_set_error_string(context, "malloc: out of memory");
            _krb5_get_init_creds_opt_free_pkinit(opt);
            return ENOMEM;
        }
        opt->private->pk_init_ctx->dh = dh;
        if (!BN_hex2bn(&dh->p, P)) {
+           krb5_set_error_string(context, "malloc: out of memory");
            _krb5_get_init_creds_opt_free_pkinit(opt);
            return ENOMEM;
        }
        if (!BN_hex2bn(&dh->g, G)) {
+           krb5_set_error_string(context, "malloc: out of memory");
            _krb5_get_init_creds_opt_free_pkinit(opt);
            return ENOMEM;
        }
        if (!BN_hex2bn(&dh->q, Q)) {
+           krb5_set_error_string(context, "malloc: out of memory");
            _krb5_get_init_creds_opt_free_pkinit(opt);
            return ENOMEM;
        }
        /* XXX generate a new key for each request ? */
        if (DH_generate_key(dh) != 1) {
+           krb5_set_error_string(context, "malloc: out of memory");
            _krb5_get_init_creds_opt_free_pkinit(opt);
            return ENOMEM;
        }
index b7194b4c4107330cef4c107d5bb7e92e388920b6..b510478f659d9afe78ea37126e38bf171a51e10f 100644 (file)
@@ -76,7 +76,7 @@ krb5_principal_get_type(krb5_context context,
 
 const char* KRB5_LIB_FUNCTION
 krb5_principal_get_realm(krb5_context context,
-                        krb5_const_principal principal)
+                        krb5_principal principal)
 {
     return princ_realm(principal);
 }                       
@@ -235,19 +235,19 @@ static const char replace_chars[] = " ntb\\/@";
 #define add_char(BASE, INDEX, LEN, C) do { if((INDEX) < (LEN)) (BASE)[(INDEX)++] = (C); }while(0);
 
 static size_t
-quote_string(const char *s, char *out, size_t string_index, size_t len)
+quote_string(const char *s, char *out, size_t idx, size_t len)
 {
     const char *p, *q;
-    for(p = s; *p && string_index < len; p++){
+    for(p = s; *p && idx < len; p++){
        if((q = strchr(quotable_chars, *p))){
-           add_char(out, string_index, len, '\\');
-           add_char(out, string_index, len, replace_chars[q - quotable_chars]);
+           add_char(out, idx, len, '\\');
+           add_char(out, idx, len, replace_chars[q - quotable_chars]);
        }else
-           add_char(out, string_index, len, *p);
+           add_char(out, idx, len, *p);
     }
-    if(string_index < len)
-       out[string_index] = '\0';
-    return string_index;
+    if(idx < len)
+       out[idx] = '\0';
+    return idx;
 }
 
 
index 9129eceeff45de0216c8c22ba70b1a048e1fd1a6..2571591e9d15cf34850549f261480ce3b3b3264c 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <krb5_locl.h>
 
-RCSID("$Id: rd_cred.c,v 1.23 2005/06/17 04:31:48 lha Exp $");
+RCSID("$Id: rd_cred.c,v 1.24 2005/07/13 08:22:50 lha Exp $");
 
 static krb5_error_code
 compare_addrs(krb5_context context,
@@ -68,6 +68,8 @@ krb5_rd_cred(krb5_context context,
     krb5_crypto crypto;
     int i;
 
+    memset(&enc_krb_cred_part, 0, sizeof(enc_krb_cred_part));
+
     if ((auth_context->flags & 
         (KRB5_AUTH_CONTEXT_RET_TIME | KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
        outdata == NULL)
@@ -262,9 +264,14 @@ krb5_rd_cred(krb5_context context,
        
     }
     (*ret_creds)[i] = NULL;
+
+    free_KRB_CRED (&cred);
+    free_EncKrbCredPart(&enc_krb_cred_part);
+
     return 0;
 
   out:
+    free_EncKrbCredPart(&enc_krb_cred_part);
     free_KRB_CRED (&cred);
     if(*ret_creds) {
        for(i = 0; (*ret_creds)[i]; i++)
diff --git a/source4/heimdal/lib/krb5/test_crypto_wrapping.c b/source4/heimdal/lib/krb5/test_crypto_wrapping.c
new file mode 100644 (file)
index 0000000..37d9bba
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * 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 above 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. Neither the name of KTH nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``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 KTH OR ITS 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. */
+
+#include "krb5_locl.h"
+#include <err.h>
+#include <getarg.h>
+
+RCSID("$Id: test_crypto_wrapping.c,v 1.2 2005/07/09 01:31:43 lha Exp $");
+
+static void
+test_wrapping(krb5_context context,
+             size_t min_size,
+             size_t max_size,
+             size_t step,
+             krb5_enctype etype)
+{
+    krb5_error_code ret;
+    krb5_keyblock key;
+    krb5_crypto crypto;
+    krb5_data data;
+    char *etype_name;
+    void *buf;
+    size_t size;
+
+    ret = krb5_generate_random_keyblock(context, etype, &key);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
+
+    ret = krb5_enctype_to_string(context, etype, &etype_name);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_enctype_to_string");
+
+    buf = malloc(max_size);
+    if (buf == NULL)
+       krb5_errx(context, 1, "out of memory");
+    memset(buf, 0, max_size);
+
+    ret = krb5_crypto_init(context, &key, 0, &crypto);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_crypto_init");
+
+    for (size = min_size; size < max_size; size += step) {
+       size_t wrapped_size;
+
+       ret = krb5_encrypt(context, crypto, 0, buf, size, &data);
+       if (ret)
+           krb5_err(context, 1, ret, "encrypt size %d using %s",
+                    size, etype_name);
+
+       wrapped_size = krb5_get_wrapped_length(context, crypto, size);
+
+       if (wrapped_size != data.length)
+           krb5_errx(context, 1, "calculated wrapped length %lu != "
+                     "real wrapped length %lu for data length %lu using "
+                     "enctype %s",
+                     (unsigned long)wrapped_size,
+                     (unsigned long)data.length,
+                     (unsigned long)size,
+                     etype_name);
+       krb5_data_free(&data);
+    }
+
+    free(buf);
+    krb5_crypto_destroy(context, crypto);
+    krb5_free_keyblock_contents(context, &key);
+}
+
+
+
+static int version_flag = 0;
+static int help_flag   = 0;
+
+static struct getargs args[] = {
+    {"version",        0,      arg_flag,       &version_flag,
+     "print version", NULL },
+    {"help",   0,      arg_flag,       &help_flag,
+     NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+    arg_printusage (args,
+                   sizeof(args)/sizeof(*args),
+                   NULL,
+                   "");
+    exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+    krb5_context context;
+    krb5_error_code ret;
+    int i, optidx = 0;
+
+    krb5_enctype enctypes[] = { 
+       ETYPE_DES_CBC_CRC,
+       ETYPE_DES_CBC_MD4,
+       ETYPE_DES_CBC_MD5,
+       ETYPE_DES3_CBC_SHA1,
+       ETYPE_ARCFOUR_HMAC_MD5,
+       ETYPE_AES128_CTS_HMAC_SHA1_96,
+       ETYPE_AES256_CTS_HMAC_SHA1_96
+    };
+
+    setprogname(argv[0]);
+
+    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+       usage(1);
+    
+    if (help_flag)
+       usage (0);
+
+    if(version_flag){
+       print_version(NULL);
+       exit(0);
+    }
+
+    argc -= optidx;
+    argv += optidx;
+
+    ret = krb5_init_context(&context);
+    if (ret)
+       errx (1, "krb5_init_context failed: %d", ret);
+
+    for (i = 0; i < sizeof(enctypes)/sizeof(enctypes[0]); i++) {
+       test_wrapping(context, 0, 1024, 1, enctypes[i]);
+       test_wrapping(context, 1024, 1024 * 100, 1024, enctypes[i]);
+    }
+    krb5_free_context(context);
+
+    return 0;
+}
diff --git a/source4/heimdal/lib/krb5/test_pkinit_dh2key.c b/source4/heimdal/lib/krb5/test_pkinit_dh2key.c
new file mode 100644 (file)
index 0000000..a40c218
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * 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 above 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. Neither the name of KTH nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``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 KTH OR ITS 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. */
+
+#include "krb5_locl.h"
+#include <err.h>
+#include <getarg.h>
+
+RCSID("$Id: test_pkinit_dh2key.c,v 1.1 2005/07/20 16:27:58 lha Exp $");
+
+static void
+test_dh2key(krb5_context context, 
+           const heim_octet_string *K,
+           const heim_octet_string *c_n,
+           const heim_octet_string *k_n,
+           krb5_enctype etype)
+{
+    return;
+}
+
+
+
+static int version_flag = 0;
+static int help_flag   = 0;
+
+static struct getargs args[] = {
+    {"version",        0,      arg_flag,       &version_flag,
+     "print version", NULL },
+    {"help",   0,      arg_flag,       &help_flag,
+     NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+    arg_printusage (args,
+                   sizeof(args)/sizeof(*args),
+                   NULL,
+                   "");
+    exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+    krb5_context context;
+    krb5_error_code ret;
+    int i, optidx = 0;
+
+    krb5_enctype enctypes[] = { 
+       ETYPE_AES128_CTS_HMAC_SHA1_96,
+       ETYPE_AES256_CTS_HMAC_SHA1_96
+    };
+
+    setprogname(argv[0]);
+
+    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+       usage(1);
+    
+    if (help_flag)
+       usage (0);
+
+    if(version_flag){
+       print_version(NULL);
+       exit(0);
+    }
+
+    argc -= optidx;
+    argv += optidx;
+
+    ret = krb5_init_context(&context);
+    if (ret)
+       errx (1, "krb5_init_context failed: %d", ret);
+
+    for (i = 0; i < sizeof(enctypes)/sizeof(enctypes[0]); i++) {
+       test_dh2key(context, NULL, NULL, NULL, enctypes[i]);
+    }
+
+    krb5_free_context(context);
+
+    return 0;
+}
index 78dbe9c5266b796b06c3005e4b97f45e2474f5af..0d9d6119db07ba80a8da7053c7e25663cc33c411 100644 (file)
@@ -33,7 +33,7 @@
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
-RCSID("$Id: base64.c,v 1.6 2005/04/12 11:28:34 lha Exp $");
+RCSID("$Id: base64.c,v 1.7 2005/06/23 10:47:57 lha Exp $");
 #endif
 #include <stdlib.h>
 #include <string.h>
diff --git a/source4/heimdal/lib/roken/ecalloc.c b/source4/heimdal/lib/roken/ecalloc.c
new file mode 100644 (file)
index 0000000..ad22a45
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * 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 above 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. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: ecalloc.c,v 1.2 2005/04/12 11:28:36 lha Exp $");
+#endif
+
+#include <stdlib.h>
+#include <err.h>
+
+#include <roken.h>
+
+/*
+ * Like calloc but never fails.
+ */
+
+void * ROKEN_LIB_FUNCTION
+ecalloc (size_t number, size_t size)
+{
+    void *tmp = calloc (number, size);
+
+    if (tmp == NULL && number * size != 0)
+       errx (1, "calloc %lu failed", (unsigned long)number * size);
+    return tmp;
+}
diff --git a/source4/heimdal/lib/roken/estrdup.c b/source4/heimdal/lib/roken/estrdup.c
new file mode 100644 (file)
index 0000000..1a20cdd
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1999 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * 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 above 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. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``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 INSTITUTE 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: estrdup.c,v 1.4 2005/04/12 11:28:39 lha Exp $");
+#endif
+
+#include <stdlib.h>
+#include <err.h>
+
+#include <roken.h>
+
+/*
+ * Like strdup but never fails.
+ */
+
+char * ROKEN_LIB_FUNCTION
+estrdup (const char *str)
+{
+    char *tmp = strdup (str);
+
+    if (tmp == NULL)
+       errx (1, "strdup failed");
+    return tmp;
+}
index 5c28f58bf46d2a0ca34974f555edbe99d4d2d562..52db0f88420c6aaf70ce07fc6bddf14f71f4363e 100644 (file)
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
-RCSID("$Id: gai_strerror.c,v 1.5 2005/04/12 11:28:42 lha Exp $");
+RCSID("$Id: gai_strerror.c,v 1.7 2005/08/05 09:31:35 lha Exp $");
 #endif
 
 #include "roken.h"
 
 static struct gai_error {
     int code;
-    char *str;
+    const char *str;
 } errors[] = {
 {EAI_NOERROR,          "no error"},
 #ifdef EAI_ADDRFAMILY
@@ -65,7 +65,7 @@ static struct gai_error {
  *
  */
 
-char * ROKEN_LIB_FUNCTION
+const char * ROKEN_LIB_FUNCTION
 gai_strerror(int ecode)
 {
     struct gai_error *g;
index 545f43c6a755da5162074dd0c9050a705089b3ec..04553caf4888cd76a243f7dd4c76ba8fcebc956b 100644 (file)
@@ -32,7 +32,7 @@
  * SUCH DAMAGE.
  */
 
-/* $Id: roken.h.in,v 1.175 2005/07/07 19:16:17 lha Exp $ */
+/* $Id: roken.h.in,v 1.177 2005/08/05 09:06:29 lha Exp $ */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -143,15 +143,15 @@ ROKEN_CPP_START
 #endif
 
 #ifndef HAVE_PUTENV
-int ROKEN_LIB_FUNCTION putenv(const char *string);
+int ROKEN_LIB_FUNCTION putenv(const char *);
 #endif
 
 #if !defined(HAVE_SETENV) || defined(NEED_SETENV_PROTO)
-int ROKEN_LIB_FUNCTION setenv(const char *var, const char *val, int rewrite);
+int ROKEN_LIB_FUNCTION setenv(const char *, const char *, int);
 #endif
 
 #if !defined(HAVE_UNSETENV) || defined(NEED_UNSETENV_PROTO)
-void ROKEN_LIB_FUNCTION unsetenv(const char *name);
+void ROKEN_LIB_FUNCTION unsetenv(const char *);
 #endif
 
 #if !defined(HAVE_GETUSERSHELL) || defined(NEED_GETUSERSHELL_PROTO)
@@ -160,46 +160,46 @@ void ROKEN_LIB_FUNCTION endusershell(void);
 #endif
 
 #if !defined(HAVE_SNPRINTF) || defined(NEED_SNPRINTF_PROTO)
-int ROKEN_LIB_FUNCTION snprintf (char *str, size_t sz, const char *format, ...)
+int ROKEN_LIB_FUNCTION snprintf (char *, size_t, const char *, ...)
      __attribute__ ((format (printf, 3, 4)));
 #endif
 
 #if !defined(HAVE_VSNPRINTF) || defined(NEED_VSNPRINTF_PROTO)
 int ROKEN_LIB_FUNCTION 
-     vsnprintf (char *str, size_t sz, const char *format, va_list ap)
+     vsnprintf (char *, size_t, const char *, va_list)
      __attribute__((format (printf, 3, 0)));
 #endif
 
 #if !defined(HAVE_ASPRINTF) || defined(NEED_ASPRINTF_PROTO)
 int ROKEN_LIB_FUNCTION
-     asprintf (char **ret, const char *format, ...)
+     asprintf (char **, const char *, ...)
      __attribute__ ((format (printf, 2, 3)));
 #endif
 
 #if !defined(HAVE_VASPRINTF) || defined(NEED_VASPRINTF_PROTO)
 int ROKEN_LIB_FUNCTION
-    vasprintf (char **ret, const char *format, va_list ap)
+    vasprintf (char **, const char *, va_list)
      __attribute__((format (printf, 2, 0)));
 #endif
 
 #if !defined(HAVE_ASNPRINTF) || defined(NEED_ASNPRINTF_PROTO)
 int ROKEN_LIB_FUNCTION
-    asnprintf (char **ret, size_t max_sz, const char *format, ...)
+    asnprintf (char **, size_t, const char *, ...)
      __attribute__ ((format (printf, 3, 4)));
 #endif
 
 #if !defined(HAVE_VASNPRINTF) || defined(NEED_VASNPRINTF_PROTO)
 int ROKEN_LIB_FUNCTION
-    vasnprintf (char **ret, size_t max_sz, const char *format, va_list ap)
+    vasnprintf (char **, size_t, const char *, va_list)
      __attribute__((format (printf, 3, 0)));
 #endif
 
 #ifndef HAVE_STRDUP
-char * ROKEN_LIB_FUNCTION strdup(const char *old);
+char * ROKEN_LIB_FUNCTION strdup(const char *);
 #endif
 
 #if !defined(HAVE_STRNDUP) || defined(NEED_STRNDUP_PROTO)
-char * ROKEN_LIB_FUNCTION strndup(const char *old, size_t sz);
+char * ROKEN_LIB_FUNCTION strndup(const char *, size_t);
 #endif
 
 #ifndef HAVE_STRLWR
@@ -219,7 +219,7 @@ ssize_t ROKEN_LIB_FUNCTION strsep_copy(const char**, const char*, char*, size_t)
 #endif
 
 #ifndef HAVE_STRCASECMP
-int ROKEN_LIB_FUNCTION strcasecmp(const char *s1, const char *s2);
+int ROKEN_LIB_FUNCTION strcasecmp(const char *, const char *);
 #endif
 
 #ifdef NEED_FCLOSE_PROTO
@@ -227,7 +227,7 @@ int ROKEN_LIB_FUNCTION fclose(FILE *);
 #endif
 
 #ifdef NEED_STRTOK_R_PROTO
-char * ROKEN_LIB_FUNCTION strtok_r(char *s1, const char *s2, char **lasts);
+char * ROKEN_LIB_FUNCTION strtok_r(char *, const char *, char **);
 #endif
 
 #ifndef HAVE_STRUPR
@@ -235,11 +235,11 @@ char * ROKEN_LIB_FUNCTION strupr(char *);
 #endif
 
 #ifndef HAVE_STRLCPY
-size_t ROKEN_LIB_FUNCTION strlcpy (char *dst, const char *src, size_t dst_sz);
+size_t ROKEN_LIB_FUNCTION strlcpy (char *, const char *, size_t);
 #endif
 
 #ifndef HAVE_STRLCAT
-size_t ROKEN_LIB_FUNCTION strlcat (char *dst, const char *src, size_t dst_sz);
+size_t ROKEN_LIB_FUNCTION strlcat (char *, const char *, size_t);
 #endif
 
 #ifndef HAVE_GETDTABLESIZE
@@ -247,13 +247,13 @@ int ROKEN_LIB_FUNCTION getdtablesize(void);
 #endif
 
 #if !defined(HAVE_STRERROR) && !defined(strerror)
-char * ROKEN_LIB_FUNCTION strerror(int eno);
+char * ROKEN_LIB_FUNCTION strerror(int);
 #endif
 
 #if !defined(HAVE_HSTRERROR) || defined(NEED_HSTRERROR_PROTO)
 /* This causes a fatal error under Psoriasis */
 #if !(defined(SunOS) && (SunOS >= 50))
-const char * ROKEN_LIB_FUNCTION hstrerror(int herr);
+const char * ROKEN_LIB_FUNCTION hstrerror(int);
 #endif
 #endif
 
@@ -262,7 +262,7 @@ extern int h_errno;
 #endif
 
 #if !defined(HAVE_INET_ATON) || defined(NEED_INET_ATON_PROTO)
-int ROKEN_LIB_FUNCTION inet_aton(const char *cp, struct in_addr *adr);
+int ROKEN_LIB_FUNCTION inet_aton(const char *, struct in_addr *);
 #endif
 
 #ifndef HAVE_INET_NTOP
@@ -272,31 +272,31 @@ inet_ntop(int af, const void *src, char *dst, size_t size);
 
 #ifndef HAVE_INET_PTON
 int ROKEN_LIB_FUNCTION
-inet_pton(int af, const char *src, void *dst);
+inet_pton(int, const char *, void *);
 #endif
 
 #if !defined(HAVE_GETCWD)
-char* ROKEN_LIB_FUNCTION getcwd(char *path, size_t size);
+char* ROKEN_LIB_FUNCTION getcwd(char *, size_t);
 #endif
 
 #ifdef HAVE_PWD_H
 #include <pwd.h>
-struct passwd * ROKEN_LIB_FUNCTION k_getpwnam (const char *user);
-struct passwd * ROKEN_LIB_FUNCTION k_getpwuid (uid_t uid);
+struct passwd * ROKEN_LIB_FUNCTION k_getpwnam (const char *);
+struct passwd * ROKEN_LIB_FUNCTION k_getpwuid (uid_t);
 #endif
 
 const char * ROKEN_LIB_FUNCTION get_default_username (void);
 
 #ifndef HAVE_SETEUID
-int ROKEN_LIB_FUNCTION seteuid(uid_t euid);
+int ROKEN_LIB_FUNCTION seteuid(uid_t);
 #endif
 
 #ifndef HAVE_SETEGID
-int ROKEN_LIB_FUNCTION setegid(gid_t egid);
+int ROKEN_LIB_FUNCTION setegid(gid_t);
 #endif
 
 #ifndef HAVE_LSTAT
-int ROKEN_LIB_FUNCTION lstat(const char *path, struct stat *buf);
+int ROKEN_LIB_FUNCTION lstat(const char *, struct stat *);
 #endif
 
 #if !defined(HAVE_MKSTEMP) || defined(NEED_MKSTEMP_PROTO)
@@ -304,35 +304,35 @@ int ROKEN_LIB_FUNCTION mkstemp(char *);
 #endif
 
 #ifndef HAVE_CGETENT
-int ROKEN_LIB_FUNCTION cgetent(char **buf, char **db_array, const char *name);
-int ROKEN_LIB_FUNCTION cgetstr(char *buf, const char *cap, char **str);
+int ROKEN_LIB_FUNCTION cgetent(char **, char **, const char *);
+int ROKEN_LIB_FUNCTION cgetstr(char *, const char *, char **);
 #endif
 
 #ifndef HAVE_INITGROUPS
-int ROKEN_LIB_FUNCTION initgroups(const char *name, gid_t basegid);
+int ROKEN_LIB_FUNCTION initgroups(const char *, gid_t);
 #endif
 
 #ifndef HAVE_FCHOWN
-int ROKEN_LIB_FUNCTION fchown(int fd, uid_t owner, gid_t group);
+int ROKEN_LIB_FUNCTION fchown(int, uid_t, gid_t);
 #endif
 
 #if !defined(HAVE_DAEMON) || defined(NEED_DAEMON_PROTO)
-int ROKEN_LIB_FUNCTION daemon(int nochdir, int noclose);
+int ROKEN_LIB_FUNCTION daemon(int, int);
 #endif
 
 #ifndef HAVE_INNETGR
-int ROKEN_LIB_FUNCTION innetgr(const char *netgroup, const char *machine
-           const char *user, const char *domain);
+int ROKEN_LIB_FUNCTION innetgr(const char *, const char *
+           const char *, const char *);
 #endif
 
 #ifndef HAVE_CHOWN
-int ROKEN_LIB_FUNCTION chown(const char *path, uid_t owner, gid_t group);
+int ROKEN_LIB_FUNCTION chown(const char *, uid_t, gid_t);
 #endif
 
 #ifndef HAVE_RCMD
 int ROKEN_LIB_FUNCTION
-    rcmd(char **ahost, unsigned short inport, const char *locuser,
-        const char *remuser, const char *cmd, int *fd2p);
+    rcmd(char **, unsigned short, const char *,
+        const char *, const char *, int *);
 #endif
 
 #if !defined(HAVE_INNETGR) || defined(NEED_INNETGR_PROTO)
@@ -341,27 +341,27 @@ int ROKEN_LIB_FUNCTION innetgr(const char*, const char*,
 #endif
 
 #ifndef HAVE_IRUSEROK
-int ROKEN_LIB_FUNCTION iruserok(unsigned raddr, int superuser
-    const char *ruser, const char *luser);
+int ROKEN_LIB_FUNCTION iruserok(unsigned, int
+    const char *, const char *);
 #endif
 
 #if !defined(HAVE_GETHOSTNAME) || defined(NEED_GETHOSTNAME_PROTO)
-int ROKEN_LIB_FUNCTION gethostname(char *name, int namelen);
+int ROKEN_LIB_FUNCTION gethostname(char *, int);
 #endif
 
 #ifndef HAVE_WRITEV
 ssize_t ROKEN_LIB_FUNCTION
-writev(int d, const struct iovec *iov, int iovcnt);
+writev(int, const struct iovec *, int);
 #endif
 
 #ifndef HAVE_READV
 ssize_t ROKEN_LIB_FUNCTION
-readv(int d, const struct iovec *iov, int iovcnt);
+readv(int, const struct iovec *, int);
 #endif
 
 #ifndef HAVE_MKSTEMP
 int ROKEN_LIB_FUNCTION
-mkstemp(char *template);
+mkstemp(char *);
 #endif
 
 #ifndef HAVE_PIDFILE
@@ -393,22 +393,22 @@ unsigned short ROKEN_LIB_FUNCTION bswap16(unsigned short);
 int flock(int fd, int operation);
 #endif /* HAVE_FLOCK */
 
-time_t ROKEN_LIB_FUNCTION tm2time (struct tm tm, int local);
+time_t ROKEN_LIB_FUNCTION tm2time (struct tm, int);
 
-int ROKEN_LIB_FUNCTION unix_verify_user(char *user, char *password);
+int ROKEN_LIB_FUNCTION unix_verify_user(char *, char *);
 
-int ROKEN_LIB_FUNCTION roken_concat (char *s, size_t len, ...);
+int ROKEN_LIB_FUNCTION roken_concat (char *, size_t, ...);
 
-size_t ROKEN_LIB_FUNCTION roken_mconcat (char **s, size_t max_len, ...);
+size_t ROKEN_LIB_FUNCTION roken_mconcat (char **, size_t, ...);
 
-int ROKEN_LIB_FUNCTION roken_vconcat (char *s, size_t len, va_list args);
+int ROKEN_LIB_FUNCTION roken_vconcat (char *, size_t, va_list);
 
 size_t ROKEN_LIB_FUNCTION
-    roken_vmconcat (char **s, size_t max_len, va_list args);
+    roken_vmconcat (char **, size_t, va_list);
 
-ssize_t ROKEN_LIB_FUNCTION net_write (int fd, const void *buf, size_t nbytes);
+ssize_t ROKEN_LIB_FUNCTION net_write (int, const void *, size_t);
 
-ssize_t ROKEN_LIB_FUNCTION net_read (int fd, void *buf, size_t nbytes);
+ssize_t ROKEN_LIB_FUNCTION net_read (int, void *, size_t);
 
 int ROKEN_LIB_FUNCTION issuid(void);
 
@@ -422,7 +422,7 @@ struct winsize {
 int ROKEN_LIB_FUNCTION get_window_size(int fd, struct winsize *);
 
 #ifndef HAVE_VSYSLOG
-void ROKEN_LIB_FUNCTION vsyslog(int pri, const char *fmt, va_list ap);
+void ROKEN_LIB_FUNCTION vsyslog(int, const char *, va_list);
 #endif
 
 #if !HAVE_DECL_OPTARG
@@ -441,22 +441,22 @@ extern char **environ;
 
 #ifndef HAVE_GETIPNODEBYNAME
 struct hostent * ROKEN_LIB_FUNCTION
-getipnodebyname (const char *name, int af, int flags, int *error_num);
+getipnodebyname (const char *, int, int, int *);
 #endif
 
 #ifndef HAVE_GETIPNODEBYADDR
 struct hostent * ROKEN_LIB_FUNCTION
-getipnodebyaddr (const void *src, size_t len, int af, int *error_num);
+getipnodebyaddr (const void *, size_t, int, int *);
 #endif
 
 #ifndef HAVE_FREEHOSTENT
 void ROKEN_LIB_FUNCTION
-freehostent (struct hostent *h);
+freehostent (struct hostent *);
 #endif
 
 #ifndef HAVE_COPYHOSTENT
 struct hostent * ROKEN_LIB_FUNCTION
-copyhostent (const struct hostent *h);
+copyhostent (const struct hostent *);
 #endif
 
 #ifndef HAVE_SOCKLEN_T
@@ -523,35 +523,35 @@ struct addrinfo {
 
 #ifndef HAVE_GETADDRINFO
 int ROKEN_LIB_FUNCTION
-getaddrinfo(const char *nodename,
-           const char *servname,
-           const struct addrinfo *hints,
-           struct addrinfo **res);
+getaddrinfo(const char *,
+           const char *,
+           const struct addrinfo *,
+           struct addrinfo **);
 #endif
 
 #ifndef HAVE_GETNAMEINFO
 int ROKEN_LIB_FUNCTION
-getnameinfo(const struct sockaddr *sa, socklen_t salen,
-               char *host, size_t hostlen,
-               char *serv, size_t servlen,
-               int flags);
+getnameinfo(const struct sockaddr *, socklen_t,
+               char *, size_t,
+               char *, size_t,
+               int);
 #endif
 
 #ifndef HAVE_FREEADDRINFO
 void ROKEN_LIB_FUNCTION
-freeaddrinfo(struct addrinfo *ai);
+freeaddrinfo(struct addrinfo *);
 #endif
 
 #ifndef HAVE_GAI_STRERROR
-char * ROKEN_LIB_FUNCTION
-gai_strerror(int ecode);
+const char * ROKEN_LIB_FUNCTION
+gai_strerror(int);
 #endif
 
 int ROKEN_LIB_FUNCTION
-getnameinfo_verified(const struct sockaddr *sa, socklen_t salen,
-                    char *host, size_t hostlen,
-                    char *serv, size_t servlen,
-                    int flags);
+getnameinfo_verified(const struct sockaddr *, socklen_t,
+                    char *, size_t,
+                    char *, size_t,
+                    int);
 
 int ROKEN_LIB_FUNCTION
 roken_getaddrinfo_hostspec(const char *, int, struct addrinfo **); 
@@ -560,20 +560,19 @@ roken_getaddrinfo_hostspec2(const char *, int, int, struct addrinfo **);
 
 #ifndef HAVE_STRFTIME
 size_t ROKEN_LIB_FUNCTION
-strftime (char *buf, size_t maxsize, const char *format,
-         const struct tm *tm);
+strftime (char *, size_t, const char *, const struct tm *);
 #endif
 
 #ifndef HAVE_STRPTIME
 char * ROKEN_LIB_FUNCTION
-strptime (const char *buf, const char *format, struct tm *timeptr);
+strptime (const char *, const char *, struct tm *);
 #endif
 
 #ifndef HAVE_EMALLOC
 void * ROKEN_LIB_FUNCTION emalloc (size_t);
 #endif
 #ifndef HAVE_ECALLOC
-void * ROKEN_LIB_FUNCTION ecalloc(size_t num, size_t sz);
+void * ROKEN_LIB_FUNCTION ecalloc(size_t, size_t);
 #endif
 #ifndef HAVE_EREALLOC
 void * ROKEN_LIB_FUNCTION erealloc (void *, size_t);
@@ -626,7 +625,7 @@ roken_gethostbyaddr(const void*, size_t, int);
 #endif
 
 #ifndef HAVE_SETPROGNAME
-void ROKEN_LIB_FUNCTION setprogname(const char *argv0);
+void ROKEN_LIB_FUNCTION setprogname(const char *);
 #endif
 
 #ifndef HAVE_GETPROGNAME
@@ -638,46 +637,46 @@ extern const char *__progname;
 #endif
 
 void ROKEN_LIB_FUNCTION mini_inetd_addrinfo (struct addrinfo*);
-void ROKEN_LIB_FUNCTION mini_inetd (int port);
+void ROKEN_LIB_FUNCTION mini_inetd (int);
 
 #ifndef HAVE_LOCALTIME_R
 struct tm * ROKEN_LIB_FUNCTION
-localtime_r(const time_t *timer, struct tm *result);
+localtime_r(const time_t *, struct tm *);
 #endif
 
 #if !defined(HAVE_STRSVIS) || defined(NEED_STRSVIS_PROTO)
 int ROKEN_LIB_FUNCTION
-strsvis(char *dst, const char *src, int flag, const char *extra);
+strsvis(char *, const char *, int, const char *);
 #endif
 
 #if !defined(HAVE_STRUNVIS) || defined(NEED_STRUNVIS_PROTO)
 int ROKEN_LIB_FUNCTION
-strunvis(char *dst, const char *src);
+strunvis(char *, const char *);
 #endif
 
 #if !defined(HAVE_STRVIS) || defined(NEED_STRVIS_PROTO)
 int ROKEN_LIB_FUNCTION
-strvis(char *dst, const char *src, int flag);
+strvis(char *, const char *, int);
 #endif
 
 #if !defined(HAVE_STRVISX) || defined(NEED_STRVISX_PROTO)
 int ROKEN_LIB_FUNCTION
-strvisx(char *dst, const char *src, size_t len, int flag);
+strvisx(char *, const char *, size_t, int);
 #endif
 
 #if !defined(HAVE_SVIS) || defined(NEED_SVIS_PROTO)
 char * ROKEN_LIB_FUNCTION
-svis(char *dst, int c, int flag, int nextc, const char *extra);
+svis(char *, int, int, int, const char *);
 #endif
 
 #if !defined(HAVE_UNVIS) || defined(NEED_UNVIS_PROTO)
 int ROKEN_LIB_FUNCTION
-unvis(char *cp, int c, int *astate, int flag);
+unvis(char *, int, int *, int);
 #endif
 
 #if !defined(HAVE_VIS) || defined(NEED_VIS_PROTO)
 char * ROKEN_LIB_FUNCTION
-vis(char *dst, int c, int flag, int nextc);
+vis(char *, int, int, int);
 #endif
 
 #if !defined(HAVE_CLOSEFROM)
index 962aadfdaddf5ed0a044ed0b258b3ef67e8c6618..11e6bad706335c85f449deb16d4c9efb91205205 100755 (executable)
@@ -7,18 +7,22 @@ use File::Basename;
 
 my $file = shift;
 my $prefix = shift;
+my $options = shift;
 my $x_file, @x_files;
 my $c_file, @c_files;
 if (not defined ($prefix)) { $prefix = "asn1"; }
 
 $dirname = dirname($file);
 $basename = basename($file);
+if (not defined $options) {
+    $options = "";
+}
 
 my $header = "$dirname/$prefix.h";
 
 print "$header: $file bin/asn1_compile\n";
 print "\t\@echo \"Compiling ASN1 file $file\"\n";
-print "\t\@cd $dirname && ../../../bin/asn1_compile $basename $prefix\n\n";
+print "\t\@cd $dirname && ../../../bin/asn1_compile $options $basename $prefix\n\n";
 
 open(IN,$file) or die("Can't open $file: $!");
 foreach(<IN>) {
index 0eb8316d1ad38b056a5165f9caab40011d4c547a..6e8882ed11e8f933b88d3a6c68a9ba324e87465a 100644 (file)
@@ -53,6 +53,7 @@ ADD_OBJ_FILES = \
        heimdal/lib/gssapi/asn1_ContextFlags.o \
        heimdal/lib/gssapi/asn1_MechType.o \
        heimdal/lib/gssapi/asn1_MechTypeList.o \
+       heimdal/lib/gssapi/asn1_NegotiationToken.o \
        heimdal/lib/gssapi/asn1_NegTokenInit.o \
        heimdal/lib/gssapi/asn1_NegTokenTarg.o \
        heimdal/lib/gssapi/8003.o \
@@ -236,8 +237,9 @@ ADD_OBJ_FILES = \
        heimdal/lib/asn1/asn1_Ticket.o \
        heimdal/lib/asn1/asn1_TicketFlags.o \
        heimdal/lib/asn1/asn1_TransitedEncoding.o \
-       heimdal/lib/asn1/asn1_UNSIGNED.o \
-       heimdal/lib/asn1/asn1_err.o
+       heimdal/lib/asn1/asn1_err.o \
+       heimdal/lib/asn1/asn1_krb5int32.o \
+       heimdal/lib/asn1/asn1_krb5uint32.o
 NOPROTO = YES
 # End SUBSYSTEM HEIMDAL_KRB5
 #######################
@@ -357,6 +359,8 @@ ADD_OBJ_FILES = \
        heimdal/lib/roken/strupr.o \
        heimdal/lib/roken/getprogname.o \
        heimdal/lib/roken/get_window_size.o \
+       heimdal/lib/roken/estrdup.o \
+       heimdal/lib/roken/ecalloc.o \
        heimdal/lib/asn1/symbol.o \
        heimdal_build/replace.o
 NOPROTO = YES
@@ -403,7 +407,7 @@ heimdal/lib/roken/err.h: heimdal/lib/roken/err.hin
 
 include ./heimdal_build/asn1_deps.pl heimdal/lib/hdb/hdb.asn1 hdb_asn1|
 include ./heimdal_build/asn1_deps.pl heimdal/lib/gssapi/spnego.asn1 spnego_asn1|
-include ./heimdal_build/asn1_deps.pl heimdal/lib/asn1/k5.asn1 krb5_asn1|
+include ./heimdal_build/asn1_deps.pl heimdal/lib/asn1/k5.asn1 krb5_asn1 --encode-rfc1510-bit-string|
 
 include ./heimdal_build/et_deps.pl heimdal/lib/asn1/asn1_err.et|
 include ./heimdal_build/et_deps.pl heimdal/lib/hdb/hdb_err.et|
@@ -423,11 +427,7 @@ heimdal_basics: \
        heimdal/lib/krb5/k524_err.h \
        heimdal/lib/krb5/krb5_err.h
 
-heimdal_clean:
-       @echo Removing generated ASN1 files
-       @-find heimdal/lib/asn1 -name 'asn1_*.[cx]' -exec rm -f '{}' \;
-       @-find heimdal/lib/gssapi -name 'asn1_*.[c]' -exec rm -f '{}' \;
-       @-find heimdal/lib/hdb -name 'asn1_*.[c]' -exec rm -f '{}' \;
+heimdal_clean: hdb_asn1_clean spnego_asn1_clean krb5_asn1_clean
        @-rm -f heimdal/lib/roken/vis.h heimdal/lib/roken/err.h
        @-rm -f heimdal/lib/hdb/hdb_asn1.h
        @-rm -f heimdal/lib/gssapi/spnego_asn1.h
index 532e9103df8e9257a9077ec1ab96bf27e211eb10..ac8296c5ae094ec0f39c72a64d458b307fafe4da 100644 (file)
@@ -3,6 +3,9 @@
 
 #ifndef __krb5_types_h__
 #define __krb5_types_h__
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #if HAVE_INTTYPES_H
 #include <inttypes.h>