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

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

diff --git a/source/heimdal/fix-export b/source/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/source/heimdal/lib/asn1/CMS.asn1 b/source/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/source/heimdal/lib/asn1/asn1_gen.c b/source/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/source/heimdal/lib/asn1/asn1_queue.h b/source/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/source/heimdal/lib/asn1/canthandle.asn1 b/source/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/source/heimdal/lib/asn1/der.c b/source/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/source/heimdal/lib/asn1/extra.c b/source/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/source/heimdal/lib/asn1/heim_asn1.h b/source/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,
-&n