r9413: Bring Samba4 back up to date with lorikeet-heimdal.
authorAndrew Bartlett <abartlet@samba.org>
Sat, 20 Aug 2005 06:00:50 +0000 (06:00 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:33:35 +0000 (13:33 -0500)
Delete test_crypto_wrapping.c, previously included but unbuilt.

Andrew Bartlett
(This used to be commit d5fb30fb0cef330e0947969f0c9afc1f58fc4c7d)

26 files changed:
source4/heimdal/kdc/kdc_locl.h
source4/heimdal/kdc/kerberos5.c
source4/heimdal/kdc/pkinit.c
source4/heimdal/kdc/process.c
source4/heimdal/lib/asn1/asn1_gen.c
source4/heimdal/lib/asn1/canthandle.asn1
source4/heimdal/lib/asn1/lex.c
source4/heimdal/lib/asn1/parse.c
source4/heimdal/lib/asn1/parse.h
source4/heimdal/lib/gssapi/init_sec_context.c
source4/heimdal/lib/hdb/ext.c [new file with mode: 0644]
source4/heimdal/lib/hdb/hdb-private.h
source4/heimdal/lib/hdb/hdb-protos.h
source4/heimdal/lib/hdb/hdb.asn1
source4/heimdal/lib/hdb/hdb.h
source4/heimdal/lib/hdb/hdb_err.et
source4/heimdal/lib/hdb/mkey.c [new file with mode: 0644]
source4/heimdal/lib/krb5/crypto.c
source4/heimdal/lib/krb5/fcache.c
source4/heimdal/lib/krb5/init_creds_pw.c
source4/heimdal/lib/krb5/krb5-private.h
source4/heimdal/lib/krb5/krb5-protos.h
source4/heimdal/lib/krb5/pkinit.c
source4/heimdal/lib/krb5/test_crypto_wrapping.c [deleted file]
source4/heimdal/lib/krb5/test_pkinit_dh2key.c [deleted file]
source4/heimdal_build/config.mk

index d347c6080c62db1e19b1bff023ea9c637991f8ef..b87895d56cb94bf8ef56e9407268d5bef95372f6 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 /* 
- * $Id: kdc_locl.h,v 1.71 2005/07/01 15:36:16 lha Exp $ 
+ * $Id: kdc_locl.h,v 1.72 2005/08/12 08:46:39 lha Exp $ 
  */
 
 #ifndef __KDC_LOCL_H__
@@ -61,7 +61,8 @@ extern struct timeval _kdc_now;
 krb5_error_code
 _kdc_as_rep(krb5_context context, 
            krb5_kdc_configuration *config,
-           KDC_REQ*, krb5_data*, const char*, struct sockaddr*);
+           KDC_REQ*, const krb5_data*, krb5_data*, 
+           const char*, struct sockaddr*);
 
 krb5_kdc_configuration *
 configure(krb5_context context, int argc, char **argv);
index e85a269a010673aeee13972a74dc7c6026c6a99c..27a25d95ff4f79fc2dc6e410e05eae1aedf8aa7f 100644 (file)
@@ -189,7 +189,8 @@ log_timestamp(krb5_context context,
              KerberosTime authtime, KerberosTime *starttime, 
              KerberosTime endtime, KerberosTime *renew_till)
 {
-    char authtime_str[100], starttime_str[100], endtime_str[100], renewtime_str[100];
+    char authtime_str[100], starttime_str[100], 
+       endtime_str[100], renewtime_str[100];
     
     krb5_format_time(context, authtime, 
                     authtime_str, sizeof(authtime_str), TRUE); 
@@ -728,6 +729,7 @@ krb5_error_code
 _kdc_as_rep(krb5_context context, 
            krb5_kdc_configuration *config,
            KDC_REQ *req, 
+           const krb5_data *req_buffer, 
            krb5_data *reply,
            const char *from,
            struct sockaddr *from_addr)
@@ -940,7 +942,8 @@ _kdc_as_rep(krb5_context context,
                kdc_log(context, config, 5, 
                        "Failed to decrypt PA-DATA -- %s "
                        "(enctype %s) error %s",
-                       client_name, str ? str : "unknown enctype", 
+                       client_name,
+                       str ? str : "unknown enctype", 
                        krb5_get_err_text(context, ret));
                free(str);
 
@@ -1308,8 +1311,9 @@ _kdc_as_rep(krb5_context context,
     reply_key = &ckey->key;
 #if PKINIT
     if (pkp) {
-       ret = _kdc_pk_mk_pa_reply(context, config, pkp, client, req,
-                             &reply_key, rep.padata);
+       ret = _kdc_pk_mk_pa_reply(context, config, pkp, client, 
+                                 req, req_buffer, 
+                                 &reply_key, rep.padata);
        if (ret)
            goto out;
     }
@@ -1372,30 +1376,35 @@ check_tgs_flags(krb5_context context,
        
     if(f.validate){
        if(!tgt->flags.invalid || tgt->starttime == NULL){
-           kdc_log(context, config, 0, "Bad request to validate ticket");
+           kdc_log(context, config, 0,
+                   "Bad request to validate ticket");
            return KRB5KDC_ERR_BADOPTION;
        }
        if(*tgt->starttime > kdc_time){
-           kdc_log(context, config, 0, "Early request to validate ticket");
+           kdc_log(context, config, 0,
+                   "Early request to validate ticket");
            return KRB5KRB_AP_ERR_TKT_NYV;
        }
        /* XXX  tkt = tgt */
        et->flags.invalid = 0;
     }else if(tgt->flags.invalid){
-       kdc_log(context, config, 0, "Ticket-granting ticket has INVALID flag set");
+       kdc_log(context, config, 0, 
+               "Ticket-granting ticket has INVALID flag set");
        return KRB5KRB_AP_ERR_TKT_INVALID;
     }
 
     if(f.forwardable){
        if(!tgt->flags.forwardable){
-           kdc_log(context, config, 0, "Bad request for forwardable ticket");
+           kdc_log(context, config, 0,
+                   "Bad request for forwardable ticket");
            return KRB5KDC_ERR_BADOPTION;
        }
        et->flags.forwardable = 1;
     }
     if(f.forwarded){
        if(!tgt->flags.forwardable){
-           kdc_log(context, config, 0, "Request to forward non-forwardable ticket");
+           kdc_log(context, config, 0,
+                   "Request to forward non-forwardable ticket");
            return KRB5KDC_ERR_BADOPTION;
        }
        et->flags.forwarded = 1;
@@ -1906,7 +1915,8 @@ tgs_check_authenticator(krb5_context context,
     free(buf);
     krb5_crypto_destroy(context, crypto);
     if(ret){
-       kdc_log(context, config, 0, "Failed to verify authenticator checksum: %s", 
+       kdc_log(context, config, 0,
+               "Failed to verify authenticator checksum: %s", 
                krb5_get_err_text(context, ret));
     }
 out:
@@ -2102,11 +2112,11 @@ tgs_rep2(krb5_context context,
 
     ret = tgs_check_authenticator(context, config, 
                                  ac, b, &e_text, &tgt->key);
-    if(ret){
+    if (ret) {
        krb5_auth_con_free(context, ac);
        goto out2;
     }
-    
+
     if (b->enc_authorization_data) {
        krb5_keyblock *subkey;
        krb5_data ad;
@@ -2167,6 +2177,8 @@ tgs_rep2(krb5_context context,
        }
     }
 
+    krb5_auth_con_free(context, ac);
+
     {
        PrincipalName *s;
        Realm r;
index f591aa8fc12bac1b2cf7677502efdbb113202da6..fdeaf27ac4441d2c2edf98d9302bddd234467332 100755 (executable)
@@ -33,7 +33,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: pkinit.c,v 1.37 2005/07/26 18:37:02 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.41 2005/08/12 09:21:40 lha Exp $");
 
 #ifdef PKINIT
 
@@ -66,7 +66,7 @@ struct krb5_pk_cert {
 enum pkinit_type {
     PKINIT_COMPAT_WIN2K = 1,
     PKINIT_COMPAT_19 = 2,
-    PKINIT_COMPAT_25 = 3
+    PKINIT_COMPAT_27 = 3
 };
 
 struct pk_client_params {
@@ -640,7 +640,7 @@ _kdc_pk_rd_padata(krb5_context context,
        PA_PK_AS_REQ r;
        ContentInfo info;
 
-       type = "PK-INIT-25";
+       type = "PK-INIT-27";
        pa_contentType = oid_id_pkauthdata();
 
        ret = decode_PA_PK_AS_REQ(pa->padata_value.data,
@@ -796,7 +796,7 @@ _kdc_pk_rd_padata(krb5_context context,
            goto out;
        }
 
-       client_params->type = PKINIT_COMPAT_25;
+       client_params->type = PKINIT_COMPAT_27;
        client_params->nonce = ap.pkAuthenticator.nonce;
 
        if (ap.clientPublicValue) {
@@ -851,6 +851,7 @@ static krb5_error_code
 pk_mk_pa_reply_enckey(krb5_context context,
                      pk_client_params *client_params,
                      const KDC_REQ *req,
+                     const krb5_data *req_buffer,
                      krb5_keyblock *reply_key,
                      ContentInfo *content_info)
 {
@@ -945,7 +946,8 @@ pk_mk_pa_reply_enckey(krb5_context context,
                           &kp, &size,ret);
        free_ReplyKeyPack_19(&kp);
     }
-    case PKINIT_COMPAT_25: {
+    case PKINIT_COMPAT_27: {
+       krb5_crypto ascrypto;
        ReplyKeyPack kp;
        memset(&kp, 0, sizeof(kp));
 
@@ -954,9 +956,29 @@ pk_mk_pa_reply_enckey(krb5_context context,
            krb5_clear_error_string(context);
            goto out;
        }
-       /* XXX add whatever is the outcome of asChecksum discussion here */
+
+       ret = krb5_crypto_init(context, reply_key, 0, &ascrypto);
+       if (ret) {
+           krb5_clear_error_string(context);
+           goto out;
+       }
+
+       ret = krb5_create_checksum(context, ascrypto, 6, 0,
+                                  req_buffer->data, req_buffer->length,
+                                  &kp.asChecksum);
+       if (ret) {
+           krb5_clear_error_string(context);
+           goto out;
+       }
+                            
+       ret = krb5_crypto_destroy(context, ascrypto);
+       if (ret) {
+           krb5_clear_error_string(context);
+           goto out;
+       }
        ASN1_MALLOC_ENCODE(ReplyKeyPack, buf.data, buf.length, &kp, &size,ret);
        free_ReplyKeyPack(&kp);
+       break;
     }
     default:
        krb5_abortx(context, "internal pkinit error");
@@ -1194,6 +1216,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
                    pk_client_params *client_params,
                    const hdb_entry *client,
                    const KDC_REQ *req,
+                   const krb5_data *req_buffer,
                    krb5_keyblock **reply_key,
                    METHOD_DATA *md)
 {
@@ -1223,7 +1246,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
     } else
        enctype = ETYPE_DES3_CBC_SHA1;
 
-    if (client_params->type == PKINIT_COMPAT_25) {
+    if (client_params->type == PKINIT_COMPAT_27) {
        PA_PK_AS_REP rep;
 
        pa_type = KRB5_PADATA_PK_AS_REP;
@@ -1239,6 +1262,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
            ret = pk_mk_pa_reply_enckey(context,
                                        client_params,
                                        req,
+                                       req_buffer,
                                        &client_params->reply_key,
                                        &info);
            if (ret) {
@@ -1259,7 +1283,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
                krb5_abortx(context, "Internal ASN.1 encoder error");
 
        } else {
-           krb5_set_error_string(context, "DH -25 not implemented");
+           krb5_set_error_string(context, "DH -27 not implemented");
            ret = KRB5KRB_ERR_GENERIC;
        }
        if (ret) {
@@ -1291,6 +1315,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
            ret = pk_mk_pa_reply_enckey(context,
                                        client_params,
                                        req,
+                                       req_buffer,
                                        &client_params->reply_key,
                                        &rep.u.encKeyPack);
        } else {
@@ -1332,7 +1357,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
        memset(&rep, 0, sizeof(rep));
 
        if (client_params->dh) {
-           krb5_set_error_string(context, "DH -25 not implemented");
+           krb5_set_error_string(context, "DH -27 not implemented");
            ret = KRB5KRB_ERR_GENERIC;
        } else {
            rep.element = choice_PA_PK_AS_REP_encKeyPack;
@@ -1343,6 +1368,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
            ret = pk_mk_pa_reply_enckey(context,
                                        client_params,
                                        req,
+                                       req_buffer,
                                        &client_params->reply_key,
                                        &info);
            if (ret) {
index 22cf23c48d9089fcbdd84377284ee6aaf68860fc..d0f8245bf9101a3b02c4c407b72136577821908a 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "kdc_locl.h"
 
-RCSID("$Id: process.c,v 1.2 2005/06/30 01:54:49 lha Exp $");
+RCSID("$Id: process.c,v 1.3 2005/08/12 08:25:48 lha Exp $");
 
 /*
  * handle the request in `buf, len', from `addr' (or `from' as a string),
@@ -58,7 +58,13 @@ krb5_kdc_process_generic_request(krb5_context context,
 
     gettimeofday(&_kdc_now, NULL);
     if(decode_AS_REQ(buf, len, &req, &i) == 0){
-       ret = _kdc_as_rep(context, config, &req, reply, from, addr);
+       krb5_data req_buffer;
+
+       req_buffer.data = buf;
+       req_buffer.length = len;
+
+       ret = _kdc_as_rep(context, config, &req, &req_buffer, 
+                         reply, from, addr);
        free_AS_REQ(&req);
        return ret;
     }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
@@ -105,7 +111,13 @@ krb5_kdc_process_krb5_request(krb5_context context,
 
     gettimeofday(&_kdc_now, NULL);
     if(decode_AS_REQ(buf, len, &req, &i) == 0){
-       ret = _kdc_as_rep(context, config, &req, reply, from, addr);
+       krb5_data req_buffer;
+
+       req_buffer.data = buf;
+       req_buffer.length = len;
+
+       ret = _kdc_as_rep(context, config, &req, &req_buffer,
+                         reply, from, addr);
        free_AS_REQ(&req);
        return ret;
     }else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
index 939fb1123e274acd788ca7d4e573cdae59612a25..95d670cbb16b3ae8823d58d176715783ef268a0a 100644 (file)
@@ -40,7 +40,7 @@
 #include <hex.h>
 #include <err.h>
 
-RCSID("$Id: asn1_gen.c,v 1.2 2005/07/12 06:27:14 lha Exp $");
+RCSID("$Id: asn1_gen.c,v 1.3 2005/08/11 10:44:43 lha Exp $");
 
 static int
 doit(const char *fn)
@@ -166,11 +166,11 @@ usage(int code)
 int
 main(int argc, char **argv)
 {
-    int optind = 0;
+    int optidx = 0;
 
     setprogname (argv[0]);
 
-    if(getarg(args, num_args, argc, argv, &optind))
+    if(getarg(args, num_args, argc, argv, &optidx))
        usage(1);
     if(help_flag)
        usage(0);
@@ -178,8 +178,8 @@ main(int argc, char **argv)
        print_version(NULL);
        exit(0);
     }
-    argv += optind;
-    argc -= optind;
+    argv += optidx;
+    argc -= optidx;
     if (argc != 1)
        usage (1);
 
index 55ba4d1bb6a7c4c2d68b8e03fe622e04e93f49ae..7d012ed6f8df3c00763bfca5792be7e4f96b6d98 100644 (file)
@@ -1,4 +1,4 @@
--- $Id: canthandle.asn1,v 1.4 2005/07/21 20:49:15 lha Exp $ --
+-- $Id: canthandle.asn1,v 1.5 2005/08/11 14:07:21 lha Exp $ --
 
 CANTHANDLE DEFINITIONS ::= BEGIN
 
@@ -31,4 +31,10 @@ Bar ::= SEQUENCE {
 
 Baz ::= SET OF INTEGER
 
+-- Allocation is done on CONTEXT tags.
+
+Alloc ::= SEQUENCE {
+       a heim_any OPTIONAL
+}
+
 END
index 713a3d26aacd6de653a1279c75431da7618b286e..3b563038e89b9a39157a7b1d4287ea4c3732ec91 100644 (file)
@@ -760,7 +760,7 @@ static unsigned lineno = 1;
 
 static void handle_comment(int type);
 static char *handle_string(void);
-#line 764 "lex.yy.c"
+#line 764 "lex.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -913,7 +913,7 @@ YY_DECL
 
 #line 62 "lex.l"
 
-#line 917 "lex.yy.c"
+#line 917 "lex.c"
 
        if ( yy_init )
                {
@@ -1481,7 +1481,7 @@ YY_RULE_SETUP
 #line 168 "lex.l"
 ECHO;
        YY_BREAK
-#line 1485 "lex.yy.c"
+#line 1485 "lex.c"
 case YY_STATE_EOF(INITIAL):
        yyterminate();
 
index 2d8697843bda4aeee623245cf864995c7c401e64..83e8ccb8b5101ba7d3ecf624856c3286e9dca769 100644 (file)
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 1.875c.  */
+/* A Bison parser, made by GNU Bison 2.0.  */
 
 /* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -291,7 +291,7 @@ typedef union YYSTYPE {
     struct tagtype tag;
     struct memhead *members;
 } YYSTYPE;
-/* Line 191 of yacc.c.  */
+/* Line 190 of yacc.c.  */
 #line 296 "parse.c"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -303,7 +303,7 @@ typedef union YYSTYPE {
 /* Copy the second part of user declarations.  */
 
 
-/* Line 214 of yacc.c.  */
+/* Line 213 of yacc.c.  */
 #line 308 "parse.c"
 
 #if ! defined (yyoverflow) || YYERROR_VERBOSE
@@ -319,14 +319,10 @@ typedef union YYSTYPE {
 
 # ifdef YYSTACK_USE_ALLOCA
 #  if YYSTACK_USE_ALLOCA
-#   define YYSTACK_ALLOC alloca
-#  endif
-# else
-#  if defined (alloca) || defined (_ALLOCA_H)
-#   define YYSTACK_ALLOC alloca
-#  else
 #   ifdef __GNUC__
 #    define YYSTACK_ALLOC __builtin_alloca
+#   else
+#    define YYSTACK_ALLOC alloca
 #   endif
 #  endif
 # endif
@@ -352,7 +348,7 @@ typedef union YYSTYPE {
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  short yyss;
+  short int yyss;
   YYSTYPE yyvs;
   };
 
@@ -362,7 +358,7 @@ union yyalloc
 /* The size of an array large to enough to hold all stacks, each with
    N elements.  */
 # define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (short) + sizeof (YYSTYPE))                                \
+     ((N) * (sizeof (short int) + sizeof (YYSTYPE))                    \
       + YYSTACK_GAP_MAXIMUM)
 
 /* Copy COUNT objects from FROM to TO.  The source and destination do
@@ -404,7 +400,7 @@ union yyalloc
 #if defined (__STDC__) || defined (__cplusplus)
    typedef signed char yysigned_char;
 #else
-   typedef short yysigned_char;
+   typedef short int yysigned_char;
 #endif
 
 /* YYFINAL -- State number of the termination state. */
@@ -471,7 +467,7 @@ static const unsigned char yytranslate[] =
 #if YYDEBUG
 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
    YYRHS.  */
-static const unsigned short yyprhs[] =
+static const unsigned short int yyprhs[] =
 {
        0,     0,     3,    12,    15,    18,    21,    22,    25,    26,
       29,    30,    34,    35,    37,    38,    40,    43,    48,    50,
@@ -489,7 +485,7 @@ static const unsigned short yyprhs[] =
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const short yyrhs[] =
+static const short int yyrhs[] =
 {
       99,     0,    -1,    86,    21,   100,   101,    84,     8,   102,
       24,    -1,    27,    70,    -1,    38,    70,    -1,     7,    70,
@@ -527,7 +523,7 @@ static const short yyrhs[] =
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const unsigned short yyrline[] =
+static const unsigned short int yyrline[] =
 {
        0,   222,   222,   229,   230,   232,   234,   237,   239,   242,
      243,   246,   247,   250,   251,   254,   255,   258,   269,   270,
@@ -592,7 +588,7 @@ static const char *const yytname[] =
 # ifdef YYPRINT
 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
    token YYLEX-NUM.  */
-static const unsigned short yytoknum[] =
+static const unsigned short int yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
@@ -670,7 +666,7 @@ static const unsigned char yydefact[] =
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
-static const short yydefgoto[] =
+static const short int yydefgoto[] =
 {
       -1,     2,     8,    13,    18,    19,    21,    22,    23,    27,
       28,    24,    29,    56,    57,    58,    85,    59,   110,   111,
@@ -724,7 +720,7 @@ static const yysigned_char yypgoto[] =
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -13
-static const short yytable[] =
+static const short int yytable[] =
 {
       35,    36,    37,    88,   139,    38,    90,    17,    93,    98,
        5,   149,   151,   105,   105,   150,    39,   154,   167,   105,
@@ -744,7 +740,7 @@ static const short yytable[] =
      163,     0,   170
 };
 
-static const short yycheck[] =
+static const short int yycheck[] =
 {
        9,    10,    11,    53,    97,    14,    53,    40,     6,    27,
        7,    91,    20,    86,    86,    95,    25,    91,    85,    86,
@@ -840,20 +836,53 @@ do                                                                \
     }                                                          \
 while (0)
 
+
 #define YYTERROR       1
 #define YYERRCODE      256
 
-/* YYLLOC_DEFAULT -- Compute the default location (before the actions
-   are run).  */
 
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
 #ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)               \
-   ((Current).first_line   = (Rhs)[1].first_line,      \
-    (Current).first_column = (Rhs)[1].first_column,    \
-    (Current).last_line    = (Rhs)[N].last_line,       \
-    (Current).last_column  = (Rhs)[N].last_column)
+# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                 \
+      if (N)                                                           \
+       {                                                               \
+         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         (Current).first_line   = (Current).last_line   =              \
+           YYRHSLOC (Rhs, 0).last_line;                                \
+         (Current).first_column = (Current).last_column =              \
+           YYRHSLOC (Rhs, 0).last_column;                              \
+       }                                                               \
+    while (0)
 #endif
 
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                 \
+     fprintf (File, "%d.%d-%d.%d",                     \
+              (Loc).first_line, (Loc).first_column,    \
+              (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
 /* YYLEX -- calling `yylex' with the right arguments.  */
 
 #ifdef YYLEX_PARAM
@@ -876,19 +905,13 @@ do {                                              \
     YYFPRINTF Args;                            \
 } while (0)
 
-# define YYDSYMPRINT(Args)                     \
-do {                                           \
-  if (yydebug)                                 \
-    yysymprint Args;                           \
-} while (0)
-
-# define YYDSYMPRINTF(Title, Token, Value, Location)           \
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)         \
 do {                                                           \
   if (yydebug)                                                 \
     {                                                          \
       YYFPRINTF (stderr, "%s ", Title);                                \
       yysymprint (stderr,                                      \
-                  Token, Value);       \
+                  Type, Value);        \
       YYFPRINTF (stderr, "\n");                                        \
     }                                                          \
 } while (0)
@@ -900,12 +923,12 @@ do {                                                              \
 
 #if defined (__STDC__) || defined (__cplusplus)
 static void
-yy_stack_print (short *bottom, short *top)
+yy_stack_print (short int *bottom, short int *top)
 #else
 static void
 yy_stack_print (bottom, top)
-    short *bottom;
-    short *top;
+    short int *bottom;
+    short int *top;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
@@ -955,8 +978,7 @@ do {                                        \
 int yydebug;
 #else /* !YYDEBUG */
 # define YYDPRINTF(Args)
-# define YYDSYMPRINT(Args)
-# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
 # define YY_STACK_PRINT(Bottom, Top)
 # define YY_REDUCE_PRINT(Rule)
 #endif /* !YYDEBUG */
@@ -974,10 +996,6 @@ int yydebug;
    SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
    evaluated with infinite-precision integer arithmetic.  */
 
-#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
-# undef YYMAXDEPTH
-#endif
-
 #ifndef YYMAXDEPTH
 # define YYMAXDEPTH 10000
 #endif
@@ -1059,15 +1077,15 @@ yysymprint (yyoutput, yytype, yyvaluep)
   (void) yyvaluep;
 
   if (yytype < YYNTOKENS)
-    {
-      YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-# ifdef YYPRINT
-      YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
-    }
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
   else
     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
 
+
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
   switch (yytype)
     {
       default:
@@ -1083,10 +1101,11 @@ yysymprint (yyoutput, yytype, yyvaluep)
 
 #if defined (__STDC__) || defined (__cplusplus)
 static void
-yydestruct (int yytype, YYSTYPE *yyvaluep)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
 #else
 static void
-yydestruct (yytype, yyvaluep)
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
     int yytype;
     YYSTYPE *yyvaluep;
 #endif
@@ -1094,6 +1113,10 @@ yydestruct (yytype, yyvaluep)
   /* Pacify ``unused variable'' warnings.  */
   (void) yyvaluep;
 
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
   switch (yytype)
     {
 
@@ -1121,10 +1144,10 @@ int yyparse ();
 
 
 
-/* The lookahead symbol.  */
+/* The look-ahead symbol.  */
 int yychar;
 
-/* The semantic value of the lookahead symbol.  */
+/* The semantic value of the look-ahead symbol.  */
 YYSTYPE yylval;
 
 /* Number of syntax errors so far.  */
@@ -1160,7 +1183,7 @@ yyparse ()
   int yyresult;
   /* Number of tokens to shift before error messages enabled.  */
   int yyerrstatus;
-  /* Lookahead token as an internal (translated) token number.  */
+  /* Look-ahead token as an internal (translated) token number.  */
   int yytoken = 0;
 
   /* Three stacks and their tools:
@@ -1172,9 +1195,9 @@ yyparse ()
      to reallocate them elsewhere.  */
 
   /* The state stack.  */
-  short        yyssa[YYINITDEPTH];
-  short *yyss = yyssa;
-  register short *yyssp;
+  short int yyssa[YYINITDEPTH];
+  short int *yyss = yyssa;
+  register short int *yyssp;
 
   /* The semantic value stack.  */
   YYSTYPE yyvsa[YYINITDEPTH];
@@ -1211,6 +1234,9 @@ yyparse ()
   yyssp = yyss;
   yyvsp = yyvs;
 
+
+  yyvsp[0] = yylval;
+
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -1236,7 +1262,7 @@ yyparse ()
           these so that the &'s don't force the real ones into
           memory.  */
        YYSTYPE *yyvs1 = yyvs;
-       short *yyss1 = yyss;
+       short int *yyss1 = yyss;
 
 
        /* Each stack pointer address is followed by the size of the
@@ -1264,7 +1290,7 @@ yyparse ()
        yystacksize = YYMAXDEPTH;
 
       {
-       short *yyss1 = yyss;
+       short int *yyss1 = yyss;
        union yyalloc *yyptr =
          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
        if (! yyptr)
@@ -1300,18 +1326,18 @@ yyparse ()
 yybackup:
 
 /* Do appropriate processing given the current state.  */
-/* Read a lookahead token if we need one and don't already have one.  */
+/* Read a look-ahead token if we need one and don't already have one.  */
 /* yyresume: */
 
-  /* First try to decide what to do without reference to lookahead token.  */
+  /* First try to decide what to do without reference to look-ahead token.  */
 
   yyn = yypact[yystate];
   if (yyn == YYPACT_NINF)
     goto yydefault;
 
-  /* Not known => get a lookahead token if don't already have one.  */
+  /* Not known => get a look-ahead token if don't already have one.  */
 
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
@@ -1326,7 +1352,7 @@ yybackup:
   else
     {
       yytoken = YYTRANSLATE (yychar);
-      YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
     }
 
   /* If the proper action on seeing token YYTOKEN is to reduce or to
@@ -1346,8 +1372,8 @@ yybackup:
   if (yyn == YYFINAL)
     YYACCEPT;
 
-  /* Shift the lookahead token.  */
-  YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
   /* Discard the token being shifted unless it is eof.  */
   if (yychar != YYEOF)
@@ -1422,38 +1448,38 @@ yyreduce:
 #line 259 "parse.y"
     { 
                    struct string_list *sl;
-                   for(sl = yyvsp[-3].sl; sl != NULL; sl = sl->next) {
+                   for(sl = (yyvsp[-3].sl); sl != NULL; sl = sl->next) {
                        Symbol *s = addsym(sl->string);
                        s->stype = Stype;
                    }
-                   add_import(yyvsp[-1].name);
+                   add_import((yyvsp[-1].name));
                }
     break;
 
   case 22:
 #line 278 "parse.y"
     {
-                   yyval.sl = emalloc(sizeof(*yyval.sl));
-                   yyval.sl->string = yyvsp[-2].name;
-                   yyval.sl->next = yyvsp[0].sl;
+                   (yyval.sl) = emalloc(sizeof(*(yyval.sl)));
+                   (yyval.sl)->string = (yyvsp[-2].name);
+                   (yyval.sl)->next = (yyvsp[0].sl);
                }
     break;
 
   case 23:
 #line 284 "parse.y"
     {
-                   yyval.sl = emalloc(sizeof(*yyval.sl));
-                   yyval.sl->string = yyvsp[0].name;
-                   yyval.sl->next = NULL;
+                   (yyval.sl) = emalloc(sizeof(*(yyval.sl)));
+                   (yyval.sl)->string = (yyvsp[0].name);
+                   (yyval.sl)->next = NULL;
                }
     break;
 
   case 24:
 #line 292 "parse.y"
     {
-                   Symbol *s = addsym (yyvsp[-2].name);
+                   Symbol *s = addsym ((yyvsp[-2].name));
                    s->stype = Stype;
-                   s->type = yyvsp[0].type;
+                   s->type = (yyvsp[0].type);
                    fix_labels(s);
                    generate_type (s);
                }
@@ -1462,7 +1488,7 @@ yyreduce:
   case 41:
 #line 322 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_Boolean, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_Boolean, 
                                     TE_EXPLICIT, new_type(TBoolean));
                }
     break;
@@ -1470,18 +1496,18 @@ yyreduce:
   case 42:
 #line 329 "parse.y"
     {
-                       if(yyvsp[-3].value->type != integervalue || 
-                          yyvsp[-1].value->type != integervalue)
+                       if((yyvsp[-3].value)->type != integervalue || 
+                          (yyvsp[-1].value)->type != integervalue)
                                error_message("Non-integer value used in range");
-                       yyval.range.min = yyvsp[-3].value->u.integervalue;
-                       yyval.range.max = yyvsp[-1].value->u.integervalue;
+                       (yyval.range).min = (yyvsp[-3].value)->u.integervalue;
+                       (yyval.range).max = (yyvsp[-1].value)->u.integervalue;
                }
     break;
 
   case 43:
 #line 339 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_Integer, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_Integer, 
                                     TE_EXPLICIT, new_type(TInteger));
                }
     break;
@@ -1489,90 +1515,90 @@ yyreduce:
   case 44:
 #line 344 "parse.y"
     {
-                       yyval.type = new_type(TInteger);
-                       yyval.type->range = emalloc(sizeof(*yyval.type->range));
-                       *(yyval.type->range) = yyvsp[0].range;
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, yyval.type);
+                       (yyval.type) = new_type(TInteger);
+                       (yyval.type)->range = emalloc(sizeof(*(yyval.type)->range));
+                       *((yyval.type)->range) = (yyvsp[0].range);
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 45:
 #line 351 "parse.y"
     {
-                 yyval.type = new_type(TInteger);
-                 yyval.type->members = yyvsp[-1].members;
-                 yyval.type = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, yyval.type);
+                 (yyval.type) = new_type(TInteger);
+                 (yyval.type)->members = (yyvsp[-1].members);
+                 (yyval.type) = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 46:
 #line 359 "parse.y"
     {
-                       yyval.members = emalloc(sizeof(*yyval.members));
-                       ASN1_TAILQ_INIT(yyval.members);
-                       ASN1_TAILQ_INSERT_HEAD(yyval.members, yyvsp[0].member, members);
+                       (yyval.members) = emalloc(sizeof(*(yyval.members)));
+                       ASN1_TAILQ_INIT((yyval.members));
+                       ASN1_TAILQ_INSERT_HEAD((yyval.members), (yyvsp[0].member), members);
                }
     break;
 
   case 47:
 #line 365 "parse.y"
     {
-                       ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, yyvsp[0].member, members);
-                       yyval.members = yyvsp[-2].members;
+                       ASN1_TAILQ_INSERT_TAIL((yyvsp[-2].members), (yyvsp[0].member), members);
+                       (yyval.members) = (yyvsp[-2].members);
                }
     break;
 
   case 48:
 #line 370 "parse.y"
-    { yyval.members = yyvsp[-2].members; }
+    { (yyval.members) = (yyvsp[-2].members); }
     break;
 
   case 49:
 #line 374 "parse.y"
     {
-                       yyval.member = emalloc(sizeof(*yyval.member));
-                       yyval.member->name = yyvsp[-3].name;
-                       yyval.member->gen_name = estrdup(yyvsp[-3].name);
-                       output_name (yyval.member->gen_name);
-                       yyval.member->val = yyvsp[-1].constant;
-                       yyval.member->optional = 0;
-                       yyval.member->ellipsis = 0;
-                       yyval.member->type = NULL;
+                       (yyval.member) = emalloc(sizeof(*(yyval.member)));
+                       (yyval.member)->name = (yyvsp[-3].name);
+                       (yyval.member)->gen_name = estrdup((yyvsp[-3].name));
+                       output_name ((yyval.member)->gen_name);
+                       (yyval.member)->val = (yyvsp[-1].constant);
+                       (yyval.member)->optional = 0;
+                       (yyval.member)->ellipsis = 0;
+                       (yyval.member)->type = NULL;
                }
     break;
 
   case 50:
 #line 387 "parse.y"
     {
-                 yyval.type = new_type(TInteger);
-                 yyval.type->members = yyvsp[-1].members;
-                 yyval.type = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, yyval.type);
+                 (yyval.type) = new_type(TInteger);
+                 (yyval.type)->members = (yyvsp[-1].members);
+                 (yyval.type) = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 52:
 #line 398 "parse.y"
     {
-                 yyval.type = new_type(TBitString);
-                 yyval.type->members = emalloc(sizeof(*yyval.type->members));
-                 ASN1_TAILQ_INIT(yyval.type->members);
-                 yyval.type = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, yyval.type);
+                 (yyval.type) = new_type(TBitString);
+                 (yyval.type)->members = emalloc(sizeof(*(yyval.type)->members));
+                 ASN1_TAILQ_INIT((yyval.type)->members);
+                 (yyval.type) = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 53:
 #line 405 "parse.y"
     {
-                 yyval.type = new_type(TBitString);
-                 yyval.type->members = yyvsp[-1].members;
-                 yyval.type = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, yyval.type);
+                 (yyval.type) = new_type(TBitString);
+                 (yyval.type)->members = (yyvsp[-1].members);
+                 (yyval.type) = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 54:
 #line 413 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_OID, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_OID, 
                                     TE_EXPLICIT, new_type(TOID));
                }
     break;
@@ -1580,7 +1606,7 @@ yyreduce:
   case 55:
 #line 419 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_OctetString, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_OctetString, 
                                     TE_EXPLICIT, new_type(TOctetString));
                }
     break;
@@ -1588,7 +1614,7 @@ yyreduce:
   case 56:
 #line 426 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_Null, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_Null, 
                                     TE_EXPLICIT, new_type(TNull));
                }
     break;
@@ -1596,81 +1622,81 @@ yyreduce:
   case 57:
 #line 433 "parse.y"
     {
-                 yyval.type = new_type(TSequence);
-                 yyval.type->members = yyvsp[-1].members;
-                 yyval.type = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, yyval.type);
+                 (yyval.type) = new_type(TSequence);
+                 (yyval.type)->members = (yyvsp[-1].members);
+                 (yyval.type) = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 58:
 #line 439 "parse.y"
     {
-                 yyval.type = new_type(TSequence);
-                 yyval.type->members = NULL;
-                 yyval.type = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, yyval.type);
+                 (yyval.type) = new_type(TSequence);
+                 (yyval.type)->members = NULL;
+                 (yyval.type) = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 59:
 #line 447 "parse.y"
     {
-                 yyval.type = new_type(TSequenceOf);
-                 yyval.type->subtype = yyvsp[0].type;
-                 yyval.type = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, yyval.type);
+                 (yyval.type) = new_type(TSequenceOf);
+                 (yyval.type)->subtype = (yyvsp[0].type);
+                 (yyval.type) = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 60:
 #line 455 "parse.y"
     {
-                 yyval.type = new_type(TSet);
-                 yyval.type->members = yyvsp[-1].members;
-                 yyval.type = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, yyval.type);
+                 (yyval.type) = new_type(TSet);
+                 (yyval.type)->members = (yyvsp[-1].members);
+                 (yyval.type) = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 61:
 #line 461 "parse.y"
     {
-                 yyval.type = new_type(TSet);
-                 yyval.type->members = NULL;
-                 yyval.type = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, yyval.type);
+                 (yyval.type) = new_type(TSet);
+                 (yyval.type)->members = NULL;
+                 (yyval.type) = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 62:
 #line 469 "parse.y"
     {
-                 yyval.type = new_type(TSetOf);
-                 yyval.type->subtype = yyvsp[0].type;
-                 yyval.type = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, yyval.type);
+                 (yyval.type) = new_type(TSetOf);
+                 (yyval.type)->subtype = (yyvsp[0].type);
+                 (yyval.type) = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, (yyval.type));
                }
     break;
 
   case 63:
 #line 477 "parse.y"
     {
-                 yyval.type = new_type(TChoice);
-                 yyval.type->members = yyvsp[-1].members;
+                 (yyval.type) = new_type(TChoice);
+                 (yyval.type)->members = (yyvsp[-1].members);
                }
     break;
 
   case 66:
 #line 488 "parse.y"
     {
-                 Symbol *s = addsym(yyvsp[0].name);
-                 yyval.type = new_type(TType);
+                 Symbol *s = addsym((yyvsp[0].name));
+                 (yyval.type) = new_type(TType);
                  if(s->stype != Stype && s->stype != SUndefined)
-                   error_message ("%s is not a type\n", yyvsp[0].name);
+                   error_message ("%s is not a type\n", (yyvsp[0].name));
                  else
-                   yyval.type->symbol = s;
+                   (yyval.type)->symbol = s;
                }
     break;
 
   case 67:
 #line 499 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_GeneralizedTime, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_GeneralizedTime, 
                                     TE_EXPLICIT, new_type(TGeneralizedTime));
                }
     break;
@@ -1678,7 +1704,7 @@ yyreduce:
   case 68:
 #line 504 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_UTCTime, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_UTCTime, 
                                     TE_EXPLICIT, new_type(TUTCTime));
                }
     break;
@@ -1686,72 +1712,72 @@ yyreduce:
   case 69:
 #line 511 "parse.y"
     {
-                       yyval.type = new_type(TTag);
-                       yyval.type->tag = yyvsp[-2].tag;
-                       yyval.type->tag.tagenv = yyvsp[-1].constant;
-                       if(yyvsp[0].type->type == TTag && yyvsp[-1].constant == TE_IMPLICIT) {
-                               yyval.type->subtype = yyvsp[0].type->subtype;
-                               free(yyvsp[0].type);
+                       (yyval.type) = new_type(TTag);
+                       (yyval.type)->tag = (yyvsp[-2].tag);
+                       (yyval.type)->tag.tagenv = (yyvsp[-1].constant);
+                       if((yyvsp[0].type)->type == TTag && (yyvsp[-1].constant) == TE_IMPLICIT) {
+                               (yyval.type)->subtype = (yyvsp[0].type)->subtype;
+                               free((yyvsp[0].type));
                        } else
-                               yyval.type->subtype = yyvsp[0].type;
+                               (yyval.type)->subtype = (yyvsp[0].type);
                }
     break;
 
   case 70:
 #line 524 "parse.y"
     {
-                       yyval.tag.tagclass = yyvsp[-2].constant;
-                       yyval.tag.tagvalue = yyvsp[-1].constant;
-                       yyval.tag.tagenv = TE_EXPLICIT;
+                       (yyval.tag).tagclass = (yyvsp[-2].constant);
+                       (yyval.tag).tagvalue = (yyvsp[-1].constant);
+                       (yyval.tag).tagenv = TE_EXPLICIT;
                }
     break;
 
   case 71:
 #line 532 "parse.y"
     {
-                       yyval.constant = ASN1_C_CONTEXT;
+                       (yyval.constant) = ASN1_C_CONTEXT;
                }
     break;
 
   case 72:
 #line 536 "parse.y"
     {
-                       yyval.constant = ASN1_C_UNIV;
+                       (yyval.constant) = ASN1_C_UNIV;
                }
     break;
 
   case 73:
 #line 540 "parse.y"
     {
-                       yyval.constant = ASN1_C_APPL;
+                       (yyval.constant) = ASN1_C_APPL;
                }
     break;
 
   case 74:
 #line 544 "parse.y"
     {
-                       yyval.constant = ASN1_C_PRIVATE;
+                       (yyval.constant) = ASN1_C_PRIVATE;
                }
     break;
 
   case 75:
 #line 550 "parse.y"
     {
-                       yyval.constant = TE_EXPLICIT;
+                       (yyval.constant) = TE_EXPLICIT;
                }
     break;
 
   case 76:
 #line 554 "parse.y"
     {
-                       yyval.constant = TE_EXPLICIT;
+                       (yyval.constant) = TE_EXPLICIT;
                }
     break;
 
   case 77:
 #line 558 "parse.y"
     {
-                       yyval.constant = TE_IMPLICIT;
+                       (yyval.constant) = TE_IMPLICIT;
                }
     break;
 
@@ -1759,10 +1785,10 @@ yyreduce:
 #line 565 "parse.y"
     {
                        Symbol *s;
-                       s = addsym (yyvsp[-3].name);
+                       s = addsym ((yyvsp[-3].name));
 
                        s->stype = SValue;
-                       s->value = yyvsp[0].value;
+                       s->value = (yyvsp[0].value);
                        generate_constant (s);
                }
     break;
@@ -1770,7 +1796,7 @@ yyreduce:
   case 80:
 #line 579 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_GeneralString, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_GeneralString, 
                                     TE_EXPLICIT, new_type(TGeneralString));
                }
     break;
@@ -1778,7 +1804,7 @@ yyreduce:
   case 81:
 #line 584 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_UTF8String, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_UTF8String, 
                                     TE_EXPLICIT, new_type(TUTF8String));
                }
     break;
@@ -1786,7 +1812,7 @@ yyreduce:
   case 82:
 #line 589 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_PrintableString, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_PrintableString, 
                                     TE_EXPLICIT, new_type(TPrintableString));
                }
     break;
@@ -1794,7 +1820,7 @@ yyreduce:
   case 83:
 #line 594 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_IA5String, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_IA5String, 
                                     TE_EXPLICIT, new_type(TIA5String));
                }
     break;
@@ -1802,7 +1828,7 @@ yyreduce:
   case 84:
 #line 599 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_BMPString, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_BMPString, 
                                     TE_EXPLICIT, new_type(TBMPString));
                }
     break;
@@ -1810,7 +1836,7 @@ yyreduce:
   case 85:
 #line 604 "parse.y"
     {
-                       yyval.type = new_tag(ASN1_C_UNIV, UT_UniversalString, 
+                       (yyval.type) = new_tag(ASN1_C_UNIV, UT_UniversalString, 
                                     TE_EXPLICIT, new_type(TUniversalString));
                }
     break;
@@ -1818,17 +1844,17 @@ yyreduce:
   case 86:
 #line 612 "parse.y"
     {
-                       yyval.members = emalloc(sizeof(*yyval.members));
-                       ASN1_TAILQ_INIT(yyval.members);
-                       ASN1_TAILQ_INSERT_HEAD(yyval.members, yyvsp[0].member, members);
+                       (yyval.members) = emalloc(sizeof(*(yyval.members)));
+                       ASN1_TAILQ_INIT((yyval.members));
+                       ASN1_TAILQ_INSERT_HEAD((yyval.members), (yyvsp[0].member), members);
                }
     break;
 
   case 87:
 #line 618 "parse.y"
     {
-                       ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, yyvsp[0].member, members);
-                       yyval.members = yyvsp[-2].members;
+                       ASN1_TAILQ_INSERT_TAIL((yyvsp[-2].members), (yyvsp[0].member), members);
+                       (yyval.members) = (yyvsp[-2].members);
                }
     break;
 
@@ -1839,108 +1865,108 @@ yyreduce:
                        m->name = estrdup("...");
                        m->gen_name = estrdup("asn1_ellipsis");
                        m->ellipsis = 1;
-                       ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, m, members);
-                       yyval.members = yyvsp[-2].members;
+                       ASN1_TAILQ_INSERT_TAIL((yyvsp[-2].members), m, members);
+                       (yyval.members) = (yyvsp[-2].members);
                }
     break;
 
   case 89:
 #line 634 "parse.y"
     {
-                 yyval.member = emalloc(sizeof(*yyval.member));
-                 yyval.member->name = yyvsp[-1].name;
-                 yyval.member->gen_name = estrdup(yyvsp[-1].name);
-                 output_name (yyval.member->gen_name);
-                 yyval.member->type = yyvsp[0].type;
-                 yyval.member->ellipsis = 0;
+                 (yyval.member) = emalloc(sizeof(*(yyval.member)));
+                 (yyval.member)->name = (yyvsp[-1].name);
+                 (yyval.member)->gen_name = estrdup((yyvsp[-1].name));
+                 output_name ((yyval.member)->gen_name);
+                 (yyval.member)->type = (yyvsp[0].type);
+                 (yyval.member)->ellipsis = 0;
                }
     break;
 
   case 90:
 #line 645 "parse.y"
     {
-                       yyval.member = yyvsp[0].member;
-                       yyval.member->optional = 0;
-                       yyval.member->defval = NULL;
+                       (yyval.member) = (yyvsp[0].member);
+                       (yyval.member)->optional = 0;
+                       (yyval.member)->defval = NULL;
                }
     break;
 
   case 91:
 #line 651 "parse.y"
     {
-                       yyval.member = yyvsp[-1].member;
-                       yyval.member->optional = 1;
-                       yyval.member->defval = NULL;
+                       (yyval.member) = (yyvsp[-1].member);
+                       (yyval.member)->optional = 1;
+                       (yyval.member)->defval = NULL;
                }
     break;
 
   case 92:
 #line 657 "parse.y"
     {
-                       yyval.member = yyvsp[-2].member;
-                       yyval.member->optional = 0;
-                       yyval.member->defval = yyvsp[0].value;
+                       (yyval.member) = (yyvsp[-2].member);
+                       (yyval.member)->optional = 0;
+                       (yyval.member)->defval = (yyvsp[0].value);
                }
     break;
 
   case 93:
 #line 665 "parse.y"
     {
-                       yyval.members = emalloc(sizeof(*yyval.members));
-                       ASN1_TAILQ_INIT(yyval.members);
-                       ASN1_TAILQ_INSERT_HEAD(yyval.members, yyvsp[0].member, members);
+                       (yyval.members) = emalloc(sizeof(*(yyval.members)));
+                       ASN1_TAILQ_INIT((yyval.members));
+                       ASN1_TAILQ_INSERT_HEAD((yyval.members), (yyvsp[0].member), members);
                }
     break;
 
   case 94:
 #line 671 "parse.y"
     {
-                       ASN1_TAILQ_INSERT_TAIL(yyvsp[-2].members, yyvsp[0].member, members);
-                       yyval.members = yyvsp[-2].members;
+                       ASN1_TAILQ_INSERT_TAIL((yyvsp[-2].members), (yyvsp[0].member), members);
+                       (yyval.members) = (yyvsp[-2].members);
                }
     break;
 
   case 95:
 #line 678 "parse.y"
     {
-                 yyval.member = emalloc(sizeof(*yyval.member));
-                 yyval.member->name = yyvsp[-3].name;
-                 yyval.member->gen_name = estrdup(yyvsp[-3].name);
-                 output_name (yyval.member->gen_name);
-                 yyval.member->val = yyvsp[-1].constant;
-                 yyval.member->optional = 0;
-                 yyval.member->ellipsis = 0;
-                 yyval.member->type = NULL;
+                 (yyval.member) = emalloc(sizeof(*(yyval.member)));
+                 (yyval.member)->name = (yyvsp[-3].name);
+                 (yyval.member)->gen_name = estrdup((yyvsp[-3].name));
+                 output_name ((yyval.member)->gen_name);
+                 (yyval.member)->val = (yyvsp[-1].constant);
+                 (yyval.member)->optional = 0;
+                 (yyval.member)->ellipsis = 0;
+                 (yyval.member)->type = NULL;
                }
     break;
 
   case 97:
 #line 691 "parse.y"
-    { yyval.objid = NULL; }
+    { (yyval.objid) = NULL; }
     break;
 
   case 98:
 #line 695 "parse.y"
     {
-                       yyval.objid = yyvsp[-1].objid;
+                       (yyval.objid) = (yyvsp[-1].objid);
                }
     break;
 
   case 99:
 #line 701 "parse.y"
     {
-                       yyval.objid = NULL;
+                       (yyval.objid) = NULL;
                }
     break;
 
   case 100:
 #line 705 "parse.y"
     {
-                       if (yyvsp[0].objid) {
-                               yyval.objid = yyvsp[0].objid;
-                               add_oid_to_tail(yyvsp[0].objid, yyvsp[-1].objid);
+                       if ((yyvsp[0].objid)) {
+                               (yyval.objid) = (yyvsp[0].objid);
+                               add_oid_to_tail((yyvsp[0].objid), (yyvsp[-1].objid));
                        } else {
-                               yyval.objid = yyvsp[-1].objid;
+                               (yyval.objid) = (yyvsp[-1].objid);
                        }
                }
     break;
@@ -1948,76 +1974,76 @@ yyreduce:
   case 101:
 #line 716 "parse.y"
     {
-                       yyval.objid = new_objid(yyvsp[-3].name, yyvsp[-1].constant);
+                       (yyval.objid) = new_objid((yyvsp[-3].name), (yyvsp[-1].constant));
                }
     break;
 
   case 102:
 #line 720 "parse.y"
     {
-                   Symbol *s = addsym(yyvsp[0].name);
+                   Symbol *s = addsym((yyvsp[0].name));
                    if(s->stype != SValue ||
                       s->value->type != objectidentifiervalue) {
                        error_message("%s is not an object identifier\n", 
                                      s->name);
                        exit(1);
                    }
-                   yyval.objid = s->value->u.objectidentifiervalue;
+                   (yyval.objid) = s->value->u.objectidentifiervalue;
                }
     break;
 
   case 103:
 #line 731 "parse.y"
     {
-                   yyval.objid = new_objid(NULL, yyvsp[0].constant);
+                   (yyval.objid) = new_objid(NULL, (yyvsp[0].constant));
                }
     break;
 
   case 113:
 #line 754 "parse.y"
     {
-                       Symbol *s = addsym(yyvsp[0].name);
+                       Symbol *s = addsym((yyvsp[0].name));
                        if(s->stype != SValue)
                                error_message ("%s is not a value\n",
                                                s->name);
                        else
-                               yyval.value = s->value;
+                               (yyval.value) = s->value;
                }
     break;
 
   case 114:
 #line 765 "parse.y"
     {
-                       yyval.value = emalloc(sizeof(*yyval.value));
-                       yyval.value->type = stringvalue;
-                       yyval.value->u.stringvalue = yyvsp[0].name;
+                       (yyval.value) = emalloc(sizeof(*(yyval.value)));
+                       (yyval.value)->type = stringvalue;
+                       (yyval.value)->u.stringvalue = (yyvsp[0].name);
                }
     break;
 
   case 115:
 #line 773 "parse.y"
     {
-                       yyval.value = emalloc(sizeof(*yyval.value));
-                       yyval.value->type = booleanvalue;
-                       yyval.value->u.booleanvalue = 0;
+                       (yyval.value) = emalloc(sizeof(*(yyval.value)));
+                       (yyval.value)->type = booleanvalue;
+                       (yyval.value)->u.booleanvalue = 0;
                }
     break;
 
   case 116:
 #line 779 "parse.y"
     {
-                       yyval.value = emalloc(sizeof(*yyval.value));
-                       yyval.value->type = booleanvalue;
-                       yyval.value->u.booleanvalue = 0;
+                       (yyval.value) = emalloc(sizeof(*(yyval.value)));
+                       (yyval.value)->type = booleanvalue;
+                       (yyval.value)->u.booleanvalue = 0;
                }
     break;
 
   case 117:
 #line 787 "parse.y"
     {
-                       yyval.value = emalloc(sizeof(*yyval.value));
-                       yyval.value->type = integervalue;
-                       yyval.value->u.integervalue = yyvsp[0].constant;
+                       (yyval.value) = emalloc(sizeof(*(yyval.value)));
+                       (yyval.value)->type = integervalue;
+                       (yyval.value)->u.integervalue = (yyvsp[0].constant);
                }
     break;
 
@@ -2030,17 +2056,17 @@ yyreduce:
   case 120:
 #line 803 "parse.y"
     {
-                       yyval.value = emalloc(sizeof(*yyval.value));
-                       yyval.value->type = objectidentifiervalue;
-                       yyval.value->u.objectidentifiervalue = yyvsp[0].objid;
+                       (yyval.value) = emalloc(sizeof(*(yyval.value)));
+                       (yyval.value)->type = objectidentifiervalue;
+                       (yyval.value)->u.objectidentifiervalue = (yyvsp[0].objid);
                }
     break;
 
 
     }
 
-/* Line 1000 of yacc.c.  */
-#line 2044 "parse.c"
+/* Line 1037 of yacc.c.  */
+#line 2070 "parse.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -2140,7 +2166,7 @@ yyerrlab:
 
   if (yyerrstatus == 3)
     {
-      /* If just tried and failed to reuse lookahead token after an
+      /* If just tried and failed to reuse look-ahead token after an
         error, discard it.  */
 
       if (yychar <= YYEOF)
@@ -2150,23 +2176,22 @@ yyerrlab:
          if (yychar == YYEOF)
             for (;;)
               {
+
                 YYPOPSTACK;
                 if (yyssp == yyss)
                   YYABORT;
-                YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
-                yydestruct (yystos[*yyssp], yyvsp);
+                yydestruct ("Error: popping",
+                             yystos[*yyssp], yyvsp);
               }
         }
       else
        {
-         YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
-         yydestruct (yytoken, &yylval);
+         yydestruct ("Error: discarding", yytoken, &yylval);
          yychar = YYEMPTY;
-
        }
     }
 
-  /* Else will try to reuse lookahead token after shifting the error
+  /* Else will try to reuse look-ahead token after shifting the error
      token.  */
   goto yyerrlab1;
 
@@ -2183,7 +2208,7 @@ yyerrorlab:
      goto yyerrorlab;
 #endif
 
-  yyvsp -= yylen;
+yyvsp -= yylen;
   yyssp -= yylen;
   yystate = *yyssp;
   goto yyerrlab1;
@@ -2213,8 +2238,8 @@ yyerrlab1:
       if (yyssp == yyss)
        YYABORT;
 
-      YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
-      yydestruct (yystos[yystate], yyvsp);
+
+      yydestruct ("Error: popping", yystos[yystate], yyvsp);
       YYPOPSTACK;
       yystate = *yyssp;
       YY_STACK_PRINT (yyss, yyssp);
@@ -2223,11 +2248,12 @@ yyerrlab1:
   if (yyn == YYFINAL)
     YYACCEPT;
 
-  YYDPRINTF ((stderr, "Shifting error token, "));
-
   *++yyvsp = yylval;
 
 
+  /* Shift the error token. */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
   yystate = yyn;
   goto yynewstate;
 
@@ -2243,6 +2269,9 @@ yyacceptlab:
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
 yyabortlab:
+  yydestruct ("Error: discarding lookahead",
+              yytoken, &yylval);
+  yychar = YYEMPTY;
   yyresult = 1;
   goto yyreturn;
 
index ad2ed3c4a2d2c7cd9ce4d0ebc184cdaf5e1cc165..76ff8755c96402ccd8e4c405b20704519526b273 100644 (file)
@@ -1,7 +1,7 @@
-/* A Bison parser, made by GNU Bison 1.875c.  */
+/* A Bison parser, made by GNU Bison 2.0.  */
 
 /* Skeleton parser for Yacc-like parsing with Bison,
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -224,7 +224,7 @@ typedef union YYSTYPE {
     struct tagtype tag;
     struct memhead *members;
 } YYSTYPE;
-/* Line 1275 of yacc.c.  */
+/* Line 1318 of yacc.c.  */
 #line 229 "parse.h"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
index 0376ca30bf0ec3cceae397fbac1b5e0813798c42..6a80934e46743a18d3cc7aad6379f565dcd35417 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "gssapi_locl.h"
 
-RCSID("$Id: init_sec_context.c,v 1.58 2005/07/13 07:00:15 lha Exp $");
+RCSID("$Id: init_sec_context.c,v 1.59 2005/08/11 10:47:25 lha Exp $");
 
 /*
  * copy the addresses from `input_chan_bindings' (if any) to
@@ -989,9 +989,6 @@ spnego_initial
     u_char *buf;
     size_t buf_size, buf_len;
     krb5_data data;
-#if 1
-    size_t ni_len;
-#endif
 
     memset (&ni, 0, sizeof(ni));
 
diff --git a/source4/heimdal/lib/hdb/ext.c b/source4/heimdal/lib/hdb/ext.c
new file mode 100644 (file)
index 0000000..850b23f
--- /dev/null
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2004 - 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 "hdb_locl.h"
+#include <der.h>
+
+RCSID("$Id: ext.c,v 1.1 2005/08/11 20:49:31 lha Exp $");
+
+krb5_error_code
+hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent)
+{
+    int i;
+
+    if (ent->extensions == NULL)
+       return 0;
+
+    /* 
+     * check for unknown extensions and if they where tagged mandatory
+     */
+
+    for (i = 0; i < ent->extensions->len; i++) {
+       if (ent->extensions->val[i].data.element != 
+           choice_HDB_extension_data_asn1_ellipsis)
+           continue;
+       if (ent->extensions->val[i].mandatory) {
+           krb5_set_error_string(context,  "Principal have unknown "
+                                 "mandatory extension");
+           return HDB_ERR_MANDATORY_OPTION;
+       }
+    }
+    return 0;
+}
+
+HDB_extension *
+hdb_find_extension(const hdb_entry *entry, int type)
+{
+    int i;
+
+    if (entry->extensions == NULL)
+       return NULL;
+
+    for (i = 0; i < entry->extensions->len; i++)
+       if (entry->extensions->val[i].data.element == type)
+           return &entry->extensions->val[i];
+    return NULL;
+}
+
+/*
+ * Replace the extension `ext' in `entry'. Make a copy of the
+ * extension, so the caller must still free `ext' on both success and
+ * failure. Returns 0 or error code.
+ */
+
+krb5_error_code
+hdb_replace_extension(krb5_context context, 
+                     hdb_entry *entry, 
+                     const HDB_extension *ext)
+{
+    HDB_extension *ext2;
+    HDB_extension *es;
+    int ret;
+
+    ext2 = NULL;
+
+    if (entry->extensions == NULL) {
+       entry->extensions = calloc(1, sizeof(*entry->extensions));
+       if (entry->extensions == NULL) {
+           krb5_set_error_string(context, "malloc: out of memory");
+           return ENOMEM;
+       }
+    } else if (ext->data.element != choice_HDB_extension_data_asn1_ellipsis) {
+       ext2 = hdb_find_extension(entry, ext->data.element);
+    } else {
+       /* 
+        * This is an unknown extention, and we are asked to replace a
+        * possible entry in `entry' that is of the same type. This
+        * might seem impossible, but ASN.1 CHOICE comes to our
+        * rescue. The first tag in each branch in the CHOICE is
+        * unique, so just find the element in the list that have the
+        * same tag was we are putting into the list.
+        */
+       Der_class replace_class, list_class;
+       Der_type replace_type, list_type;
+       unsigned int replace_tag, list_tag;
+       size_t size;
+       int i;
+
+       ret = der_get_tag(ext->data.u.asn1_ellipsis.data,
+                         ext->data.u.asn1_ellipsis.length,
+                         &replace_class, &replace_type, &replace_tag,
+                         &size);
+       if (ret) {
+           krb5_set_error_string(context, "hdb: failed to decode "
+                                 "replacement hdb extention");
+           return ret;
+       }
+
+       for (i = 0; i < entry->extensions->len; i++) {
+           HDB_extension *ext3 = &entry->extensions->val[i];
+
+           if (ext3->data.element != choice_HDB_extension_data_asn1_ellipsis)
+               continue;
+
+           ret = der_get_tag(ext3->data.u.asn1_ellipsis.data,
+                             ext3->data.u.asn1_ellipsis.length,
+                             &list_class, &list_type, &list_tag,
+                             &size);
+           if (ret) {
+               krb5_set_error_string(context, "hdb: failed to decode "
+                                     "present hdb extention");
+               return ret;
+           }
+
+           if (MAKE_TAG(replace_class,replace_type,replace_type) ==
+               MAKE_TAG(list_class,list_type,list_type)) {
+               ext2 = ext3;
+               break;
+           }
+       }
+    }
+
+    if (ext2) {
+       free_HDB_extension(ext2);
+       ret = copy_HDB_extension(ext, ext2);
+       if (ret)
+           krb5_set_error_string(context, "hdb: failed to copy replacement "
+                                 "hdb extention");
+       return ret;
+    }
+
+    es = realloc(entry->extensions->val, 
+                (entry->extensions->len+1)*sizeof(entry->extensions->val[0]));
+    if (es == NULL) {
+       krb5_set_error_string(context, "malloc: out of memory");
+       return ENOMEM;
+    }
+    entry->extensions->val = es;
+
+    ret = copy_HDB_extension(ext,
+                            &entry->extensions->val[entry->extensions->len]);
+    if (ret == 0) {
+       entry->extensions->len++;
+       krb5_set_error_string(context, "hdb: failed to copy new extension");
+    }
+
+    return ret;
+}
+
+krb5_error_code
+hdb_clear_extension(krb5_context context, 
+                   hdb_entry *entry, 
+                   int type)
+{
+    int i;
+
+    if (entry->extensions == NULL)
+       return 0;
+
+    for (i = 0; i < entry->extensions->len; i++) {
+       if (entry->extensions->val[i].data.element == type) {
+           free_HDB_extension(&entry->extensions->val[i]);
+           memmove(&entry->extensions->val[i],
+                   &entry->extensions->val[i + 1],
+                   sizeof(entry->extensions->val[i]) * (entry->extensions->len - i - 1));
+           entry->extensions->len--;
+       }
+    }
+    if (entry->extensions->len == 0) {
+       free(entry->extensions->val);
+       free(entry->extensions);
+       entry->extensions = NULL;
+    }
+
+    return 0;
+}
+
+
+krb5_error_code
+hdb_entry_get_pkinit_acl(const hdb_entry *entry, const HDB_Ext_PKINIT_acl **a)
+{
+    const HDB_extension *ext;
+
+    ext = hdb_find_extension(entry, choice_HDB_extension_data_pkinit_acl);
+    if (ext)
+       *a = &ext->data.u.pkinit_acl;
+    else
+       *a = NULL;
+
+    return 0;
+}
+
+krb5_error_code
+hdb_entry_get_pw_change_time(const hdb_entry *entry, time_t *t)
+{
+    const HDB_extension *ext;
+
+    ext = hdb_find_extension(entry, choice_HDB_extension_data_last_pw_change);
+    if (ext)
+       *t = ext->data.u.last_pw_change;
+    else
+       *t = 0;
+
+    return 0;
+}
+
+krb5_error_code
+hdb_entry_set_pw_change_time(krb5_context context, 
+                            hdb_entry *entry,
+                            time_t t)
+{
+    HDB_extension ext;
+
+    ext.mandatory = FALSE;
+    ext.data.element = choice_HDB_extension_data_last_pw_change;
+    if (t == 0)
+       t = time(NULL);
+    ext.data.u.last_pw_change = t;
+
+    return hdb_replace_extension(context, entry, &ext);
+}
+
+int
+hdb_entry_get_password(krb5_context context, HDB *db, 
+                      const hdb_entry *entry, char **p)
+{
+    HDB_extension *ext;
+    int ret;
+
+    ext = hdb_find_extension(entry, choice_HDB_extension_data_password);
+    if (ext) {
+       heim_utf8_string str;
+       heim_octet_string pw;
+
+       if (db->hdb_master_key_set && ext->data.u.password.mkvno) {
+           hdb_master_key key;
+
+           key = _hdb_find_master_key(ext->data.u.password.mkvno, 
+                                      db->hdb_master_key);
+
+           if (key == NULL) {
+               krb5_set_error_string(context, "master key %d missing",
+                                     *ext->data.u.password.mkvno);
+               return HDB_ERR_NO_MKEY;
+           }
+
+           ret = _hdb_mkey_decrypt(context, key, HDB_KU_MKEY,
+                                   ext->data.u.password.password.data,
+                                   ext->data.u.password.password.length,
+                                   &pw);
+       } else {
+           ret = copy_octet_string(&ext->data.u.password.password, &pw);
+       }
+       if (ret) {
+           krb5_clear_error_string(context);
+           return ret;
+       }
+
+       str = pw.data;
+       if (str[pw.length - 1] != '\0') {
+           krb5_set_error_string(context, "password malformated");
+           return EINVAL;
+       }
+
+       *p = strdup(str);
+
+       free_octet_string(&pw);
+       if (*p == NULL) {
+           krb5_set_error_string(context, "malloc: out of memory");
+           return ENOMEM;
+       }
+       return 0;
+    }
+    krb5_set_error_string(context, "password attribute not found");
+    return ENOENT;
+}
+
+int
+hdb_entry_set_password(krb5_context context, HDB *db, 
+                      hdb_entry *entry, const char *p)
+{
+    HDB_extension ext;
+    hdb_master_key key;
+    int ret;
+
+    ext.mandatory = FALSE;
+    ext.data.element = choice_HDB_extension_data_password;
+
+    if (db->hdb_master_key_set) {
+
+       key = _hdb_find_master_key(NULL, db->hdb_master_key);
+       if (key == NULL) {
+           krb5_set_error_string(context, "hdb_entry_set_password: "
+                                 "failed to find masterkey");
+           return HDB_ERR_NO_MKEY;
+       }
+
+       ret = _hdb_mkey_encrypt(context, key, HDB_KU_MKEY,
+                               p, strlen(p) + 1, 
+                               &ext.data.u.password.password);
+       if (ret)
+           return ret;
+
+       ext.data.u.password.mkvno = 
+           malloc(sizeof(*ext.data.u.password.mkvno));
+       if (ext.data.u.password.mkvno == NULL) {
+           free_HDB_extension(&ext);
+           krb5_set_error_string(context, "malloc: out of memory");
+           return ENOMEM;
+       }
+       *ext.data.u.password.mkvno = _hdb_mkey_version(key);
+
+    } else {
+       ext.data.u.password.mkvno = NULL;
+
+       ret = krb5_data_copy(&ext.data.u.password.password, 
+                            p, strlen(p) + 1);
+       if (ret) {
+           krb5_set_error_string(context, "malloc: out of memory");
+           free_HDB_extension(&ext);
+           return ret;
+       }
+    }
+
+    ret = hdb_replace_extension(context, entry, &ext);
+
+    free_HDB_extension(&ext);
+
+    return ret;
+}
+
+int
+hdb_entry_clear_password(krb5_context context, hdb_entry *entry)
+{
+    return hdb_clear_extension(context, entry, 
+                              choice_HDB_extension_data_password);
+}
index a2b96bb0472a2960162377e7e1354c636fc3becc..7baa944053509997f766bf61d57e66a6d12a0bae 100644 (file)
@@ -9,10 +9,36 @@ _hdb_fetch (
        krb5_context /*context*/,
        HDB */*db*/,
        unsigned /*flags*/,
-       krb5_principal /*principal*/,
+       krb5_const_principal /*principal*/,
        enum hdb_ent_type /*ent_type*/,
        hdb_entry */*entry*/);
 
+hdb_master_key
+_hdb_find_master_key (
+       u_int32_t */*mkvno*/,
+       hdb_master_key /*mkey*/);
+
+int
+_hdb_mkey_decrypt (
+       krb5_context /*context*/,
+       hdb_master_key /*key*/,
+       krb5_key_usage /*usage*/,
+       void */*ptr*/,
+       size_t /*size*/,
+       krb5_data */*res*/);
+
+int
+_hdb_mkey_encrypt (
+       krb5_context /*context*/,
+       hdb_master_key /*key*/,
+       krb5_key_usage /*usage*/,
+       const void */*ptr*/,
+       size_t /*size*/,
+       krb5_data */*res*/);
+
+int
+_hdb_mkey_version (hdb_master_key /*mkey*/);
+
 krb5_error_code
 _hdb_remove (
        krb5_context /*context*/,
index 886d48e5bd01f4044b55aa3a761eb93b128a9f3f..799f013eba0775997ce20bd1f56c99998fef2389 100644 (file)
@@ -19,6 +19,12 @@ hdb_check_db_format (
        krb5_context /*context*/,
        HDB */*db*/);
 
+krb5_error_code
+hdb_clear_extension (
+       krb5_context /*context*/,
+       hdb_entry */*entry*/,
+       int /*type*/);
+
 krb5_error_code
 hdb_clear_master_key (
        krb5_context /*context*/,
@@ -55,6 +61,51 @@ hdb_entry2value (
        hdb_entry */*ent*/,
        krb5_data */*value*/);
 
+krb5_error_code
+hdb_entry_check_mandatory (
+       krb5_context /*context*/,
+       const hdb_entry */*ent*/);
+
+int
+hdb_entry_clear_password (
+       krb5_context /*context*/,
+       hdb_entry */*entry*/);
+
+int
+hdb_entry_get_password (
+       krb5_context /*context*/,
+       HDB */*db*/,
+       const hdb_entry */*entry*/,
+       char **/*p*/);
+
+krb5_error_code
+hdb_entry_get_pkinit_acl (
+       const hdb_entry */*entry*/,
+       const HDB_Ext_PKINIT_acl **/*a*/);
+
+krb5_error_code
+hdb_entry_get_pw_change_time (
+       const hdb_entry */*entry*/,
+       time_t */*t*/);
+
+int
+hdb_entry_set_password (
+       krb5_context /*context*/,
+       HDB */*db*/,
+       hdb_entry */*entry*/,
+       const char */*p*/);
+
+krb5_error_code
+hdb_entry_set_pw_change_time (
+       krb5_context /*context*/,
+       hdb_entry */*entry*/,
+       time_t /*t*/);
+
+HDB_extension *
+hdb_find_extension (
+       const hdb_entry */*entry*/,
+       int /*type*/);
+
 krb5_error_code
 hdb_foreach (
        krb5_context /*context*/,
@@ -141,7 +192,7 @@ hdb_next_enctype2key (
 int
 hdb_principal2key (
        krb5_context /*context*/,
-       krb5_principal /*p*/,
+       krb5_const_principal /*p*/,
        krb5_data */*key*/);
 
 krb5_error_code
@@ -165,6 +216,12 @@ hdb_read_master_key (
        const char */*filename*/,
        hdb_master_key */*mkey*/);
 
+krb5_error_code
+hdb_replace_extension (
+       krb5_context /*context*/,
+       hdb_entry */*entry*/,
+       const HDB_extension */*ext*/);
+
 krb5_error_code
 hdb_seal_key (
        krb5_context /*context*/,
index 770acf4dce05fbc3a68f85898297b654fef9d0e0..c8a1a34b4f646d63d3e8e7910136e47e0ca5afd1 100644 (file)
@@ -1,4 +1,4 @@
--- $Id: hdb.asn1,v 1.12 2004/11/10 18:50:27 lha Exp $
+-- $Id: hdb.asn1,v 1.13 2005/08/11 13:15:44 lha Exp $
 HDB DEFINITIONS ::=
 BEGIN
 
@@ -50,6 +50,51 @@ GENERATION ::= SEQUENCE {
        gen[2]          INTEGER (0..4294967295)         -- generation number
 }
 
+HDB-Ext-PKINIT-acl ::= SEQUENCE OF SEQUENCE {
+       subject[0]      UTF8String,
+       issuer[1]       UTF8String
+}
+
+HDB-Ext-PKINIT-certificate ::= SEQUENCE OF OCTET STRING
+
+HDB-Ext-Constrained-delegation-acl ::= SEQUENCE OF Principal
+
+-- hdb-ext-referrals ::= PA-SERVER-REFERRAL-DATA
+
+HDB-Ext-Lan-Manager-OWF ::= OCTET STRING
+
+HDB-Ext-Password ::= SEQUENCE {
+       mkvno[0]        INTEGER (0..4294967295) OPTIONAL, -- master key version number
+       password        OCTET STRING
+}
+
+HDB-Ext-Aliases ::= SEQUENCE {
+       case-insensitive[0]     BOOLEAN, -- case insensitive name allowed
+       aliases[1]              SEQUENCE OF Principal -- all names, inc primary
+}
+
+
+HDB-extension ::= SEQUENCE {
+        mandatory[0]    BOOLEAN,        -- kdc MUST understand this extension,
+                                        --   if not the whole entry must
+                                        --   be rejected
+        data[1]          CHOICE {
+               pkinit-acl[0]                   HDB-Ext-PKINIT-acl,
+               pkinit-cert[1]                  HDB-Ext-PKINIT-certificate,
+               allowed-to-delegate-to[2]   HDB-Ext-Constrained-delegation-acl,
+--             referral-info[3]                HDB-Ext-Referrals,
+               lm-owf[4]                       HDB-Ext-Lan-Manager-OWF,
+               password[5]                     HDB-Ext-Password,
+               aliases[6]                      HDB-Ext-Aliases,
+               last-pw-change[7]               KerberosTime,
+               ...
+       },
+       ...
+}
+
+HDB-extensions ::= SEQUENCE OF HDB-extension
+
+
 hdb_entry ::= SEQUENCE {
        principal[0]    Principal  OPTIONAL, -- this is optional only 
                                             -- for compatibility with libkrb5
@@ -64,7 +109,8 @@ hdb_entry ::= SEQUENCE {
        max-renew[9]    INTEGER (0..4294967295) OPTIONAL,
        flags[10]       HDBFlags,
        etypes[11]      SEQUENCE OF INTEGER (0..4294967295) OPTIONAL,
-       generation[12]  GENERATION OPTIONAL
+       generation[12]  GENERATION OPTIONAL,
+        extensions[13]  HDB-extensions OPTIONAL
 }
 
 END
index 481d4ea93d6d42197d582f37f48b40726b6a7f36..fe86f0ae722fa38484a105b0efaec52365e1200a 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. 
  *
  * SUCH DAMAGE. 
  */
 
-/* $Id: hdb.h,v 1.33 2003/09/19 00:19:36 lha Exp $ */
+/* $Id: hdb.h,v 1.35 2005/08/11 13:16:44 lha Exp $ */
 
 #ifndef __HDB_H__
 #define __HDB_H__
 
 #include <hdb_err.h>
 
+#include <heim_asn1.h>
 #include <hdb_asn1.h>
 
 enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
 
 /* flags for various functions */
-#define HDB_F_DECRYPT  1 /* decrypt keys */
-#define HDB_F_REPLACE  2 /* replace entry */
+#define HDB_F_DECRYPT          1 /* decrypt keys */
+#define HDB_F_REPLACE          2 /* replace entry */
 
 /* key usage for master key */
 #define HDB_KU_MKEY    0x484442
@@ -68,20 +69,20 @@ typedef struct HDB{
     krb5_error_code (*hdb_store)(krb5_context,struct HDB*,unsigned,hdb_entry*);
     krb5_error_code (*hdb_remove)(krb5_context, struct HDB*, hdb_entry*);
     krb5_error_code (*hdb_firstkey)(krb5_context, struct HDB*, 
-                               unsigned, hdb_entry*);
+                                   unsigned, hdb_entry*);
     krb5_error_code (*hdb_nextkey)(krb5_context, struct HDB*, 
-                              unsigned, hdb_entry*);
+                                  unsigned, hdb_entry*);
     krb5_error_code (*hdb_lock)(krb5_context, struct HDB*, int operation);
     krb5_error_code (*hdb_unlock)(krb5_context, struct HDB*);
     krb5_error_code (*hdb_rename)(krb5_context, struct HDB*, const char*);
     krb5_error_code (*hdb__get)(krb5_context,struct HDB*,krb5_data,krb5_data*);
     krb5_error_code (*hdb__put)(krb5_context, struct HDB*, int, 
-                           krb5_data, krb5_data);
+                               krb5_data, krb5_data);
     krb5_error_code (*hdb__del)(krb5_context, struct HDB*, krb5_data);
     krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*);
 }HDB;
 
-#define HDB_INTERFACE_VERSION  1
+#define HDB_INTERFACE_VERSION  2
 
 struct hdb_so_method {
     int version;
index 9929a56311e568300844af147c7873e732ae8b49..f2636b2fea74178df46644ad665e14d3b0c32ba3 100644 (file)
@@ -3,7 +3,7 @@
 #
 # This might look like a com_err file, but is not
 #
-id "$Id: hdb_err.et,v 1.5 2001/01/28 23:05:52 assar Exp $"
+id "$Id: hdb_err.et,v 1.6 2005/08/11 13:17:22 lha Exp $"
 
 error_table hdb
 
@@ -23,5 +23,6 @@ error_code CANT_LOCK_DB,      "Insufficient access to lock database"
 error_code EXISTS,             "Entry already exists in database"
 error_code BADVERSION,         "Wrong database version"
 error_code NO_MKEY,            "No correct master key"
+error_code MANDATORY_OPTION,   "Entry contains unknown mandatory extension"
 
 end
diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c
new file mode 100644 (file)
index 0000000..9e04dc6
--- /dev/null
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 2000 - 2004 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 "hdb_locl.h"
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+RCSID("$Id: mkey.c,v 1.20 2005/08/10 08:41:03 lha Exp $");
+
+struct hdb_master_key_data {
+    krb5_keytab_entry keytab;
+    krb5_crypto crypto;
+    struct hdb_master_key_data *next;
+};
+
+void
+hdb_free_master_key(krb5_context context, hdb_master_key mkey)
+{
+    struct hdb_master_key_data *ptr;
+    while(mkey) {
+       krb5_kt_free_entry(context, &mkey->keytab);
+       if (mkey->crypto)
+           krb5_crypto_destroy(context, mkey->crypto);
+       ptr = mkey;
+       mkey = mkey->next;
+       free(ptr);
+    }
+}
+
+krb5_error_code
+hdb_process_master_key(krb5_context context,
+                      int kvno, krb5_keyblock *key, krb5_enctype etype,
+                      hdb_master_key *mkey)
+{
+    krb5_error_code ret;
+
+    *mkey = calloc(1, sizeof(**mkey));
+    if(*mkey == NULL) {
+       krb5_set_error_string(context, "malloc: out of memory");
+       return ENOMEM;
+    }
+    (*mkey)->keytab.vno = kvno;
+    ret = krb5_parse_name(context, "K/M", &(*mkey)->keytab.principal);
+    if(ret)
+       goto fail;
+    ret = krb5_copy_keyblock_contents(context, key, &(*mkey)->keytab.keyblock);
+    if(ret)
+       goto fail;
+    if(etype != 0)
+       (*mkey)->keytab.keyblock.keytype = etype;
+    (*mkey)->keytab.timestamp = time(NULL);
+    ret = krb5_crypto_init(context, key, etype, &(*mkey)->crypto);
+    if(ret)
+       goto fail;
+    return 0;
+ fail:
+    hdb_free_master_key(context, *mkey);
+    *mkey = NULL;
+    return ret;
+}
+
+krb5_error_code
+hdb_add_master_key(krb5_context context, krb5_keyblock *key,
+                  hdb_master_key *inout)
+{
+    int vno = 0;
+    hdb_master_key p;
+    krb5_error_code ret;
+
+    for(p = *inout; p; p = p->next)
+       vno = max(vno, p->keytab.vno);
+    vno++;
+    ret = hdb_process_master_key(context, vno, key, 0, &p);
+    if(ret)
+       return ret;
+    p->next = *inout;
+    *inout = p;
+    return 0;
+}
+
+static krb5_error_code
+read_master_keytab(krb5_context context, const char *filename, 
+                  hdb_master_key *mkey)
+{
+    krb5_error_code ret;
+    krb5_keytab id;
+    krb5_kt_cursor cursor;
+    krb5_keytab_entry entry;
+    hdb_master_key p;
+    
+    ret = krb5_kt_resolve(context, filename, &id);
+    if(ret)
+       return ret;
+
+    ret = krb5_kt_start_seq_get(context, id, &cursor);
+    if(ret)
+       goto out;
+    *mkey = NULL;
+    while(krb5_kt_next_entry(context, id, &entry, &cursor) == 0) {
+       p = calloc(1, sizeof(*p));
+       p->keytab = entry;
+       ret = krb5_crypto_init(context, &p->keytab.keyblock, 0, &p->crypto);
+       p->next = *mkey;
+       *mkey = p;
+    }
+    krb5_kt_end_seq_get(context, id, &cursor);
+  out:
+    krb5_kt_close(context, id);
+    return ret;
+}
+
+/* read a MIT master keyfile */
+static krb5_error_code
+read_master_mit(krb5_context context, const char *filename, 
+               hdb_master_key *mkey)
+{
+    int fd;
+    krb5_error_code ret;
+    krb5_storage *sp;
+    int16_t enctype;
+    krb5_keyblock key;
+              
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if(fd < 0) {
+       int save_errno = errno;
+       krb5_set_error_string(context, "failed to open %s: %s", filename,
+                             strerror(save_errno));
+       return save_errno;
+    }
+    sp = krb5_storage_from_fd(fd);
+    if(sp == NULL) {
+       close(fd);
+       return errno;
+    }
+    krb5_storage_set_flags(sp, KRB5_STORAGE_HOST_BYTEORDER);
+#if 0
+    /* could possibly use ret_keyblock here, but do it with more
+       checks for now */
+    ret = krb5_ret_keyblock(sp, &key);
+#else
+    ret = krb5_ret_int16(sp, &enctype);
+    if((htons(enctype) & 0xff00) == 0x3000) {
+       krb5_set_error_string(context, "unknown keytype in %s: %#x, expected %#x", 
+                             filename, htons(enctype), 0x3000);
+       ret = HEIM_ERR_BAD_MKEY;
+       goto out;
+    }
+    key.keytype = enctype;
+    ret = krb5_ret_data(sp, &key.keyvalue);
+    if(ret)
+       goto out;
+#endif
+    ret = hdb_process_master_key(context, 0, &key, 0, mkey);
+    krb5_free_keyblock_contents(context, &key);
+  out:
+    krb5_storage_free(sp);
+    close(fd);
+    return ret;
+}
+
+/* read an old master key file */
+static krb5_error_code
+read_master_encryptionkey(krb5_context context, const char *filename, 
+                         hdb_master_key *mkey)
+{
+    int fd;
+    krb5_keyblock key;
+    krb5_error_code ret;
+    unsigned char buf[256];
+    ssize_t len;
+    size_t ret_len;
+              
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if(fd < 0) {
+       int save_errno = errno;
+       krb5_set_error_string(context, "failed to open %s: %s", 
+                             filename, strerror(save_errno));
+       return save_errno;
+    }
+    
+    len = read(fd, buf, sizeof(buf));
+    close(fd);
+    if(len < 0) {
+       int save_errno = errno;
+       krb5_set_error_string(context, "error reading %s: %s", 
+                             filename, strerror(save_errno));
+       return save_errno;
+    }
+
+    ret = decode_EncryptionKey(buf, len, &key, &ret_len);
+    memset(buf, 0, sizeof(buf));
+    if(ret)
+       return ret;
+
+    /* Originally, the keytype was just that, and later it got changed
+       to des-cbc-md5, but we always used des in cfb64 mode. This
+       should cover all cases, but will break if someone has hacked
+       this code to really use des-cbc-md5 -- but then that's not my
+       problem. */
+    if(key.keytype == KEYTYPE_DES || key.keytype == ETYPE_DES_CBC_MD5)
+       key.keytype = ETYPE_DES_CFB64_NONE;
+    
+    ret = hdb_process_master_key(context, 0, &key, 0, mkey);
+    krb5_free_keyblock_contents(context, &key);
+    return ret;
+}
+
+/* read a krb4 /.k style file */
+static krb5_error_code
+read_master_krb4(krb5_context context, const char *filename, 
+                hdb_master_key *mkey)
+{
+    int fd;
+    krb5_keyblock key;
+    krb5_error_code ret;
+    unsigned char buf[256];
+    ssize_t len;
+              
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if(fd < 0) {
+       int save_errno = errno;
+       krb5_set_error_string(context, "failed to open %s: %s", 
+                             filename, strerror(save_errno));
+       return save_errno;
+    }
+    
+    len = read(fd, buf, sizeof(buf));
+    close(fd);
+    if(len < 0) {
+       int save_errno = errno;
+       krb5_set_error_string(context, "error reading %s: %s", 
+                             filename, strerror(save_errno));
+       return save_errno;
+    }
+    if(len != 8) {
+       krb5_set_error_string(context, "bad contents of %s", filename);
+       return HEIM_ERR_EOF; /* XXX file might be too large */
+    }
+
+    memset(&key, 0, sizeof(key));
+    key.keytype = ETYPE_DES_PCBC_NONE;
+    ret = krb5_data_copy(&key.keyvalue, buf, len);
+    memset(buf, 0, sizeof(buf));
+    if(ret) 
+       return ret;
+
+    ret = hdb_process_master_key(context, 0, &key, 0, mkey);
+    krb5_free_keyblock_contents(context, &key);
+    return ret;
+}
+
+krb5_error_code
+hdb_read_master_key(krb5_context context, const char *filename, 
+                   hdb_master_key *mkey)
+{
+    FILE *f;
+    unsigned char buf[16];
+    krb5_error_code ret;
+
+    off_t len;
+
+    *mkey = NULL;
+
+    if(filename == NULL)
+       filename = HDB_DB_DIR "/m-key";
+
+    f = fopen(filename, "r");
+    if(f == NULL) {
+       int save_errno = errno;
+       krb5_set_error_string(context, "failed to open %s: %s", 
+                             filename, strerror(save_errno));
+       return save_errno;
+    }
+    
+    if(fread(buf, 1, 2, f) != 2) {
+       krb5_set_error_string(context, "end of file reading %s", filename);
+       fclose(f);
+       return HEIM_ERR_EOF;
+    }
+    
+    fseek(f, 0, SEEK_END);
+    len = ftell(f);
+
+    if(fclose(f) != 0)
+       return errno;
+    
+    if(len < 0)
+       return errno;
+    
+    if(len == 8) {
+       ret = read_master_krb4(context, filename, mkey);
+    } else if(buf[0] == 0x30 && len <= 127 && buf[1] == len - 2) {
+       ret = read_master_encryptionkey(context, filename, mkey);
+    } else if(buf[0] == 5 && buf[1] >= 1 && buf[1] <= 2) {
+       ret = read_master_keytab(context, filename, mkey);
+    } else {
+       ret = read_master_mit(context, filename, mkey);
+    }
+    return ret;
+}
+
+krb5_error_code
+hdb_write_master_key(krb5_context context, const char *filename, 
+                    hdb_master_key mkey)
+{
+    krb5_error_code ret;
+    hdb_master_key p;
+    krb5_keytab kt;
+
+    if(filename == NULL)
+       filename = HDB_DB_DIR "/m-key";
+
+    ret = krb5_kt_resolve(context, filename, &kt);
+    if(ret)
+       return ret;
+
+    for(p = mkey; p; p = p->next) {
+       ret = krb5_kt_add_entry(context, kt, &p->keytab);
+    }
+
+    krb5_kt_close(context, kt);
+
+    return ret;
+}
+
+hdb_master_key
+_hdb_find_master_key(u_int32_t *mkvno, hdb_master_key mkey)
+{
+    hdb_master_key ret = NULL;
+    while(mkey) {
+       if(ret == NULL && mkey->keytab.vno == 0)
+           ret = mkey;
+       if(mkvno == NULL) {
+           if(ret == NULL || mkey->keytab.vno > ret->keytab.vno)
+               ret = mkey;
+       } else if(mkey->keytab.vno == *mkvno)
+           return mkey;
+       mkey = mkey->next;
+    }
+    return ret;
+}
+
+int
+_hdb_mkey_version(hdb_master_key mkey)
+{
+    return mkey->keytab.vno;
+}
+
+int
+_hdb_mkey_decrypt(krb5_context context, hdb_master_key key,
+                 krb5_key_usage usage,
+                 void *ptr, size_t size, krb5_data *res)
+{
+    return krb5_decrypt(context, key->crypto, usage,
+                       ptr, size, res);
+}
+
+int
+_hdb_mkey_encrypt(krb5_context context, hdb_master_key key,
+                 krb5_key_usage usage,
+                 const void *ptr, size_t size, krb5_data *res)
+{
+    return krb5_encrypt(context, key->crypto, usage,
+                       ptr, size, res);
+}
+
+krb5_error_code
+hdb_unseal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) 
+{
+       
+    krb5_error_code ret;
+    krb5_data res;
+    size_t keysize;
+
+    hdb_master_key key;
+
+    if(k->mkvno == NULL)
+       return 0;
+       
+    key = _hdb_find_master_key(k->mkvno, mkey);
+
+    if (key == NULL)
+       return HDB_ERR_NO_MKEY;
+
+    ret = _hdb_mkey_decrypt(context, key, HDB_KU_MKEY,
+                           k->key.keyvalue.data,
+                           k->key.keyvalue.length,
+                           &res);
+    if(ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+       /* try to decrypt with MIT key usage */
+       ret = _hdb_mkey_decrypt(context, key, 0,
+                               k->key.keyvalue.data,
+                               k->key.keyvalue.length,
+                               &res);
+    }    
+    if (ret)
+       return ret;
+
+    /* fixup keylength if the key got padded when encrypting it */
+    ret = krb5_enctype_keysize(context, k->key.keytype, &keysize);
+    if (ret) {
+       krb5_data_free(&res);
+       return ret;
+    }
+    if (keysize > res.length) {
+       krb5_data_free(&res);
+       return KRB5_BAD_KEYSIZE;
+    }
+
+    memset(k->key.keyvalue.data, 0, k->key.keyvalue.length);
+    free(k->key.keyvalue.data);
+    k->key.keyvalue = res;
+    k->key.keyvalue.length = keysize;
+    free(k->mkvno);
+    k->mkvno = NULL;
+
+    return 0;
+}
+
+krb5_error_code
+hdb_unseal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey)
+{
+    int i;
+
+    for(i = 0; i < ent->keys.len; i++){
+       krb5_error_code ret;
+
+       ret = hdb_unseal_key_mkey(context, &ent->keys.val[i], mkey);
+       if (ret) 
+           return ret;
+    }
+    return 0;
+}
+
+krb5_error_code
+hdb_unseal_keys(krb5_context context, HDB *db, hdb_entry *ent)
+{
+    if (db->hdb_master_key_set == 0)
+       return 0;
+    return hdb_unseal_keys_mkey(context, ent, db->hdb_master_key);
+}
+
+krb5_error_code
+hdb_unseal_key(krb5_context context, HDB *db, Key *k)
+{
+    if (db->hdb_master_key_set == 0)
+       return 0;
+    return hdb_unseal_key_mkey(context, k, db->hdb_master_key);
+}
+
+krb5_error_code
+hdb_seal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey)
+{
+    krb5_error_code ret;
+    krb5_data res;
+    hdb_master_key key;
+
+    key = _hdb_find_master_key(k->mkvno, mkey);
+
+    if (key == NULL)
+       return HDB_ERR_NO_MKEY;
+
+    ret = _hdb_mkey_encrypt(context, key, HDB_KU_MKEY,
+                           k->key.keyvalue.data,
+                           k->key.keyvalue.length,
+                           &res);
+    if (ret)
+       return ret;
+
+    memset(k->key.keyvalue.data, 0, k->key.keyvalue.length);
+    free(k->key.keyvalue.data);
+    k->key.keyvalue = res;
+
+    if (k->mkvno == NULL) {
+       k->mkvno = malloc(sizeof(*k->mkvno));
+       if (k->mkvno == NULL)
+           return ENOMEM;
+    }
+    *k->mkvno = key->keytab.vno;
+       
+    return 0;
+}
+
+krb5_error_code
+hdb_seal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey)
+{
+    int i;
+    for(i = 0; i < ent->keys.len; i++){
+       krb5_error_code ret;
+
+       ret = hdb_seal_key_mkey(context, &ent->keys.val[i], mkey);
+       if (ret)
+           return ret;
+    }
+    return 0;
+}
+
+krb5_error_code
+hdb_seal_keys(krb5_context context, HDB *db, hdb_entry *ent)
+{
+    if (db->hdb_master_key_set == 0)
+       return 0;
+    
+    return hdb_seal_keys_mkey(context, ent, db->hdb_master_key);
+}
+
+krb5_error_code
+hdb_seal_key(krb5_context context, HDB *db, Key *k)
+{
+    if (db->hdb_master_key_set == 0)
+       return 0;
+    
+    return hdb_seal_key_mkey(context, k, db->hdb_master_key);
+}
+
+krb5_error_code
+hdb_set_master_key (krb5_context context,
+                   HDB *db,
+                   krb5_keyblock *key)
+{
+    krb5_error_code ret;
+    hdb_master_key mkey;
+
+    ret = hdb_process_master_key(context, 0, key, 0, &mkey);
+    if (ret)
+       return ret;
+    db->hdb_master_key = mkey;
+#if 0 /* XXX - why? */
+    des_set_random_generator_seed(key.keyvalue.data);
+#endif
+    db->hdb_master_key_set = 1;
+    return 0;
+}
+
+krb5_error_code
+hdb_set_master_keyfile (krb5_context context,
+                       HDB *db,
+                       const char *keyfile)
+{
+    hdb_master_key key;
+    krb5_error_code ret;
+
+    ret = hdb_read_master_key(context, keyfile, &key);
+    if (ret) {
+       if (ret != ENOENT)
+           return ret;
+       krb5_clear_error_string(context);
+       return 0;
+    }
+    db->hdb_master_key = key;
+    db->hdb_master_key_set = 1;
+    return ret;
+}
+
+krb5_error_code
+hdb_clear_master_key (krb5_context context,
+                     HDB *db)
+{
+    if (db->hdb_master_key_set) {
+       hdb_free_master_key(context, db->hdb_master_key);
+       db->hdb_master_key_set = 0;
+    }
+    return 0;
+}
index c8fa556696d21cc5cd590c25f624a3a7797743f1..1c3e8d2a10b3e8e610d871243fb81726ea08e1cd 100644 (file)
@@ -2124,8 +2124,7 @@ verify_checksum(krb5_context context,
        return KRB5_PROG_SUMTYPE_NOSUPP;
     }
     if(ct->checksumsize != cksum->checksum.length) {
-       krb5_set_error_string (context, "checksum length was %d, but should be %d for checksum type %s",
-                              cksum->checksum.length, ct->checksumsize, ct->name);
+       krb5_clear_error_string (context);
        return KRB5KRB_AP_ERR_BAD_INTEGRITY; /* XXX */
     }
     keyed_checksum = (ct->flags & F_KEYED) != 0;
@@ -2146,11 +2145,8 @@ verify_checksum(krb5_context context,
 
     (*ct->checksum)(context, dkey, data, len, usage, &c);
 
-    if(c.checksum.length != cksum->checksum.length) {
-       krb5_set_error_string (context, "(INTERNAL ERROR) our checksum length was %d, but should be %d for checksum type %s",
-                              c.checksum.length, ct->checksumsize, ct->name);
-       ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-    } else if (memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) {
+    if(c.checksum.length != cksum->checksum.length || 
+       memcmp(c.checksum.data, cksum->checksum.data, c.checksum.length)) {
        krb5_clear_error_string (context);
        ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
     } else {
index 03848abb9ad5ade34c51d05d7552eef635650120..f8ebe837b7137d14e9b5de07ee8e7a2a31e7406c 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: fcache.c,v 1.49 2005/06/16 20:25:20 lha Exp $");
+RCSID("$Id: fcache.c,v 1.51 2005/08/12 13:31:19 lha Exp $");
 
 typedef struct krb5_fcache{
     char *filename;
index 8b3975f418085bd4c196bf0a352878b9f2e07148..8fd5c4611facae12843b5fd94c28321ea8b3f82f 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 "krb5_locl.h"
 
-RCSID("$Id: init_creds_pw.c,v 1.87 2005/06/17 04:15:20 lha Exp $");
+RCSID("$Id: init_creds_pw.c,v 1.88 2005/08/13 08:25:32 lha Exp $");
 
 typedef struct krb5_get_init_creds_ctx {
     krb5_kdc_flags flags;
@@ -45,6 +45,7 @@ typedef struct krb5_get_init_creds_ctx {
     unsigned nonce;
     unsigned pk_nonce;
 
+    krb5_data req_buffer;
     AS_REQ as_req;
     int pa_counter;
 
@@ -1158,6 +1159,7 @@ process_pa_data_to_key(krb5_context context,
                                   ctx->pk_init_ctx,
                                   etype,
                                   ctx->pk_nonce,
+                                  &ctx->req_buffer,
                                   pa,
                                   key);
 #else
@@ -1218,7 +1220,6 @@ init_cred_loop(krb5_context context,
 
     ctx->pa_counter = 0;
     while (ctx->pa_counter < MAX_PA_COUNTER) {
-       krb5_data req;
 
        ctx->pa_counter++;
 
@@ -1237,17 +1238,20 @@ init_cred_loop(krb5_context context,
                                    prompter, prompter_data);
        if (ret)
            goto out;
-       ASN1_MALLOC_ENCODE(AS_REQ, req.data, req.length, 
+
+       krb5_data_free(&ctx->req_buffer);
+
+       ASN1_MALLOC_ENCODE(AS_REQ, 
+                          ctx->req_buffer.data, ctx->req_buffer.length, 
                           &ctx->as_req, &len, ret);
        if (ret)
            goto out;
-       if(len != req.length)
+       if(len != ctx->req_buffer.length)
            krb5_abortx(context, "internal error in ASN.1 encoder");
 
-       ret = krb5_sendto_kdc_flags (context, &req
+       ret = krb5_sendto_kdc_flags (context, &ctx->req_buffer
                                     &creds->client->realm, &resp,
                                     send_to_kdc_flags);
-       krb5_data_free(&req);
        if (ret)
            goto out;
 
@@ -1336,6 +1340,7 @@ init_cred_loop(krb5_context context,
        krb5_free_keyblock(context, key);
     }
 out:
+    krb5_data_free(&ctx->req_buffer);
     free_METHOD_DATA(&md);
     memset(&md, 0, sizeof(md));
 
index b877de8cf25966651337a8afeb571bf2f9daa50e..e70527845bdf8a89ff86b500069dee707a3dcf47 100644 (file)
@@ -293,6 +293,16 @@ _krb5_pk_mk_padata (
        unsigned /*nonce*/,
        METHOD_DATA */*md*/);
 
+krb5_error_code
+_krb5_pk_octetstring2key (
+       krb5_context /*context*/,
+       krb5_enctype /*type*/,
+       const void */*dhdata*/,
+       size_t /*dhsize*/,
+       const heim_octet_string */*c_n*/,
+       const heim_octet_string */*k_n*/,
+       krb5_keyblock */*key*/);
+
 krb5_error_code KRB5_LIB_FUNCTION
 _krb5_pk_rd_pa_reply (
        krb5_context /*context*/,
index f306bf949f05fff4aa709ed7522750069956f4f9..2750c8b5d2bc76f0cd5dc7e8a74649e438710725 100644 (file)
@@ -3251,6 +3251,14 @@ krb5_verify_init_creds_opt_set_ap_req_nofail (
        krb5_verify_init_creds_opt */*options*/,
        int /*ap_req_nofail*/);
 
+int KRB5_LIB_FUNCTION
+krb5_verify_opt_alloc (
+       krb5_context /*context*/,
+       krb5_verify_opt **/*opt*/);
+
+void KRB5_LIB_FUNCTION
+krb5_verify_opt_free (krb5_verify_opt */*opt*/);
+
 void KRB5_LIB_FUNCTION
 krb5_verify_opt_init (krb5_verify_opt */*opt*/);
 
index 35a751c2915b3ac440c2ac4fc91296206a518d1c..69f72d7b88e62c4e09cd622d08bd0cab652b9266 100755 (executable)
@@ -33,7 +33,7 @@
 
 #include "krb5_locl.h"
 
-RCSID("$Id: pkinit.c,v 1.58 2005/07/23 10:42:01 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.59 2005/08/12 08:53:00 lha Exp $");
 
 #ifdef PKINIT
 
@@ -58,7 +58,7 @@ RCSID("$Id: pkinit.c,v 1.58 2005/07/23 10:42:01 lha Exp $");
 enum {
     COMPAT_WIN2K = 1,
     COMPAT_19 = 2,
-    COMPAT_25 = 3
+    COMPAT_27 = 3
 };
 
 
@@ -716,7 +716,7 @@ pk_mk_padata(krb5_context context,
            krb5_abortx(context, "internal ASN1 encoder error");
 
        oid = oid_id_pkauthdata();
-    } else if (compat == COMPAT_25) {
+    } else if (compat == COMPAT_27) {
        AuthPack ap;
        
        memset(&ap, 0, sizeof(ap));
@@ -802,7 +802,7 @@ pk_mk_padata(krb5_context context,
 
        free_PA_PK_AS_REQ_19(&req_19);
 
-    } else if (compat == COMPAT_25) {
+    } else if (compat == COMPAT_27) {
 
        pa_type = KRB5_PADATA_PK_AS_REQ;
 
@@ -871,7 +871,7 @@ _krb5_pk_mk_padata(krb5_context context,
        if (ret)
            goto out;
 
-       ret = pk_mk_padata(context, COMPAT_25, ctx, req_body, nonce, md);
+       ret = pk_mk_padata(context, COMPAT_27, ctx, req_body, nonce, md);
        if (ret)
            goto out;
     }
@@ -1280,10 +1280,10 @@ _krb5_pk_verify_sign(krb5_context context,
 }
 
 static krb5_error_code
-get_reply_key(krb5_context context,
-             const krb5_data *content,
-             unsigned nonce,
-             krb5_keyblock **key)
+get_reply_key_19(krb5_context context,
+                const krb5_data *content,
+                unsigned nonce,
+                krb5_keyblock **key)
 {
     ReplyKeyPack_19 key_pack;
     krb5_error_code ret;
@@ -1323,6 +1323,69 @@ get_reply_key(krb5_context context,
     return ret;
 }
 
+static krb5_error_code
+get_reply_key(krb5_context context,
+             const krb5_data *content,
+             const krb5_data *req_buffer,
+             krb5_keyblock **key)
+{
+    ReplyKeyPack key_pack;
+    krb5_error_code ret;
+    size_t size;
+
+    ret = decode_ReplyKeyPack(content->data,
+                             content->length,
+                             &key_pack,
+                             &size);
+    if (ret) {
+       krb5_set_error_string(context, "PKINIT decoding reply key failed");
+       free_ReplyKeyPack(&key_pack);
+       return ret;
+    }
+    
+    {
+       krb5_crypto crypto;
+
+       /* 
+        * XXX Verify kp.replyKey is a allowed enctype in the
+        * configuration file
+        */
+
+       ret = krb5_crypto_init(context, &key_pack.replyKey, 0, &crypto);
+       if (ret) {
+           free_ReplyKeyPack(&key_pack);
+           return ret;
+       }
+
+       ret = krb5_verify_checksum(context, crypto, 6,
+                                  req_buffer->data, req_buffer->length,
+                                  &key_pack.asChecksum);
+       krb5_crypto_destroy(context, crypto);
+       if (ret) {
+           free_ReplyKeyPack(&key_pack);
+           return ret;
+       }
+    }
+
+    *key = malloc (sizeof (**key));
+    if (*key == NULL) {
+       krb5_set_error_string(context, "PKINIT failed allocating reply key");
+       free_ReplyKeyPack(&key_pack);
+       krb5_set_error_string(context, "malloc: out of memory");
+       return ENOMEM;
+    }
+
+    ret = copy_EncryptionKey(&key_pack.replyKey, *key);
+    free_ReplyKeyPack(&key_pack);
+    if (ret) {
+       krb5_set_error_string(context, "PKINIT failed copying reply key");
+       free(*key);
+    }
+
+    return ret;
+}
+
+
 static krb5_error_code
 pk_verify_host(krb5_context context, struct krb5_pk_cert *host)
 {
@@ -1332,11 +1395,12 @@ pk_verify_host(krb5_context context, struct krb5_pk_cert *host)
 
 static krb5_error_code
 pk_rd_pa_reply_enckey(krb5_context context,
-                     int win2k_compat,
+                     int type,
                       ContentInfo *rep,
                      krb5_pk_init_ctx ctx,
                      krb5_enctype etype,
                      unsigned nonce,
+                     const krb5_data *req_buffer,
                      PA_DATA *pa,
                      krb5_keyblock **key) 
 {
@@ -1418,7 +1482,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
 
   
     /* verify content type */
-    if (win2k_compat) {
+    if (type == COMPAT_WIN2K) {
        if (heim_oid_cmp(&ed.encryptedContentInfo.contentType, oid_id_pkcs7_data())) {
            ret = KRB5KRB_AP_ERR_MSG_TYPE;
            goto out;
@@ -1481,7 +1545,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
     length = plain.length;
 
     /* win2k uses ContentInfo */
-    if (win2k_compat) {
+    if (type == COMPAT_WIN2K) {
        ContentInfo ci;
 
        ret = decode_ContentInfo(p, length, &ci, &size);
@@ -1518,7 +1582,7 @@ pk_rd_pa_reply_enckey(krb5_context context,
        goto out;
     }
 
-    if (win2k_compat) {
+    if (type == COMPAT_WIN2K) {
        if (heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) {
            krb5_set_error_string(context, "PKINIT: reply key, wrong oid");
            ret = KRB5KRB_AP_ERR_MSG_TYPE;
@@ -1532,7 +1596,15 @@ pk_rd_pa_reply_enckey(krb5_context context,
        }
     }
 
-    ret = get_reply_key(context, &content, nonce, key);
+    switch(type) {
+    case COMPAT_WIN2K:
+    case COMPAT_19:
+       ret = get_reply_key_19(context, &content, nonce, key);
+       break;
+    case COMPAT_27:
+       ret = get_reply_key(context, &content, req_buffer, key);
+       break;
+    }
     if (ret)
        goto out;
 
@@ -1728,6 +1800,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
                     void *c,
                     krb5_enctype etype,
                     unsigned nonce,
+                    const krb5_data *req_buffer,
                     PA_DATA *pa,
                     krb5_keyblock **key)
 {
@@ -1736,7 +1809,7 @@ _krb5_pk_rd_pa_reply(krb5_context context,
     ContentInfo ci;
     size_t size;
 
-    /* Check for PK-INIT -25 */
+    /* Check for PK-INIT -27 */
     if (pa->padata_type == KRB5_PADATA_PK_AS_REP) {
        PA_PK_AS_REP rep;
 
@@ -1781,8 +1854,8 @@ _krb5_pk_rd_pa_reply(krb5_context context,
                                      "ContentInfo: %d", ret);
                break;
            }
-           ret = pk_rd_pa_reply_enckey(context, 0, &ci, ctx,
-                                       etype, nonce, pa, key);
+           ret = pk_rd_pa_reply_enckey(context, COMPAT_27, &ci, ctx,
+                                       etype, nonce, req_buffer, pa, key);
            free_ContentInfo(&ci);
            return ret;
        default:
@@ -1811,9 +1884,9 @@ _krb5_pk_rd_pa_reply(krb5_context context,
                                        nonce, pa, key);
                break;
            case choice_PA_PK_AS_REP_19_encKeyPack:
-               ret = pk_rd_pa_reply_enckey(context, 0,
+               ret = pk_rd_pa_reply_enckey(context, COMPAT_19,
                                            &rep19.u.encKeyPack, ctx,
-                                           etype, nonce, pa, key);
+                                           etype, nonce, NULL, pa, key);
                break;
            default:
                krb5_set_error_string(context, "PKINIT: -19 reply invalid "
@@ -1857,8 +1930,8 @@ _krb5_pk_rd_pa_reply(krb5_context context,
                                      ret);
                return ret;
            }
-           ret = pk_rd_pa_reply_enckey(context, 1, &ci, ctx,
-                                       etype, nonce, pa, key);
+           ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &ci, ctx,
+                                       etype, nonce, NULL, pa, key);
            free_ContentInfo(&ci);
            break;
        default:
diff --git a/source4/heimdal/lib/krb5/test_crypto_wrapping.c b/source4/heimdal/lib/krb5/test_crypto_wrapping.c
deleted file mode 100644 (file)
index 37d9bba..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2005 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
- *
- * 1. Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright 
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the distribution. 
- *
- * 3. Neither the name of KTH nor the names of its contributors may be
- *    used to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#include "krb5_locl.h"
-#include <err.h>
-#include <getarg.h>
-
-RCSID("$Id: test_crypto_wrapping.c,v 1.2 2005/07/09 01:31:43 lha Exp $");
-
-static void
-test_wrapping(krb5_context context,
-             size_t min_size,
-             size_t max_size,
-             size_t step,
-             krb5_enctype etype)
-{
-    krb5_error_code ret;
-    krb5_keyblock key;
-    krb5_crypto crypto;
-    krb5_data data;
-    char *etype_name;
-    void *buf;
-    size_t size;
-
-    ret = krb5_generate_random_keyblock(context, etype, &key);
-    if (ret)
-       krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
-
-    ret = krb5_enctype_to_string(context, etype, &etype_name);
-    if (ret)
-       krb5_err(context, 1, ret, "krb5_enctype_to_string");
-
-    buf = malloc(max_size);
-    if (buf == NULL)
-       krb5_errx(context, 1, "out of memory");
-    memset(buf, 0, max_size);
-
-    ret = krb5_crypto_init(context, &key, 0, &crypto);
-    if (ret)
-       krb5_err(context, 1, ret, "krb5_crypto_init");
-
-    for (size = min_size; size < max_size; size += step) {
-       size_t wrapped_size;
-
-       ret = krb5_encrypt(context, crypto, 0, buf, size, &data);
-       if (ret)
-           krb5_err(context, 1, ret, "encrypt size %d using %s",
-                    size, etype_name);
-
-       wrapped_size = krb5_get_wrapped_length(context, crypto, size);
-
-       if (wrapped_size != data.length)
-           krb5_errx(context, 1, "calculated wrapped length %lu != "
-                     "real wrapped length %lu for data length %lu using "
-                     "enctype %s",
-                     (unsigned long)wrapped_size,
-                     (unsigned long)data.length,
-                     (unsigned long)size,
-                     etype_name);
-       krb5_data_free(&data);
-    }
-
-    free(buf);
-    krb5_crypto_destroy(context, crypto);
-    krb5_free_keyblock_contents(context, &key);
-}
-
-
-
-static int version_flag = 0;
-static int help_flag   = 0;
-
-static struct getargs args[] = {
-    {"version",        0,      arg_flag,       &version_flag,
-     "print version", NULL },
-    {"help",   0,      arg_flag,       &help_flag,
-     NULL, NULL }
-};
-
-static void
-usage (int ret)
-{
-    arg_printusage (args,
-                   sizeof(args)/sizeof(*args),
-                   NULL,
-                   "");
-    exit (ret);
-}
-
-int
-main(int argc, char **argv)
-{
-    krb5_context context;
-    krb5_error_code ret;
-    int i, optidx = 0;
-
-    krb5_enctype enctypes[] = { 
-       ETYPE_DES_CBC_CRC,
-       ETYPE_DES_CBC_MD4,
-       ETYPE_DES_CBC_MD5,
-       ETYPE_DES3_CBC_SHA1,
-       ETYPE_ARCFOUR_HMAC_MD5,
-       ETYPE_AES128_CTS_HMAC_SHA1_96,
-       ETYPE_AES256_CTS_HMAC_SHA1_96
-    };
-
-    setprogname(argv[0]);
-
-    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
-       usage(1);
-    
-    if (help_flag)
-       usage (0);
-
-    if(version_flag){
-       print_version(NULL);
-       exit(0);
-    }
-
-    argc -= optidx;
-    argv += optidx;
-
-    ret = krb5_init_context(&context);
-    if (ret)
-       errx (1, "krb5_init_context failed: %d", ret);
-
-    for (i = 0; i < sizeof(enctypes)/sizeof(enctypes[0]); i++) {
-       test_wrapping(context, 0, 1024, 1, enctypes[i]);
-       test_wrapping(context, 1024, 1024 * 100, 1024, enctypes[i]);
-    }
-    krb5_free_context(context);
-
-    return 0;
-}
diff --git a/source4/heimdal/lib/krb5/test_pkinit_dh2key.c b/source4/heimdal/lib/krb5/test_pkinit_dh2key.c
deleted file mode 100644 (file)
index a40c218..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2005 Kungliga Tekniska Högskolan
- * (Royal Institute of Technology, Stockholm, Sweden). 
- * All rights reserved. 
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met: 
- *
- * 1. Redistributions of source code must retain the above copyright 
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright 
- *    notice, this list of conditions and the following disclaimer in the 
- *    documentation and/or other materials provided with the distribution. 
- *
- * 3. Neither the name of KTH nor the names of its contributors may be
- *    used to endorse or promote products derived from this software without
- *    specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-
-#include "krb5_locl.h"
-#include <err.h>
-#include <getarg.h>
-
-RCSID("$Id: test_pkinit_dh2key.c,v 1.1 2005/07/20 16:27:58 lha Exp $");
-
-static void
-test_dh2key(krb5_context context, 
-           const heim_octet_string *K,
-           const heim_octet_string *c_n,
-           const heim_octet_string *k_n,
-           krb5_enctype etype)
-{
-    return;
-}
-
-
-
-static int version_flag = 0;
-static int help_flag   = 0;
-
-static struct getargs args[] = {
-    {"version",        0,      arg_flag,       &version_flag,
-     "print version", NULL },
-    {"help",   0,      arg_flag,       &help_flag,
-     NULL, NULL }
-};
-
-static void
-usage (int ret)
-{
-    arg_printusage (args,
-                   sizeof(args)/sizeof(*args),
-                   NULL,
-                   "");
-    exit (ret);
-}
-
-int
-main(int argc, char **argv)
-{
-    krb5_context context;
-    krb5_error_code ret;
-    int i, optidx = 0;
-
-    krb5_enctype enctypes[] = { 
-       ETYPE_AES128_CTS_HMAC_SHA1_96,
-       ETYPE_AES256_CTS_HMAC_SHA1_96
-    };
-
-    setprogname(argv[0]);
-
-    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
-       usage(1);
-    
-    if (help_flag)
-       usage (0);
-
-    if(version_flag){
-       print_version(NULL);
-       exit(0);
-    }
-
-    argc -= optidx;
-    argv += optidx;
-
-    ret = krb5_init_context(&context);
-    if (ret)
-       errx (1, "krb5_init_context failed: %d", ret);
-
-    for (i = 0; i < sizeof(enctypes)/sizeof(enctypes[0]); i++) {
-       test_dh2key(context, NULL, NULL, NULL, enctypes[i]);
-    }
-
-    krb5_free_context(context);
-
-    return 0;
-}
index 6e8882ed11e8f933b88d3a6c68a9ba324e87465a..d311f8636f346c358eb4be8590f5766cf5ce7503 100644 (file)
@@ -21,11 +21,21 @@ NOPROTO = YES
 ADD_OBJ_FILES = \
        heimdal/lib/hdb/db.o \
        heimdal/lib/hdb/hdb.o \
+       heimdal/lib/hdb/ext.o \
        heimdal/lib/hdb/keys.o \
+       heimdal/lib/hdb/mkey.o \
        heimdal/lib/hdb/ndbm.o \
        heimdal/lib/hdb/asn1_Event.o \
        heimdal/lib/hdb/asn1_GENERATION.o \
        heimdal/lib/hdb/asn1_HDBFlags.o \
+       heimdal/lib/hdb/asn1_HDB_Ext_Aliases.o \
+       heimdal/lib/hdb/asn1_HDB_Ext_Constrained_delegation_acl.o \
+       heimdal/lib/hdb/asn1_HDB_Ext_Lan_Manager_OWF.o \
+       heimdal/lib/hdb/asn1_HDB_Ext_PKINIT_acl.o \
+       heimdal/lib/hdb/asn1_HDB_Ext_PKINIT_certificate.o \
+       heimdal/lib/hdb/asn1_HDB_Ext_Password.o \
+       heimdal/lib/hdb/asn1_HDB_extension.o \
+       heimdal/lib/hdb/asn1_HDB_extensions.o \
        heimdal/lib/hdb/asn1_Key.o \
        heimdal/lib/hdb/asn1_Salt.o \
        heimdal/lib/hdb/asn1_hdb_entry.o \