Use OpenSSL 3.x _only_ and implement RFC 8636
- No more OpenSSL 1.x support - Remove 1DES and 3DES - Remove NETLOGON, NTLM (client and 'digest' service)
This commit is contained in:
+3
-1
@@ -2,12 +2,14 @@
|
||||
|
||||
include $(top_srcdir)/Makefile.am.common
|
||||
|
||||
AM_CPPFLAGS += $(INCLUDE_readline)
|
||||
AM_CPPFLAGS += $(INCLUDE_readline) -I$(srcdir)/../lib/krb5
|
||||
|
||||
man_MANS = ktutil.1
|
||||
|
||||
bin_PROGRAMS = ktutil
|
||||
|
||||
ktutil_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/../lib/krb5
|
||||
|
||||
dist_ktutil_SOURCES = \
|
||||
add.c \
|
||||
change.c \
|
||||
|
||||
+2
-2
@@ -96,8 +96,8 @@ kt_add(struct add_options *opt, int argc, char **argv)
|
||||
goto out;
|
||||
}
|
||||
if(opt->password_string == NULL && opt->random_flag == 0) {
|
||||
if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Password: ",
|
||||
UI_UTIL_FLAG_VERIFY)) {
|
||||
if(_krb5_UI_UTIL_read_pw_string(buf, sizeof(buf), "Password: ",
|
||||
UI_UTIL_FLAG_VERIFY)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
|
||||
#include "crypto-headers.h"
|
||||
#include <krb5.h>
|
||||
#include <krb5_locl.h>
|
||||
#include <kadm5/admin.h>
|
||||
#include <kadm5/kadm5_err.h>
|
||||
|
||||
|
||||
@@ -5,11 +5,7 @@ include $(top_srcdir)/Makefile.am.common
|
||||
if DCE
|
||||
dir_dce = dceutils
|
||||
endif
|
||||
if !NO_AFS
|
||||
dir_afsutil = afsutil
|
||||
endif
|
||||
SUBDIRS = \
|
||||
$(dir_afsutil) \
|
||||
dbutils \
|
||||
gssmask \
|
||||
test \
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
2007-04-11 Love Hörnquist Åstrand <lha@it.su.se>
|
||||
|
||||
* pagsh.1,afslog.1: - options must be lexicographically ordered;
|
||||
again, options without arguments must be placed before options
|
||||
with arguments. - manual page cross references are done using
|
||||
the macro `.Xr', not the macro `.Nm' (used for command names
|
||||
instead).
|
||||
|
||||
From Igor Sobrado.
|
||||
|
||||
2006-10-07 Love Hörnquist Åstrand <lha@it.su.se>
|
||||
|
||||
* Makefile.am: Add man_MANS to EXTRA_DIST
|
||||
|
||||
2006-01-03 Love Hörnquist Åstrand <lha@it.su.se>
|
||||
|
||||
* afslog.1: Document options to allow select principal or
|
||||
credential cache when doing afslog.
|
||||
|
||||
* afslog.c: Add options to allow select principal or credential
|
||||
cache when doing afslog.
|
||||
|
||||
2005-02-12 Love Hörnquist Åstrand <lha@it.su.se>
|
||||
|
||||
* Makefile.am: man_MANS += pagsh.1
|
||||
|
||||
* pagsh.c: add --cache-type that allows the user to control the
|
||||
resulting credential cache type, inherit the type from the
|
||||
invoking process
|
||||
|
||||
* pagsh.1: manpage for pagsh
|
||||
|
||||
2004-09-03 Love Hörnquist Åstrand <lha@it.su.se>
|
||||
|
||||
* afslog.c: use negative string help string for arg_negative_flag
|
||||
Pointed out by Harald Barth
|
||||
|
||||
2004-07-27 Love Hörnquist Åstrand <lha@it.su.se>
|
||||
|
||||
* pagsh.c: use setprogname, if we stripped off -c, try use the
|
||||
fallback code
|
||||
|
||||
2003-10-14 Johan Danielsson <joda@pdc.kth.se>
|
||||
|
||||
* pagsh.c: mkstemp formats must end in exactly six X's
|
||||
|
||||
2003-07-15 Love Hörnquist Åstrand <lha@it.su.se>
|
||||
|
||||
* afslog.c (do_afslog): is cell is unset, set it "<default cell>"
|
||||
for error printing
|
||||
|
||||
* pagsh.c: unconditionally set KRBTKFILE
|
||||
|
||||
2003-04-23 Love Hörnquist Åstrand <lha@it.su.se>
|
||||
|
||||
* afslog.c (log_func): drop the error number
|
||||
|
||||
2003-04-14 Love Hörnquist Åstrand <lha@it.su.se>
|
||||
|
||||
* afslog.c: set kafs log function if verbose is turned on
|
||||
|
||||
2003-03-18 Love Hörnquist Åstrand <lha@it.su.se>
|
||||
|
||||
* Makefile.am (LDADD): use LIB_kafs
|
||||
|
||||
* afslog.1: --no-v4, --no-v5
|
||||
|
||||
* Makefile.am: always build afsutils now
|
||||
|
||||
* afslog.c: make build without KRB4
|
||||
|
||||
2002-11-26 Johan Danielsson <joda@pdc.kth.se>
|
||||
|
||||
* afslog.c: remove plural form in help string
|
||||
|
||||
* Makefile.am: add afslog manpage
|
||||
|
||||
* afslog.1: manpage
|
||||
|
||||
* afslog.c: try more files when trying to expand a cell name
|
||||
|
||||
* afslog.c: create a list of cells to get tokens for, before
|
||||
actually doing anything, and try to get tokens via krb4 if krb5
|
||||
fails, and give it a chance to work with krb4-only; also some bug
|
||||
fixes, partially from Tomas Olsson.
|
||||
|
||||
2002-08-23 Assar Westerlund <assar@kth.se>
|
||||
|
||||
* pagsh.c: make it handle --version/--help
|
||||
|
||||
2001-05-17 Assar Westerlund <assar@sics.se>
|
||||
|
||||
* afslog.c (main): call free_getarg_strings
|
||||
|
||||
2000-12-31 Assar Westerlund <assar@sics.se>
|
||||
|
||||
* afslog.c (main): handle krb5_init_context failure consistently
|
||||
|
||||
2000-12-25 Assar Westerlund <assar@sics.se>
|
||||
|
||||
* afslog.c: clarify usage strings
|
||||
|
||||
1999-08-04 Assar Westerlund <assar@sics.se>
|
||||
|
||||
* pagsh.c (main): use mkstemp to generate temporary file names.
|
||||
From Miroslav Ruda <ruda@ics.muni.cz>
|
||||
|
||||
1999-07-04 Assar Westerlund <assar@sics.se>
|
||||
|
||||
* afslog.c (expand_cell_name): terminate on #. From Miroslav Ruda
|
||||
<ruda@ics.muni.cz>
|
||||
|
||||
1999-06-27 Assar Westerlund <assar@sics.se>
|
||||
|
||||
* Makefile.am (bin_PROGRAMS): only include pagsh if KRB4
|
||||
|
||||
1999-06-26 Assar Westerlund <assar@sics.se>
|
||||
|
||||
* Makefile.am: add pagsh
|
||||
|
||||
* pagsh.c: new file. contributed by Miroslav Ruda <ruda@ics.muni.cz>
|
||||
|
||||
Sat Mar 27 12:49:43 1999 Johan Danielsson <joda@blubb.pdc.kth.se>
|
||||
|
||||
* afslog.c: cleanup option parsing
|
||||
@@ -1,18 +0,0 @@
|
||||
# $Id$
|
||||
|
||||
include $(top_srcdir)/Makefile.am.common
|
||||
|
||||
bin_PROGRAMS = afslog pagsh
|
||||
|
||||
afslog_SOURCES = afslog.c
|
||||
|
||||
pagsh_SOURCES = pagsh.c
|
||||
|
||||
man_MANS = afslog.1 pagsh.1
|
||||
|
||||
LDADD = $(LIB_kafs) \
|
||||
$(top_builddir)/lib/krb5/libkrb5.la \
|
||||
$(top_builddir)/lib/asn1/libasn1.la \
|
||||
$(LIB_roken)
|
||||
|
||||
EXTRA_DIST = NTMakefile $(man_MANS)
|
||||
@@ -1,35 +0,0 @@
|
||||
########################################################################
|
||||
#
|
||||
# Copyright (c) 2009, Secure Endpoints Inc.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# - 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.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
|
||||
# COPYRIGHT HOLDER 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.
|
||||
#
|
||||
|
||||
RELDIR=appl\afsutil
|
||||
|
||||
!include ../../windows/NTMakefile.w32
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
.\" Copyright (c) 2002 - 2007 Kungliga Tekniska Högskolan
|
||||
.\" (Royal Institute of Technology, Stockholm, Sweden).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\"
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\"
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" 3. Neither the name of the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd November 26, 2002
|
||||
.Dt AFSLOG 1
|
||||
.Os HEIMDAL
|
||||
.Sh NAME
|
||||
.Nm afslog
|
||||
.Nd obtain AFS tokens
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl h | Fl Fl help
|
||||
.Op Fl Fl no-v5
|
||||
.Op Fl u | Fl Fl unlog
|
||||
.Op Fl v | Fl Fl verbose
|
||||
.Op Fl Fl version
|
||||
.Oo Fl c Ar cell \*(Ba Xo
|
||||
.Fl Fl cell= Ns Ar cell
|
||||
.Xc
|
||||
.Oc
|
||||
.Oo Fl k Ar realm \*(Ba Xo
|
||||
.Fl Fl realm= Ns Ar realm
|
||||
.Xc
|
||||
.Oc
|
||||
.Oo Fl P Ar principal \*(Ba Xo
|
||||
.Fl Fl principal= Ns Ar principal
|
||||
.Xc
|
||||
.Oc
|
||||
.Bk -words
|
||||
.Oo Fl p Ar path \*(Ba Xo
|
||||
.Fl Fl file= Ns Ar path
|
||||
.Xc
|
||||
.Oc
|
||||
.Ek
|
||||
.Op Ar cell | path ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
obtains AFS tokens for a number of cells. What cells to get tokens for
|
||||
can either be specified as an explicit list, as file paths to get
|
||||
tokens for, or be left unspecified, in which case
|
||||
.Nm
|
||||
will use whatever magic
|
||||
.Xr krb_afslog 3
|
||||
decides upon.
|
||||
.Pp
|
||||
Supported options:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl Fl no-v5
|
||||
This makes
|
||||
.Nm
|
||||
not try using Kerberos 5.
|
||||
.It Xo
|
||||
.Fl P Ar principal ,
|
||||
.Fl Fl principal Ar principal
|
||||
.Xc
|
||||
select what Kerberos 5 principal to use.
|
||||
.It Fl Fl cache Ar cache
|
||||
select what Kerberos 5 credential cache to use.
|
||||
.Fl Fl principal
|
||||
overrides this option.
|
||||
.It Xo
|
||||
.Fl u ,
|
||||
.Fl Fl unlog
|
||||
.Xc
|
||||
Destroy tokens instead of obtaining new. If this is specified, all
|
||||
other options are ignored (except for
|
||||
.Fl Fl help
|
||||
and
|
||||
.Fl Fl version ) .
|
||||
.It Xo
|
||||
.Fl v ,
|
||||
.Fl Fl verbose
|
||||
.Xc
|
||||
Adds more verbosity for what is actually going on.
|
||||
.It Xo
|
||||
.Fl c Ar cell,
|
||||
.Fl Fl cell= Ns Ar cell
|
||||
.Xc
|
||||
This specified one or more cell names to get tokens for.
|
||||
.It Xo
|
||||
.Fl k Ar realm ,
|
||||
.Fl Fl realm= Ns Ar realm
|
||||
.Xc
|
||||
This is the Kerberos realm the AFS servers live in, this should
|
||||
normally not be specified.
|
||||
.It Xo
|
||||
.Fl p Ar path ,
|
||||
.Fl Fl file= Ns Ar path
|
||||
.Xc
|
||||
This specified one or more file paths for which tokens should be
|
||||
obtained.
|
||||
.El
|
||||
.Pp
|
||||
Instead of using
|
||||
.Fl c
|
||||
and
|
||||
.Fl p ,
|
||||
you may also pass a list of cells and file paths after any other
|
||||
options. These arguments are considered files if they are either
|
||||
the strings
|
||||
.Do . Dc
|
||||
or
|
||||
.Dq ..
|
||||
or they contain a slash, or if there exists a file by that name.
|
||||
.Sh EXAMPLES
|
||||
Assuming that there is no file called
|
||||
.Dq openafs.org
|
||||
in the current directory, and that
|
||||
.Pa /afs/openafs.org
|
||||
points to that cell, the follwing should be identical:
|
||||
.Bd -literal -offset indent
|
||||
$ afslog -c openafs.org
|
||||
$ afslog openafs.org
|
||||
$ afslog /afs/openafs.org/some/file
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr krb_afslog 3
|
||||
@@ -1,303 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
RCSID("$Id$");
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#ifdef KRB5
|
||||
#include <krb5.h>
|
||||
#endif
|
||||
#include <kafs.h>
|
||||
#include <roken.h>
|
||||
#include <getarg.h>
|
||||
#include <err.h>
|
||||
|
||||
static int help_flag;
|
||||
static int version_flag;
|
||||
static getarg_strings cells;
|
||||
static char *realm;
|
||||
static getarg_strings files;
|
||||
static int unlog_flag;
|
||||
static int verbose;
|
||||
#ifdef KRB5
|
||||
static char *client_string;
|
||||
static char *cache_string;
|
||||
static int use_krb5 = 1;
|
||||
#endif
|
||||
|
||||
struct getargs args[] = {
|
||||
{ "cell", 'c', arg_strings, &cells, "cells to get tokens for", "cell" },
|
||||
{ "file", 'p', arg_strings, &files, "files to get tokens for", "path" },
|
||||
{ "realm", 'k', arg_string, &realm, "realm for afs cell", "realm" },
|
||||
{ "unlog", 'u', arg_flag, &unlog_flag, "remove tokens", NULL },
|
||||
#ifdef KRB5
|
||||
{ "principal",'P',arg_string,&client_string,"principal to use","principal"},
|
||||
{ "cache", 0, arg_string, &cache_string, "ccache to use", "cache"},
|
||||
{ "v5", 0, arg_negative_flag, &use_krb5, "don't use Kerberos 5",
|
||||
NULL },
|
||||
#endif
|
||||
{ "verbose",'v', arg_flag, &verbose, NULL, NULL },
|
||||
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
||||
{ "help", 'h', arg_flag, &help_flag, NULL, NULL },
|
||||
};
|
||||
|
||||
static int num_args = sizeof(args) / sizeof(args[0]);
|
||||
|
||||
#ifdef KRB5
|
||||
krb5_context context;
|
||||
krb5_ccache id;
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
expand_one_file(FILE *f, const char *cell)
|
||||
{
|
||||
static char buf[1024];
|
||||
char *p;
|
||||
|
||||
while (fgets (buf, sizeof(buf), f) != NULL) {
|
||||
if(buf[0] == '>') {
|
||||
for(p = buf; *p && !isspace((unsigned char)*p) && *p != '#'; p++)
|
||||
;
|
||||
*p = '\0';
|
||||
if(strncmp(buf + 1, cell, strlen(cell)) == 0)
|
||||
return buf + 1;
|
||||
}
|
||||
buf[0] = '\0';
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
expand_cell_name(const char *cell)
|
||||
{
|
||||
FILE *f;
|
||||
const char *c;
|
||||
const char **fn, *fns[] = { _PATH_CELLSERVDB,
|
||||
_PATH_ARLA_CELLSERVDB,
|
||||
_PATH_OPENAFS_DEBIAN_CELLSERVDB,
|
||||
_PATH_ARLA_DEBIAN_CELLSERVDB,
|
||||
NULL };
|
||||
for(fn = fns; *fn; fn++) {
|
||||
f = fopen(*fn, "r");
|
||||
if(f == NULL)
|
||||
continue;
|
||||
c = expand_one_file(f, cell);
|
||||
fclose(f);
|
||||
if(c)
|
||||
return c;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(int ecode)
|
||||
{
|
||||
arg_printusage(args, num_args, NULL, "[cell|path]...");
|
||||
exit(ecode);
|
||||
}
|
||||
|
||||
struct cell_list {
|
||||
char *cell;
|
||||
struct cell_list *next;
|
||||
} *cell_list;
|
||||
|
||||
static int
|
||||
afslog_cell(const char *cell, int expand)
|
||||
{
|
||||
struct cell_list *p, **q;
|
||||
const char *c = cell;
|
||||
if(expand){
|
||||
c = expand_cell_name(cell);
|
||||
if(c == NULL){
|
||||
warnx("No cell matching \"%s\" found.", cell);
|
||||
return -1;
|
||||
}
|
||||
if(verbose && strcmp(c, cell) != 0)
|
||||
warnx("Cell \"%s\" expanded to \"%s\"", cell, c);
|
||||
}
|
||||
/* add to list of cells to get tokens for, and also remove
|
||||
duplicates; the actual afslog takes place later */
|
||||
for(p = cell_list, q = &cell_list; p; q = &p->next, p = p->next)
|
||||
if(strcmp(p->cell, c) == 0)
|
||||
return 0;
|
||||
p = malloc(sizeof(*p));
|
||||
if(p == NULL)
|
||||
return -1;
|
||||
p->cell = strdup(c);
|
||||
if(p->cell == NULL) {
|
||||
free(p);
|
||||
return -1;
|
||||
}
|
||||
p->next = NULL;
|
||||
*q = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
afslog_file(const char *path)
|
||||
{
|
||||
char cell[64];
|
||||
if(k_afs_cell_of_file(path, cell, sizeof(cell))){
|
||||
warnx("No cell found for file \"%s\".", path);
|
||||
return -1;
|
||||
}
|
||||
if(verbose)
|
||||
warnx("File \"%s\" lives in cell \"%s\"", path, cell);
|
||||
return afslog_cell(cell, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
do_afslog(const char *cell)
|
||||
{
|
||||
int k5ret;
|
||||
|
||||
k5ret = 0;
|
||||
|
||||
#ifdef KRB5
|
||||
if(context != NULL && id != NULL && use_krb5) {
|
||||
k5ret = krb5_afslog(context, id, cell, realm);
|
||||
if(k5ret == 0)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (cell == NULL)
|
||||
cell = "<default cell>";
|
||||
#ifdef KRB5
|
||||
if (k5ret)
|
||||
krb5_warn(context, k5ret, "krb5_afslog(%s)", cell);
|
||||
#endif
|
||||
if (k5ret)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
log_func(void *ctx, const char *str)
|
||||
{
|
||||
fprintf(stderr, "%s\n", str);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int optidx = 0;
|
||||
int i;
|
||||
int num;
|
||||
int ret = 0;
|
||||
int failed = 0;
|
||||
struct cell_list *p;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
if(getarg(args, num_args, argc, argv, &optidx))
|
||||
usage(1);
|
||||
if(help_flag)
|
||||
usage(0);
|
||||
if(version_flag) {
|
||||
print_version(NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if(!k_hasafs())
|
||||
errx(1, "AFS does not seem to be present on this machine");
|
||||
|
||||
if(unlog_flag){
|
||||
k_unlog();
|
||||
exit(0);
|
||||
}
|
||||
#ifdef KRB5
|
||||
ret = krb5_init_context(&context);
|
||||
if (ret) {
|
||||
context = NULL;
|
||||
} else {
|
||||
if (client_string) {
|
||||
krb5_principal client;
|
||||
|
||||
ret = krb5_parse_name(context, client_string, &client);
|
||||
if (ret == 0)
|
||||
ret = krb5_cc_cache_match(context, client, &id);
|
||||
if (ret)
|
||||
id = NULL;
|
||||
}
|
||||
if (id == NULL && cache_string) {
|
||||
if(krb5_cc_resolve(context, cache_string, &id) != 0) {
|
||||
krb5_warnx(context, "failed to open kerberos 5 cache '%s'",
|
||||
cache_string);
|
||||
id = NULL;
|
||||
}
|
||||
}
|
||||
if (id == NULL)
|
||||
if(krb5_cc_default(context, &id) != 0)
|
||||
id = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (verbose)
|
||||
kafs_set_verbose(log_func, NULL);
|
||||
|
||||
num = 0;
|
||||
for(i = 0; i < files.num_strings; i++){
|
||||
afslog_file(files.strings[i]);
|
||||
num++;
|
||||
}
|
||||
free_getarg_strings (&files);
|
||||
for(i = 0; i < cells.num_strings; i++){
|
||||
afslog_cell(cells.strings[i], 1);
|
||||
num++;
|
||||
}
|
||||
free_getarg_strings (&cells);
|
||||
for(i = optidx; i < argc; i++){
|
||||
num++;
|
||||
if(strcmp(argv[i], ".") == 0 ||
|
||||
strcmp(argv[i], "..") == 0 ||
|
||||
strchr(argv[i], '/') ||
|
||||
access(argv[i], F_OK) == 0)
|
||||
afslog_file(argv[i]);
|
||||
else
|
||||
afslog_cell(argv[i], 1);
|
||||
}
|
||||
if(num == 0) {
|
||||
if(do_afslog(NULL))
|
||||
failed++;
|
||||
} else
|
||||
for(p = cell_list; p; p = p->next) {
|
||||
if(verbose)
|
||||
warnx("Getting tokens for cell \"%s\"", p->cell);
|
||||
if(do_afslog(p->cell))
|
||||
failed++;
|
||||
}
|
||||
|
||||
return failed;
|
||||
}
|
||||
@@ -1,94 +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 the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd February 12, 2005
|
||||
.Dt PAGSH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pagsh
|
||||
.Nd creates a new credential cache sandbox
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl c Ar command-string
|
||||
.Op Fl h | Fl Fl help
|
||||
.Op Fl Fl version
|
||||
.Op Fl Fl cache-type= Ns Ar string
|
||||
.Ar command [args...]
|
||||
.Sh DESCRIPTION
|
||||
Supported options:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo
|
||||
.Fl c Ar command-string
|
||||
Executes command(s) contained in
|
||||
.Ar command-string .
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl cache-type= Ns Ar string
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl h ,
|
||||
.Fl Fl help
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl version
|
||||
.Xc
|
||||
.El
|
||||
.Pp
|
||||
.Nm
|
||||
creates a new credential cache sandbox for the user to live in.
|
||||
If AFS is installed on the computer, the user is put in a newly
|
||||
created Process Authentication Group (PAG).
|
||||
.Pp
|
||||
For Kerberos 5, the credential cache type that is used is the same as
|
||||
the credential cache type that was used at the time of
|
||||
.Nm
|
||||
invocation.
|
||||
The credential cache type can be controlled by the option
|
||||
.Fl Fl cache-type .
|
||||
.Sh EXAMPLES
|
||||
Create a new sandbox where new credentials can be used, while the old
|
||||
credentials can be used by other processes.
|
||||
.Bd -literal -offset indent
|
||||
$ klist
|
||||
Credentials cache: FILE:/tmp/krb5cc_913
|
||||
Principal: lha@E.KTH.SE
|
||||
|
||||
Issued Expires Principal
|
||||
Feb 12 10:08:31 Feb 12 20:06:36 krbtgt/E.KTH.SE@E.KTH.SE
|
||||
$ pagsh
|
||||
$ klist
|
||||
klist: No ticket file: /tmp/krb5cc_03014a
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr afslog 1 ,
|
||||
.Xr kinit 1
|
||||
@@ -1,213 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1995 - 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#ifdef KRB5
|
||||
#include <krb5.h>
|
||||
#endif
|
||||
#include <kafs.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <roken.h>
|
||||
#include <getarg.h>
|
||||
|
||||
#ifndef TKT_ROOT
|
||||
#define TKT_ROOT "/tmp/tkt"
|
||||
#endif
|
||||
|
||||
static int help_flag;
|
||||
static int version_flag;
|
||||
static int c_flag;
|
||||
#ifdef KRB5
|
||||
static char *typename_arg;
|
||||
#endif
|
||||
|
||||
struct getargs getargs[] = {
|
||||
{ NULL, 'c', arg_flag, &c_flag, NULL, NULL },
|
||||
#ifdef KRB5
|
||||
{ "cache-type", 0, arg_string, &typename_arg, NULL, NULL },
|
||||
#endif
|
||||
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
||||
{ "help", 'h', arg_flag, &help_flag, NULL, NULL },
|
||||
};
|
||||
|
||||
static int num_args = sizeof(getargs) / sizeof(getargs[0]);
|
||||
|
||||
static void
|
||||
usage(int ecode)
|
||||
{
|
||||
arg_printusage(getargs, num_args, NULL, "command [args...]");
|
||||
exit(ecode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Run command with a new ticket file / credentials cache / token
|
||||
*/
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int f;
|
||||
char tf[1024];
|
||||
char shellbuf[MAX_PATH];
|
||||
char *p;
|
||||
|
||||
char *path;
|
||||
char **args;
|
||||
unsigned int i;
|
||||
int optidx = 0;
|
||||
|
||||
setprogname(argv[0]);
|
||||
if(getarg(getargs, num_args, argc, argv, &optidx))
|
||||
usage(1);
|
||||
if(help_flag)
|
||||
usage(0);
|
||||
if(version_flag) {
|
||||
print_version(NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
argc -= optidx;
|
||||
argv += optidx;
|
||||
|
||||
#ifdef KRB5
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_context context;
|
||||
krb5_ccache id;
|
||||
const char *name;
|
||||
|
||||
ret = krb5_init_context(&context);
|
||||
if (ret) /* XXX should this really call exit ? */
|
||||
errx(1, "no kerberos 5 support");
|
||||
|
||||
ret = krb5_cc_new_unique(context, typename_arg, NULL, &id);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "Failed generating credential cache");
|
||||
|
||||
name = krb5_cc_get_name(context, id);
|
||||
if (name == NULL)
|
||||
krb5_errx(context, 1, "Generated credential cache have no name");
|
||||
|
||||
snprintf(tf, sizeof(tf), "%s:%s", krb5_cc_get_type(context, id), name);
|
||||
|
||||
ret = krb5_cc_close(context, id);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "Failed closing credential cache");
|
||||
|
||||
krb5_free_context(context);
|
||||
|
||||
esetenv("KRB5CCNAME", tf, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
snprintf (tf, sizeof(tf), "%s_XXXXXX", TKT_ROOT);
|
||||
f = mkstemp (tf);
|
||||
if (f < 0)
|
||||
err(1, "mkstemp failed");
|
||||
close (f);
|
||||
unlink (tf);
|
||||
esetenv("KRBTKFILE", tf, 1);
|
||||
|
||||
i = 0;
|
||||
|
||||
args = (char **) malloc((argc + 10)*sizeof(char *));
|
||||
if (args == NULL)
|
||||
errx (1, "Out of memory allocating %lu bytes",
|
||||
(unsigned long)((argc + 10)*sizeof(char *)));
|
||||
|
||||
if(*argv == NULL) {
|
||||
if (roken_get_shell(shellbuf, sizeof(shellbuf)) != NULL)
|
||||
path = strdup(shellbuf);
|
||||
else
|
||||
path = strdup("/bin/sh");
|
||||
} else {
|
||||
path = strdup(*argv++);
|
||||
}
|
||||
if (path == NULL)
|
||||
errx (1, "Out of memory copying path");
|
||||
|
||||
p=strrchr(path, '/');
|
||||
if(p)
|
||||
args[i] = strdup(p+1);
|
||||
else
|
||||
args[i] = strdup(path);
|
||||
|
||||
if (args[i++] == NULL)
|
||||
errx (1, "Out of memory copying arguments");
|
||||
|
||||
while(*argv)
|
||||
args[i++] = *argv++;
|
||||
|
||||
args[i++] = NULL;
|
||||
|
||||
if(k_hasafs())
|
||||
k_setpag();
|
||||
|
||||
unsetenv("PAGPID");
|
||||
execvp(path, args);
|
||||
if (errno == ENOENT || c_flag) {
|
||||
char **sh_args = malloc ((i + 2) * sizeof(char *));
|
||||
unsigned int j;
|
||||
|
||||
if (sh_args == NULL)
|
||||
errx (1, "Out of memory copying sh arguments");
|
||||
for (j = 1; j < i; ++j)
|
||||
sh_args[j + 2] = args[j];
|
||||
sh_args[0] = "sh";
|
||||
sh_args[1] = "-c";
|
||||
sh_args[2] = path;
|
||||
execv ("/bin/sh", sh_args);
|
||||
}
|
||||
err (1, "execvp");
|
||||
}
|
||||
@@ -54,7 +54,6 @@ kinit_auditdns_LDADD = \
|
||||
$(top_builddir)/lib/krb5/libkrb5.la \
|
||||
$(top_builddir)/lib/gssapi/libgssapi.la \
|
||||
$(top_builddir)/lib/gss_preauth/libgss_preauth.la \
|
||||
$(top_builddir)/lib/ntlm/libheimntlm.la \
|
||||
$(top_builddir)/lib/asn1/libasn1.la \
|
||||
$(LIB_libintl) \
|
||||
$(LIB_roken)
|
||||
|
||||
@@ -4,7 +4,7 @@ SUFFIXES = .et .h .pc.in .pc
|
||||
|
||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include
|
||||
|
||||
AM_CPPFLAGS = $(INCLUDES_roken)
|
||||
AM_CPPFLAGS = $(INCLUDES_roken) $(INCLUDE_openssl_crypto)
|
||||
|
||||
if do_roken_rename
|
||||
ROKEN_RENAME = -DROKEN_RENAME
|
||||
|
||||
@@ -10,6 +10,9 @@ m4_define([test_headers], [
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/provider.h>
|
||||
#include <openssl/encoder.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/md4.h>
|
||||
#include <openssl/md5.h>
|
||||
@@ -140,6 +143,28 @@ if test "$pkcs11_module" != ""; then
|
||||
openssl=no
|
||||
fi
|
||||
|
||||
dnl Check for OpenSSL PKCS#11 provider (pkcs11-provider project)
|
||||
dnl It installs into the OpenSSL modules directory
|
||||
openssl_pkcs11_provider=""
|
||||
if test "$openssl" = "yes"; then
|
||||
if test "$with_openssl_lib" != ""; then
|
||||
pkcs11_provider_path="${with_openssl_lib}/ossl-modules/pkcs11.so"
|
||||
elif test "$with_openssl" != "" -a "$with_openssl" != "yes"; then
|
||||
pkcs11_provider_path="${with_openssl}/lib/ossl-modules/pkcs11.so"
|
||||
else
|
||||
pkcs11_provider_path="/usr/lib/ossl-modules/pkcs11.so"
|
||||
fi
|
||||
AC_MSG_CHECKING([for OpenSSL PKCS11 provider])
|
||||
if test -f "$pkcs11_provider_path"; then
|
||||
openssl_pkcs11_provider="$pkcs11_provider_path"
|
||||
AC_MSG_RESULT([$openssl_pkcs11_provider])
|
||||
else
|
||||
AC_MSG_RESULT([not found at $pkcs11_provider_path])
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(OPENSSL_PKCS11_PROVIDER, [$openssl_pkcs11_provider])
|
||||
AM_CONDITIONAL([HAVE_OPENSSL_PKCS11_PROVIDER], [test "x$openssl_pkcs11_provider" != "x"])
|
||||
|
||||
if test "$openssl" != "yes"; then
|
||||
AC_MSG_ERROR([OpenSSL is required])
|
||||
fi
|
||||
|
||||
+8
-4
@@ -342,8 +342,14 @@ AC_SUBST(dpagaix_ldadd)
|
||||
AC_SUBST(dpagaix_ldflags)
|
||||
|
||||
AC_ARG_ENABLE([afs-support],
|
||||
AS_HELP_STRING([--disable-afs-support],[if you don't want support for AFS]))
|
||||
if test "$enable_afs_support" = no; then
|
||||
AS_HELP_STRING([--enable-afs-support],[enable support for AFS]),
|
||||
[enable_afs_support=yes],
|
||||
[enable_afs_support=no])
|
||||
if test "$enable_afs_support" = yes; then
|
||||
NO_AFS="0"
|
||||
AC_MSG_ERROR([AFS no longer supported])
|
||||
else
|
||||
# XXX This is pointless now, should be removed
|
||||
AC_DEFINE(NO_AFS, 1, [Define if you don't wan't support for AFS.])
|
||||
NO_AFS="1"
|
||||
fi
|
||||
@@ -742,7 +748,6 @@ AC_CONFIG_FILES(Makefile \
|
||||
lib/hdb/Makefile \
|
||||
lib/ipc/Makefile \
|
||||
lib/kadm5/Makefile \
|
||||
lib/kafs/Makefile \
|
||||
lib/kdfs/Makefile \
|
||||
lib/krb5/Makefile \
|
||||
lib/roken/Makefile \
|
||||
@@ -759,7 +764,6 @@ AC_CONFIG_FILES(Makefile \
|
||||
kcm/Makefile \
|
||||
kdc/Makefile \
|
||||
appl/Makefile \
|
||||
appl/afsutil/Makefile \
|
||||
appl/dbutils/Makefile \
|
||||
appl/gssmask/Makefile \
|
||||
appl/test/Makefile \
|
||||
|
||||
+2
-9
@@ -43,11 +43,6 @@ krb5.dxy: krb5.din Makefile
|
||||
chmod +x krb5.dxy.tmp
|
||||
mv krb5.dxy.tmp krb5.dxy
|
||||
|
||||
ntlm.dxy: ntlm.din Makefile
|
||||
$(dxy_subst) < $(srcdir)/ntlm.din > ntlm.dxy.tmp
|
||||
chmod +x ntlm.dxy.tmp
|
||||
mv ntlm.dxy.tmp ntlm.dxy
|
||||
|
||||
wind.dxy: wind.din Makefile
|
||||
$(dxy_subst) < $(srcdir)/wind.din > wind.dxy.tmp
|
||||
chmod +x wind.dxy.tmp
|
||||
@@ -62,9 +57,9 @@ vars.texi: vars.tin Makefile
|
||||
chmod +x vars.texi.tmp
|
||||
mv vars.texi.tmp vars.texi
|
||||
|
||||
PROJECTS = base hdb hx509 gssapi krb5 ntlm wind
|
||||
PROJECTS = base hdb hx509 gssapi krb5 wind
|
||||
|
||||
doxyout doxygen: base.dxy hdb.dxy hx509.dxy gssapi.dxy krb5.dxy ntlm.dxy wind.dxy
|
||||
doxyout doxygen: base.dxy hdb.dxy hx509.dxy gssapi.dxy krb5.dxy wind.dxy
|
||||
@test -d $(srcdir)/doxyout && \
|
||||
find $(srcdir)/doxyout -type d ! -perm -200 -exec chmod u+w {} ';' ; \
|
||||
rm -rf $(srcdir)/doxyout ; \
|
||||
@@ -135,7 +130,6 @@ EXTRA_DIST = \
|
||||
base.din \
|
||||
hx509.din \
|
||||
krb5.din \
|
||||
ntlm.din \
|
||||
init-creds \
|
||||
latin1.tex \
|
||||
layman.asc \
|
||||
@@ -152,6 +146,5 @@ CLEANFILES = \
|
||||
hdb.dxy* \
|
||||
gssapi.dxy* \
|
||||
krb5.dxy* \
|
||||
ntlm.dxy* \
|
||||
wind.dxy* \
|
||||
vars.texi*
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Doxyfile 1.5.3
|
||||
|
||||
PROJECT_NAME = Heimdal ntlm library
|
||||
PROJECT_NUMBER = @PACKAGE_VERSION@
|
||||
OUTPUT_DIRECTORY = @srcdir@/doxyout/ntlm
|
||||
INPUT = @srcdir@/../lib/ntlm
|
||||
EXAMPLE_PATH = @srcdir@/../lib/ntlm
|
||||
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
HTML_HEADER = "@srcdir@/header.html"
|
||||
HTML_FOOTER = "@srcdir@/footer.html"
|
||||
|
||||
@INCLUDE = "@srcdir@/doxytmpl.dxy"
|
||||
@@ -69,8 +69,6 @@ CLEANFILES = \
|
||||
heimbase.h \
|
||||
heimbase-svc.h \
|
||||
heimbase-protos.h \
|
||||
heimntlm-protos.h \
|
||||
heimntlm.h \
|
||||
hex.h \
|
||||
hx509-private.h \
|
||||
hx509-protos.h \
|
||||
@@ -98,7 +96,6 @@ CLEANFILES = \
|
||||
kx509_err.h \
|
||||
locate_plugin.h \
|
||||
login-protos.h \
|
||||
ntlm_err.h \
|
||||
ocsp_asn1.h \
|
||||
ocsp_template_asn1.h \
|
||||
parse_bytes.h \
|
||||
@@ -138,7 +135,6 @@ CLEANFILES = \
|
||||
gss_preauth_authorizer_plugin.h \
|
||||
token_validator_plugin.h \
|
||||
xdbm.h \
|
||||
x25519_ref10.h \
|
||||
x690sample_asn1.h \
|
||||
x690sample_template_asn1.h
|
||||
|
||||
|
||||
@@ -21,5 +21,10 @@
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/provider.h>
|
||||
#include <openssl/encoder.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/param_build.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#endif /* __crypto_header__ */
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
include $(top_srcdir)/Makefile.am.common
|
||||
|
||||
CLEANFILES = gssapi.h gssapi_krb5.h gssapi_spnego.h gssapi_ntlm.h gssapi_oid.h
|
||||
CLEANFILES = gssapi.h gssapi_krb5.h gssapi_spnego.h gssapi_oid.h
|
||||
|
||||
EXTRA_DIST = NTMakefile
|
||||
|
||||
+3
-3
@@ -150,9 +150,9 @@ add_one_principal(const char *name,
|
||||
krb5_set_error_message(context, ret, "out of memory");
|
||||
goto out;
|
||||
}
|
||||
ret = UI_UTIL_read_pw_string (pwbuf, sizeof(pwbuf), prompt,
|
||||
UI_UTIL_FLAG_VERIFY |
|
||||
UI_UTIL_FLAG_VERIFY_SILENT);
|
||||
ret = _krb5_UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), prompt,
|
||||
UI_UTIL_FLAG_VERIFY |
|
||||
UI_UTIL_FLAG_VERIFY_SILENT);
|
||||
free (prompt);
|
||||
if (ret) {
|
||||
ret = KRB5_LIBOS_BADPWDMATCH;
|
||||
|
||||
+3
-3
@@ -134,9 +134,9 @@ set_password(void *dup_kadm_handle,
|
||||
free (princ_name);
|
||||
if (aret == -1)
|
||||
return ENOMEM;
|
||||
ret = UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), prompt,
|
||||
UI_UTIL_FLAG_VERIFY |
|
||||
UI_UTIL_FLAG_VERIFY_SILENT);
|
||||
ret = _krb5_UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), prompt,
|
||||
UI_UTIL_FLAG_VERIFY |
|
||||
UI_UTIL_FLAG_VERIFY_SILENT);
|
||||
free (prompt);
|
||||
if(ret){
|
||||
return KRB5_LIBOS_BADPWDMATCH;
|
||||
|
||||
@@ -50,6 +50,8 @@ static char *client_name;
|
||||
static char *keytab;
|
||||
static char *check_library = NULL;
|
||||
static char *check_function = NULL;
|
||||
static char *ossl_cnf = NULL;
|
||||
static char *ossl_propq = NULL;
|
||||
static getarg_strings policy_libraries = { 0, NULL };
|
||||
|
||||
static struct getargs args[] = {
|
||||
@@ -93,6 +95,10 @@ static struct getargs args[] = {
|
||||
#endif
|
||||
{ "local", 'l', arg_flag, &local_flag, "local admin mode", NULL },
|
||||
{ "async", 'A', arg_flag, &async_flag, "local admin mode (no fsyncs)", NULL },
|
||||
{ "ossl-cnf", 0, arg_string, &ossl_cnf,
|
||||
"OpenSSL configuration file", "FILE" },
|
||||
{ "ossl-propq", 0, arg_string, &ossl_propq,
|
||||
"OpenSSL property query string (e.g., provider=pkcs11)", "PROPQ" },
|
||||
{ "help", 'h', arg_flag, &help_flag, NULL, NULL },
|
||||
{ "version", 'v', arg_flag, &version_flag, NULL, NULL }
|
||||
};
|
||||
@@ -188,6 +194,12 @@ main(int argc, char **argv)
|
||||
argc -= optidx;
|
||||
argv += optidx;
|
||||
|
||||
if (ossl_cnf || ossl_propq) {
|
||||
ret = krb5_set_ossl_cnf_propq(context, ossl_cnf, ossl_propq);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_set_ossl_cnf_propq");
|
||||
}
|
||||
|
||||
if (config_file == NULL) {
|
||||
aret = asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context));
|
||||
if (aret == -1)
|
||||
|
||||
+2
-2
@@ -99,8 +99,8 @@ stash(struct stash_options *opt, int argc, char **argv)
|
||||
random_password (buf, sizeof(buf));
|
||||
printf("Using random master stash password: %s\n", buf);
|
||||
} else {
|
||||
if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Master key: ",
|
||||
UI_UTIL_FLAG_VERIFY)) {
|
||||
if(_krb5_UI_UTIL_read_pw_string(buf, sizeof(buf), "Master key: ",
|
||||
UI_UTIL_FLAG_VERIFY)) {
|
||||
hdb_free_master_key(context, mkey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,10 +35,10 @@ man_MANS = kcm.8
|
||||
LDADD = $(top_builddir)/lib/hdb/libhdb.la \
|
||||
$(top_builddir)/lib/krb5/libkrb5.la \
|
||||
$(top_builddir)/lib/asn1/libasn1.la \
|
||||
$(top_builddir)/lib/ntlm/libheimntlm.la \
|
||||
$(top_builddir)/lib/ipc/libheim-ipcs.la \
|
||||
$(LIB_roken) \
|
||||
$(LIB_door_create) \
|
||||
$(LIB_openssl_crypto) \
|
||||
$(LIB_pidfile)
|
||||
|
||||
EXTRA_DIST = NTMakefile $(man_MANS)
|
||||
|
||||
+6
-367
@@ -33,7 +33,6 @@
|
||||
*/
|
||||
|
||||
#include "kcm_locl.h"
|
||||
#include <heimntlm.h>
|
||||
|
||||
static void
|
||||
kcm_drop_default_cache(krb5_context context, kcm_client *client, char *name);
|
||||
@@ -1224,28 +1223,6 @@ kcm_op_set_kdc_offset(krb5_context context,
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct kcm_ntlm_cred {
|
||||
kcmuuid_t uuid;
|
||||
char *user;
|
||||
char *domain;
|
||||
krb5_data nthash;
|
||||
uid_t uid;
|
||||
pid_t session;
|
||||
struct kcm_ntlm_cred *next;
|
||||
};
|
||||
|
||||
static struct kcm_ntlm_cred *ntlm_head;
|
||||
|
||||
static void
|
||||
free_cred(struct kcm_ntlm_cred *cred)
|
||||
{
|
||||
free(cred->user);
|
||||
free(cred->domain);
|
||||
krb5_data_free(&cred->nthash);
|
||||
free(cred);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* name
|
||||
* domain
|
||||
@@ -1255,20 +1232,6 @@ free_cred(struct kcm_ntlm_cred *cred)
|
||||
* uuid
|
||||
*/
|
||||
|
||||
static struct kcm_ntlm_cred *
|
||||
find_ntlm_cred(const char *user, const char *domain, kcm_client *client)
|
||||
{
|
||||
struct kcm_ntlm_cred *c;
|
||||
|
||||
for (c = ntlm_head; c != NULL; c = c->next)
|
||||
if ((user[0] == '\0' || strcmp(user, c->user) == 0) &&
|
||||
(domain == NULL || strcmp(domain, c->domain) == 0) &&
|
||||
kcm_is_same_session(client, c->uid, c->session))
|
||||
return c;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
kcm_op_add_ntlm_cred(krb5_context context,
|
||||
kcm_client *client,
|
||||
@@ -1276,52 +1239,10 @@ kcm_op_add_ntlm_cred(krb5_context context,
|
||||
krb5_storage *request,
|
||||
krb5_storage *response)
|
||||
{
|
||||
struct kcm_ntlm_cred *cred, *c;
|
||||
krb5_error_code ret;
|
||||
|
||||
cred = calloc(1, sizeof(*cred));
|
||||
if (cred == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
RAND_bytes(cred->uuid, sizeof(cred->uuid));
|
||||
|
||||
ret = krb5_ret_stringz(request, &cred->user);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = krb5_ret_stringz(request, &cred->domain);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = krb5_ret_data(request, &cred->nthash);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
/* search for dups */
|
||||
c = find_ntlm_cred(cred->user, cred->domain, client);
|
||||
if (c) {
|
||||
krb5_data hash = c->nthash;
|
||||
c->nthash = cred->nthash;
|
||||
cred->nthash = hash;
|
||||
free_cred(cred);
|
||||
cred = c;
|
||||
} else {
|
||||
cred->next = ntlm_head;
|
||||
ntlm_head = cred;
|
||||
}
|
||||
|
||||
cred->uid = client->uid;
|
||||
cred->session = client->session;
|
||||
|
||||
/* write response */
|
||||
(void)krb5_storage_write(response, &cred->uuid, sizeof(cred->uuid));
|
||||
(void)krb5_storage_write(response, "not supported", sizeof("not supported"));
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free_cred(cred);
|
||||
|
||||
return ret;
|
||||
return ENOTSUP;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1339,33 +1260,7 @@ kcm_op_have_ntlm_cred(krb5_context context,
|
||||
krb5_storage *request,
|
||||
krb5_storage *response)
|
||||
{
|
||||
struct kcm_ntlm_cred *c;
|
||||
char *user = NULL, *domain = NULL;
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = krb5_ret_stringz(request, &user);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = krb5_ret_stringz(request, &domain);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (domain[0] == '\0') {
|
||||
free(domain);
|
||||
domain = NULL;
|
||||
}
|
||||
|
||||
c = find_ntlm_cred(user, domain, client);
|
||||
if (c == NULL)
|
||||
ret = ENOENT;
|
||||
|
||||
error:
|
||||
free(user);
|
||||
if (domain)
|
||||
free(domain);
|
||||
|
||||
return ret;
|
||||
return ENOTSUP;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1383,35 +1278,7 @@ kcm_op_del_ntlm_cred(krb5_context context,
|
||||
krb5_storage *request,
|
||||
krb5_storage *response)
|
||||
{
|
||||
struct kcm_ntlm_cred **cp, *c;
|
||||
char *user = NULL, *domain = NULL;
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = krb5_ret_stringz(request, &user);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = krb5_ret_stringz(request, &domain);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
for (cp = &ntlm_head; *cp != NULL; cp = &(*cp)->next) {
|
||||
if (strcmp(user, (*cp)->user) == 0 && strcmp(domain, (*cp)->domain) == 0 &&
|
||||
kcm_is_same_session(client, (*cp)->uid, (*cp)->session))
|
||||
{
|
||||
c = *cp;
|
||||
*cp = c->next;
|
||||
|
||||
free_cred(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
free(user);
|
||||
free(domain);
|
||||
|
||||
return ret;
|
||||
return ENOTSUP;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1439,218 +1306,7 @@ kcm_op_do_ntlm(krb5_context context,
|
||||
krb5_storage *request,
|
||||
krb5_storage *response)
|
||||
{
|
||||
struct kcm_ntlm_cred *c;
|
||||
struct ntlm_type2 type2;
|
||||
struct ntlm_type3 type3;
|
||||
char *user = NULL, *domain = NULL;
|
||||
struct ntlm_buf ndata, sessionkey;
|
||||
krb5_data data;
|
||||
krb5_error_code ret;
|
||||
uint32_t flags = 0;
|
||||
|
||||
memset(&type2, 0, sizeof(type2));
|
||||
memset(&type3, 0, sizeof(type3));
|
||||
sessionkey.data = NULL;
|
||||
sessionkey.length = 0;
|
||||
|
||||
ret = krb5_ret_stringz(request, &user);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = krb5_ret_stringz(request, &domain);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (domain[0] == '\0') {
|
||||
free(domain);
|
||||
domain = NULL;
|
||||
}
|
||||
|
||||
c = find_ntlm_cred(user, domain, client);
|
||||
if (c == NULL) {
|
||||
ret = EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = krb5_ret_data(request, &data);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ndata.data = data.data;
|
||||
ndata.length = data.length;
|
||||
|
||||
ret = heim_ntlm_decode_type2(&ndata, &type2);
|
||||
krb5_data_free(&data);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (domain && strcmp(domain, type2.targetname) == 0) {
|
||||
ret = EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
type3.username = c->user;
|
||||
type3.flags = type2.flags;
|
||||
type3.targetname = type2.targetname;
|
||||
type3.ws = rk_UNCONST("workstation");
|
||||
|
||||
/*
|
||||
* NTLM Version 1 if no targetinfo buffer.
|
||||
*/
|
||||
|
||||
if (1 || type2.targetinfo.length == 0) {
|
||||
struct ntlm_buf tmpsesskey;
|
||||
|
||||
if (type2.flags & NTLM_NEG_NTLM2_SESSION) {
|
||||
unsigned char nonce[8];
|
||||
|
||||
if (RAND_bytes(nonce, sizeof(nonce)) != 1) {
|
||||
ret = EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = heim_ntlm_calculate_ntlm2_sess(nonce,
|
||||
type2.challenge,
|
||||
c->nthash.data,
|
||||
&type3.lm,
|
||||
&type3.ntlm);
|
||||
} else {
|
||||
ret = heim_ntlm_calculate_ntlm1(c->nthash.data,
|
||||
c->nthash.length,
|
||||
type2.challenge,
|
||||
&type3.ntlm);
|
||||
|
||||
}
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = heim_ntlm_build_ntlm1_master(c->nthash.data,
|
||||
c->nthash.length,
|
||||
&tmpsesskey,
|
||||
&type3.sessionkey);
|
||||
if (ret) {
|
||||
if (type3.lm.data)
|
||||
free(type3.lm.data);
|
||||
if (type3.ntlm.data)
|
||||
free(type3.ntlm.data);
|
||||
goto error;
|
||||
}
|
||||
|
||||
free(tmpsesskey.data);
|
||||
flags |= NTLM_FLAG_SESSIONKEY;
|
||||
#if 0
|
||||
} else {
|
||||
struct ntlm_buf sessionkey;
|
||||
unsigned char ntlmv2[16];
|
||||
struct ntlm_targetinfo ti;
|
||||
|
||||
/* verify infotarget */
|
||||
|
||||
ret = heim_ntlm_decode_targetinfo(&type2.targetinfo, 1, &ti);
|
||||
if(ret) {
|
||||
_gss_ntlm_delete_sec_context(minor_status,
|
||||
context_handle, NULL);
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (ti.domainname && strcmp(ti.domainname, name->domain) != 0) {
|
||||
_gss_ntlm_delete_sec_context(minor_status,
|
||||
context_handle, NULL);
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = heim_ntlm_calculate_ntlm2(ctx->client->key.data,
|
||||
ctx->client->key.length,
|
||||
type3.username,
|
||||
name->domain,
|
||||
type2.challenge,
|
||||
&type2.targetinfo,
|
||||
ntlmv2,
|
||||
&type3.ntlm);
|
||||
if (ret) {
|
||||
_gss_ntlm_delete_sec_context(minor_status,
|
||||
context_handle, NULL);
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = heim_ntlm_build_ntlm1_master(ntlmv2, sizeof(ntlmv2),
|
||||
&sessionkey,
|
||||
&type3.sessionkey);
|
||||
memset(ntlmv2, 0, sizeof(ntlmv2));
|
||||
if (ret) {
|
||||
_gss_ntlm_delete_sec_context(minor_status,
|
||||
context_handle, NULL);
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
flags |= NTLM_FLAG_NTLM2_SESSION |
|
||||
NTLM_FLAG_SESSION;
|
||||
|
||||
if (type3.flags & NTLM_NEG_KEYEX)
|
||||
flags |= NTLM_FLAG_KEYEX;
|
||||
|
||||
ret = krb5_data_copy(&ctx->sessionkey,
|
||||
sessionkey.data, sessionkey.length);
|
||||
free(sessionkey.data);
|
||||
if (ret) {
|
||||
_gss_ntlm_delete_sec_context(minor_status,
|
||||
context_handle, NULL);
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (flags & NTLM_FLAG_NTLM2_SESSION) {
|
||||
_gss_ntlm_set_key(&ctx->u.v2.send, 0, (ctx->flags & NTLM_NEG_KEYEX),
|
||||
ctx->sessionkey.data,
|
||||
ctx->sessionkey.length);
|
||||
_gss_ntlm_set_key(&ctx->u.v2.recv, 1, (ctx->flags & NTLM_NEG_KEYEX),
|
||||
ctx->sessionkey.data,
|
||||
ctx->sessionkey.length);
|
||||
} else {
|
||||
flags |= NTLM_FLAG_SESSION;
|
||||
RC4_set_key(&ctx->u.v1.crypto_recv.key,
|
||||
ctx->sessionkey.length,
|
||||
ctx->sessionkey.data);
|
||||
RC4_set_key(&ctx->u.v1.crypto_send.key,
|
||||
ctx->sessionkey.length,
|
||||
ctx->sessionkey.data);
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = heim_ntlm_encode_type3(&type3, &ndata, NULL);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
data.data = ndata.data;
|
||||
data.length = ndata.length;
|
||||
ret = krb5_store_data(response, data);
|
||||
heim_ntlm_free_buf(&ndata);
|
||||
if (ret) goto error;
|
||||
|
||||
ret = krb5_store_int32(response, flags);
|
||||
if (ret) goto error;
|
||||
|
||||
data.data = sessionkey.data;
|
||||
data.length = sessionkey.length;
|
||||
|
||||
ret = krb5_store_data(response, data);
|
||||
if (ret) goto error;
|
||||
|
||||
error:
|
||||
free(type3.username);
|
||||
heim_ntlm_free_type2(&type2);
|
||||
free(user);
|
||||
if (domain)
|
||||
free(domain);
|
||||
|
||||
return ret;
|
||||
return ENOTSUP;
|
||||
}
|
||||
|
||||
|
||||
@@ -1669,24 +1325,7 @@ kcm_op_get_ntlm_user_list(krb5_context context,
|
||||
krb5_storage *request,
|
||||
krb5_storage *response)
|
||||
{
|
||||
struct kcm_ntlm_cred *c;
|
||||
krb5_error_code ret;
|
||||
|
||||
for (c = ntlm_head; c != NULL; c = c->next) {
|
||||
if (!kcm_is_same_session(client, c->uid, c->session))
|
||||
continue;
|
||||
|
||||
ret = krb5_store_uint32(response, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = krb5_store_stringz(response, c->user);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = krb5_store_stringz(response, c->domain);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return krb5_store_uint32(response, 0);
|
||||
return ENOTSUP;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+3
-13
@@ -22,7 +22,7 @@ bin_PROGRAMS = string2key
|
||||
|
||||
sbin_PROGRAMS = kstash
|
||||
|
||||
libexec_PROGRAMS = hprop hpropd kdc digest-service \
|
||||
libexec_PROGRAMS = hprop hpropd kdc \
|
||||
test_token_validator test_csr_authorizer test_kdc_ca
|
||||
|
||||
noinst_PROGRAMS = kdc-replay kdc-tester
|
||||
@@ -45,6 +45,7 @@ bx509d_LDADD = -ldl \
|
||||
$(MICROHTTPD_LIBS) \
|
||||
$(LIB_roken) \
|
||||
$(LIB_heimbase) \
|
||||
$(LIB_openssl_crypto) \
|
||||
$(top_builddir)/lib/sl/libsl.la \
|
||||
$(top_builddir)/lib/asn1/libasn1.la \
|
||||
$(top_builddir)/lib/krb5/libkrb5.la \
|
||||
@@ -62,6 +63,7 @@ httpkadmind_LDADD = -ldl \
|
||||
$(MICROHTTPD_LIBS) \
|
||||
$(LIB_roken) \
|
||||
$(LIB_heimbase) \
|
||||
$(LIB_openssl_crypto) \
|
||||
$(top_builddir)/lib/sl/libsl.la \
|
||||
$(top_builddir)/lib/asn1/libasn1.la \
|
||||
$(top_builddir)/lib/krb5/libkrb5.la \
|
||||
@@ -70,9 +72,6 @@ httpkadmind_LDADD = -ldl \
|
||||
libexec_PROGRAMS += httpkadmind
|
||||
endif
|
||||
|
||||
digest_service_SOURCES = \
|
||||
digest-service.c
|
||||
|
||||
kdc_SOURCES = connect.c \
|
||||
config.c \
|
||||
announce.c \
|
||||
@@ -118,13 +117,11 @@ libkdc_la_SOURCES = \
|
||||
default_config.c \
|
||||
ca.c \
|
||||
set_dbinfo.c \
|
||||
digest.c \
|
||||
fast.c \
|
||||
kdc_locl.h \
|
||||
kerberos5.c \
|
||||
krb5tgs.c \
|
||||
pkinit.c \
|
||||
pkinit-ec.c \
|
||||
mssfu.c \
|
||||
log.c \
|
||||
misc.c \
|
||||
@@ -148,7 +145,6 @@ ALL_OBJECTS += $(string2key_OBJECTS)
|
||||
ALL_OBJECTS += $(kstash_OBJECTS)
|
||||
ALL_OBJECTS += $(hprop_OBJECTS)
|
||||
ALL_OBJECTS += $(hpropd_OBJECTS)
|
||||
ALL_OBJECTS += $(digest_service_OBJECTS)
|
||||
ALL_OBJECTS += $(bx509d_OBJECTS)
|
||||
ALL_OBJECTS += $(httpkadmind_OBJECTS)
|
||||
ALL_OBJECTS += $(cjwt_token_validator_la_OBJECTS)
|
||||
@@ -202,7 +198,6 @@ libkdc_la_LIBADD = \
|
||||
$(top_builddir)/lib/gssapi/libgssapi.la \
|
||||
$(top_builddir)/lib/gss_preauth/libgss_preauth.la \
|
||||
$(LIB_kdb) \
|
||||
$(top_builddir)/lib/ntlm/libheimntlm.la \
|
||||
$(LIB_openssl_crypto) \
|
||||
$(top_builddir)/lib/asn1/libasn1.la \
|
||||
$(LIB_roken) \
|
||||
@@ -221,11 +216,6 @@ kdc_LDFLAGS = -framework SystemConfiguration -framework CoreFoundation
|
||||
endif
|
||||
kdc_CFLAGS = $(CAPNG_CFLAGS)
|
||||
|
||||
digest_service_LDADD = \
|
||||
libkdc.la \
|
||||
$(top_builddir)/lib/ntlm/libheimntlm.la \
|
||||
$(top_builddir)/lib/ipc/libheim-ipcs.la \
|
||||
$(LDADD) $(LIB_pidfile)
|
||||
kdc_replay_LDADD = libkdc.la $(LDADD) $(LIB_pidfile)
|
||||
kdc_tester_LDADD = libkdc.la $(LDADD) $(LIB_pidfile) $(LIB_heimbase)
|
||||
test_token_validator_LDADD = libkdc.la $(LDADD) $(LIB_pidfile) $(LIB_heimbase) $(LIB_gssapi)
|
||||
|
||||
+2
-12
@@ -42,8 +42,7 @@ SBINPROGRAMS=$(SBINDIR)\kstash.exe
|
||||
LIBEXECPROGRAMS= \
|
||||
$(LIBEXECDIR)\hprop.exe \
|
||||
$(LIBEXECDIR)\hpropd.exe \
|
||||
$(LIBEXECDIR)\kdc.exe \
|
||||
# $(LIBEXECDIR)\digest-service.exe
|
||||
$(LIBEXECDIR)\kdc.exe
|
||||
|
||||
NOINST_PROGRAMS=$(OBJ)\kdc-replay.exe
|
||||
|
||||
@@ -83,10 +82,6 @@ $(BINDIR)\string2key.exe: $(OBJ)\string2key.obj $(BIN_LIBS) $(OBJ)\string2key-ve
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP)
|
||||
|
||||
$(BINDIR)\digest-service.exe: $(OBJ)\digest-service.obj $(BIN_LIBS)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP)
|
||||
|
||||
$(LIBEXECDIR)\kdc.exe: \
|
||||
$(OBJ)\connect.obj $(OBJ)\config.obj $(OBJ)\announce.obj \
|
||||
$(OBJ)\main.obj $(OBJ)\kdc-version.res \
|
||||
@@ -99,13 +94,11 @@ LIBKDC_OBJS=\
|
||||
$(OBJ)\ca.obj \
|
||||
$(OBJ)\kx509.obj \
|
||||
$(OBJ)\set_dbinfo.obj \
|
||||
$(OBJ)\digest.obj \
|
||||
$(OBJ)\fast.obj \
|
||||
$(OBJ)\kerberos5.obj \
|
||||
$(OBJ)\krb5tgs.obj \
|
||||
$(OBJ)\pkinit.obj \
|
||||
$(OBJ)\pkinit-ec.obj \
|
||||
$(OBJ)\mssfu.obj \
|
||||
$(OBJ)\mssfu.obj \
|
||||
$(OBJ)\log.obj \
|
||||
$(OBJ)\misc.obj \
|
||||
$(OBJ)\kx509.obj \
|
||||
@@ -121,7 +114,6 @@ LIBKDC_LIBS=\
|
||||
$(LIBGSSAPI) \
|
||||
$(LIBHEIMBASE) \
|
||||
$(LIBHEIMDAL) \
|
||||
$(LIBHEIMNTLM) \
|
||||
$(LIB_openssl_crypto) \
|
||||
$(LIBROKEN)
|
||||
|
||||
@@ -140,13 +132,11 @@ libkdc_la_SOURCES = \
|
||||
default_config.c \
|
||||
ca.c \
|
||||
set_dbinfo.c \
|
||||
digest.c \
|
||||
fast.c \
|
||||
kdc_locl.h \
|
||||
kerberos5.c \
|
||||
krb5tgs.c \
|
||||
pkinit.c \
|
||||
pkinit-ec.c \
|
||||
mssfu.c \
|
||||
log.c \
|
||||
misc.c \
|
||||
|
||||
+85
-34
@@ -293,8 +293,12 @@ static const char *priv_key_file;
|
||||
static const char *cache_dir;
|
||||
static const char *csrf_key_file;
|
||||
static char *impersonation_key_fn;
|
||||
static const char *impersonation_key_type;
|
||||
static int impersonation_key_bits;
|
||||
static const char *ossl_cnf;
|
||||
static const char *ossl_propq;
|
||||
|
||||
static char csrf_key[16];
|
||||
static unsigned char csrf_key[16];
|
||||
|
||||
static krb5_error_code resp(struct bx509_request_desc *, int,
|
||||
enum MHD_ResponseMemoryMode, const char *,
|
||||
@@ -382,20 +386,37 @@ generate_key(hx509_context context,
|
||||
hx509_private_key key = NULL;
|
||||
hx509_certs certs = NULL;
|
||||
hx509_cert cert = NULL;
|
||||
const heim_oid *key_oid;
|
||||
int ret;
|
||||
|
||||
if (strcmp(gen_type, "rsa") != 0)
|
||||
errx(1, "Only RSA keys are supported at this time");
|
||||
/* Map key type string to OID */
|
||||
if (gen_type == NULL || strcasecmp(gen_type, "rsa") == 0) {
|
||||
key_oid = ASN1_OID_ID_PKCS1_RSAENCRYPTION;
|
||||
if (gen_bits == 0)
|
||||
gen_bits = 2048;
|
||||
} else if (strcasecmp(gen_type, "ec") == 0 ||
|
||||
strcasecmp(gen_type, "ecdsa") == 0) {
|
||||
key_oid = ASN1_OID_ID_ECPUBLICKEY;
|
||||
if (gen_bits == 0)
|
||||
gen_bits = 256; /* P-256 by default */
|
||||
} else if (strcasecmp(gen_type, "ed25519") == 0) {
|
||||
key_oid = ASN1_OID_ID_ED25519;
|
||||
gen_bits = 0; /* Ed25519 has fixed size */
|
||||
} else if (strcasecmp(gen_type, "ed448") == 0) {
|
||||
key_oid = ASN1_OID_ID_ED448;
|
||||
gen_bits = 0; /* Ed448 has fixed size */
|
||||
} else {
|
||||
errx(1, "Unsupported key type: %s (supported: rsa, ec, ed25519, ed448)",
|
||||
gen_type);
|
||||
}
|
||||
|
||||
if (asprintf(fn, "PEM-FILE:%s/.%s_priv_key.pem",
|
||||
cache_dir, key_name) == -1 ||
|
||||
*fn == NULL)
|
||||
err(1, "Could not set up private key for %s", key_name);
|
||||
|
||||
ret = _hx509_generate_private_key_init(context,
|
||||
ASN1_OID_ID_PKCS1_RSAENCRYPTION,
|
||||
&key_gen_ctx);
|
||||
if (ret == 0)
|
||||
ret = _hx509_generate_private_key_init(context, key_oid, &key_gen_ctx);
|
||||
if (ret == 0 && gen_bits > 0)
|
||||
ret = _hx509_generate_private_key_bits(context, key_gen_ctx, gen_bits);
|
||||
if (ret == 0)
|
||||
ret = _hx509_generate_private_key(context, key_gen_ctx, &key);
|
||||
@@ -2333,35 +2354,31 @@ mac_csrf_token(struct bx509_request_desc *r, krb5_storage *sp)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_data data;
|
||||
char mac[EVP_MAX_MD_SIZE];
|
||||
unsigned int maclen = sizeof(mac);
|
||||
HMAC_CTX *ctx = NULL;
|
||||
unsigned char mac[EVP_MAX_MD_SIZE];
|
||||
size_t maclen = sizeof(mac);
|
||||
EVP_MAC_CTX *ctx = NULL;
|
||||
|
||||
ret = krb5_storage_to_data(sp, &data);
|
||||
if (ret == 0 && (ctx = HMAC_CTX_new()) == NULL)
|
||||
ret = krb5_enomem(r->context);
|
||||
if (ret == 0)
|
||||
ret = _krb5_hmac_start_ossl(r->context, csrf_key, sizeof(csrf_key),
|
||||
EVP_sha256(), &ctx);
|
||||
if (ret == ENOMEM)
|
||||
ret = krb5_enomem(r->context);
|
||||
/* HMAC the token body and the client principal name */
|
||||
if (ret == 0) {
|
||||
if (HMAC_Init_ex(ctx, csrf_key, sizeof(csrf_key),
|
||||
EVP_sha256(),
|
||||
NULL) == 0) {
|
||||
HMAC_CTX_cleanup(ctx);
|
||||
ret = krb5_enomem(r->context);
|
||||
} else {
|
||||
HMAC_Update(ctx, data.data, data.length);
|
||||
if (r->cname)
|
||||
HMAC_Update(ctx, r->cname, strlen(r->cname));
|
||||
HMAC_Final(ctx, mac, &maclen);
|
||||
HMAC_CTX_cleanup(ctx);
|
||||
krb5_data_free(&data);
|
||||
data.length = maclen;
|
||||
data.data = mac;
|
||||
if (krb5_storage_write(sp, mac, maclen) != maclen)
|
||||
ret = krb5_enomem(r->context);
|
||||
}
|
||||
}
|
||||
if (ctx)
|
||||
HMAC_CTX_free(ctx);
|
||||
if (ret == 0)
|
||||
ret = (EVP_MAC_update(ctx, data.data, data.length) == 1) ? 0 : EINVAL;
|
||||
if (ret == 0 && r->cname)
|
||||
ret = (EVP_MAC_update(ctx,
|
||||
(unsigned char *)r->cname,
|
||||
strlen(r->cname)) == 1) ? 0 : EINVAL;
|
||||
if (ret == 0)
|
||||
ret = (EVP_MAC_final(ctx, mac, &maclen, maclen) == 1) ? 0 : EINVAL;
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
krb5_data_free(&data);
|
||||
data.length = maclen;
|
||||
data.data = mac;
|
||||
if (krb5_storage_write(sp, mac, maclen) != maclen)
|
||||
ret = krb5_enomem(r->context);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2742,6 +2759,14 @@ static struct getargs args[] = {
|
||||
"private key file path (PEM)", "HX509-STORE" },
|
||||
{ "thread-per-client", 't', arg_flag, &thread_per_client_flag,
|
||||
"thread per-client", "use thread per-client" },
|
||||
{ "impersonation-key-type", 0, arg_string, &impersonation_key_type,
|
||||
"impersonation key type (rsa, ec, ed25519, ed448)", "TYPE" },
|
||||
{ "impersonation-key-bits", 0, arg_integer, &impersonation_key_bits,
|
||||
"impersonation key size/curve (default: 2048 for RSA, 256 for EC)", "BITS" },
|
||||
{ "ossl-cnf", 0, arg_string, &ossl_cnf,
|
||||
"OpenSSL configuration file", "FILE" },
|
||||
{ "ossl-propq", 0, arg_string, &ossl_propq,
|
||||
"OpenSSL property query string (e.g., provider=pkcs11)", "PROPQ" },
|
||||
{ "verbose", 'v', arg_counter, &verbose_counter, "verbose", "run verbosely" }
|
||||
};
|
||||
|
||||
@@ -2921,6 +2946,12 @@ main(int argc, char **argv)
|
||||
if ((errno = get_krb5_context(&context)))
|
||||
err(1, "Could not init krb5 context");
|
||||
|
||||
if (ossl_cnf || ossl_propq) {
|
||||
ret = krb5_set_ossl_cnf_propq(context, ossl_cnf, ossl_propq);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_set_ossl_cnf_propq");
|
||||
}
|
||||
|
||||
bx509_openlog(context, "bx509d", &logfac);
|
||||
krb5_set_log_dest(context, logfac);
|
||||
load_plugins(context);
|
||||
@@ -2986,7 +3017,27 @@ main(int argc, char **argv)
|
||||
setenv("TMPDIR", cache_dir, 1);
|
||||
}
|
||||
|
||||
generate_key(context->hx509ctx, "impersonation", "rsa", 2048, &impersonation_key_fn);
|
||||
/*
|
||||
* Get impersonation key configuration from command line or krb5.conf.
|
||||
* Supported key types: rsa, ec (ecdsa), ed25519, ed448
|
||||
* For RSA: bits is key size (default 2048)
|
||||
* For EC: bits is curve size (256=P-256, 384=P-384, 521=P-521, default 256)
|
||||
* For EdDSA: bits is ignored
|
||||
*/
|
||||
if (impersonation_key_type == NULL)
|
||||
impersonation_key_type = krb5_config_get_string(context, NULL, "bx509d",
|
||||
"impersonation_key_type",
|
||||
NULL);
|
||||
if (impersonation_key_bits == 0)
|
||||
impersonation_key_bits = krb5_config_get_int_default(context, NULL, 0,
|
||||
"bx509d",
|
||||
"impersonation_key_bits",
|
||||
NULL);
|
||||
|
||||
generate_key(context->hx509ctx, "impersonation",
|
||||
impersonation_key_type,
|
||||
(unsigned long)impersonation_key_bits,
|
||||
&impersonation_key_fn);
|
||||
|
||||
again:
|
||||
if (cert_file && !priv_key_file)
|
||||
|
||||
@@ -77,6 +77,8 @@ static struct getarg_strings addresses_str; /* addresses to listen on */
|
||||
|
||||
char *runas_string;
|
||||
char *chroot_string;
|
||||
static char *ossl_cnf;
|
||||
static char *ossl_propq;
|
||||
|
||||
|
||||
static struct getargs args[] = {
|
||||
@@ -123,6 +125,12 @@ static struct getargs args[] = {
|
||||
{ "chroot", 0, arg_string, &chroot_string,
|
||||
"chroot directory to run in", NULL
|
||||
},
|
||||
{ "ossl-cnf", 0, arg_string, &ossl_cnf,
|
||||
"OpenSSL configuration file", "FILE"
|
||||
},
|
||||
{ "ossl-propq", 0, arg_string, &ossl_propq,
|
||||
"OpenSSL property query string (e.g., provider=pkcs11)", "PROPQ"
|
||||
},
|
||||
{ "testing", 0, arg_flag, &testing_flag, NULL, NULL },
|
||||
{ "help", 'h', arg_flag, &help_flag, NULL, NULL },
|
||||
{ "version", 'v', arg_flag, &version_flag, NULL, NULL }
|
||||
@@ -184,6 +192,12 @@ configure(krb5_context context, int argc, char **argv, int *optidx)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (ossl_cnf || ossl_propq) {
|
||||
ret = krb5_set_ossl_cnf_propq(context, ossl_cnf, ossl_propq);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_set_ossl_cnf_propq");
|
||||
}
|
||||
|
||||
if(detach_from_console == -1)
|
||||
detach_from_console = krb5_config_get_bool_default(context, NULL,
|
||||
FALSE,
|
||||
|
||||
+1
-28
@@ -113,7 +113,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
|
||||
c->pkinit_max_life_bound = 0;
|
||||
c->synthetic_clients_max_life = 300;
|
||||
c->synthetic_clients_max_renew = 300;
|
||||
c->pkinit_dh_min_bits = 1024;
|
||||
c->pkinit_dh_min_bits = 2048;
|
||||
c->db = NULL;
|
||||
c->num_db = 0;
|
||||
c->logf = NULL;
|
||||
@@ -126,33 +126,6 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
|
||||
krb5_config_get_bool_default(context, NULL,
|
||||
c->require_preauth,
|
||||
"kdc", "require-preauth", NULL);
|
||||
#ifdef DIGEST
|
||||
c->enable_digest =
|
||||
krb5_config_get_bool_default(context, NULL,
|
||||
FALSE,
|
||||
"kdc", "enable-digest", NULL);
|
||||
|
||||
{
|
||||
const char *digests;
|
||||
|
||||
digests = krb5_config_get_string(context, NULL,
|
||||
"kdc",
|
||||
"digests_allowed", NULL);
|
||||
if (digests == NULL)
|
||||
digests = "ntlm-v2";
|
||||
c->digests_allowed = parse_flags(digests,_kdc_digestunits, 0);
|
||||
if (c->digests_allowed == -1) {
|
||||
kdc_log(context, c, 0,
|
||||
"unparsable digest units (%s), turning off digest",
|
||||
digests);
|
||||
c->enable_digest = 0;
|
||||
} else if (c->digests_allowed == 0) {
|
||||
kdc_log(context, c, 0, "no digest enable, turning digest off");
|
||||
c->enable_digest = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef KX509
|
||||
c->enable_kx509 =
|
||||
krb5_config_get_bool_default(context, NULL,
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. 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 "headers.h"
|
||||
#include <digest_asn1.h>
|
||||
#include <heimntlm.h>
|
||||
#include <heim-ipc.h>
|
||||
#include <getarg.h>
|
||||
|
||||
typedef struct pk_client_params pk_client_params;
|
||||
typedef struct gss_client_params gss_client_params;
|
||||
struct DigestREQ;
|
||||
struct Kx509Request;
|
||||
|
||||
#include <kdc-private.h>
|
||||
|
||||
krb5_kdc_configuration *config;
|
||||
|
||||
static void
|
||||
ntlm_service(void *ctx, const heim_idata *req,
|
||||
const heim_icred cred,
|
||||
heim_ipc_complete complete,
|
||||
heim_sipc_call cctx)
|
||||
{
|
||||
NTLMRequest2 ntq;
|
||||
unsigned char sessionkey[16];
|
||||
heim_idata rep = { 0, NULL };
|
||||
krb5_context context = ctx;
|
||||
hdb_entry *user = NULL;
|
||||
HDB *db = NULL;
|
||||
Key *key = NULL;
|
||||
NTLMReply ntp;
|
||||
size_t size;
|
||||
int ret;
|
||||
const char *domain;
|
||||
|
||||
kdc_log(context, config, 4, "digest-request: uid=%d",
|
||||
(int)heim_ipc_cred_get_uid(cred));
|
||||
|
||||
if (heim_ipc_cred_get_uid(cred) != 0) {
|
||||
(*complete)(cctx, EPERM, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
ntp.success = 0;
|
||||
ntp.flags = 0;
|
||||
ntp.sessionkey = NULL;
|
||||
|
||||
ret = decode_NTLMRequest2(req->data, req->length, &ntq, NULL);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* XXX forward to NetrLogonSamLogonEx() if not a local domain */
|
||||
if (strcmp(ntq.loginDomainName, "BUILTIN") == 0) {
|
||||
domain = ntq.loginDomainName;
|
||||
} else if (strcmp(ntq.loginDomainName, "") == 0) {
|
||||
domain = "BUILTIN";
|
||||
} else {
|
||||
ret = EINVAL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
kdc_log(context, config, 4, "digest-request: user=%s/%s",
|
||||
ntq.loginUserName, domain);
|
||||
|
||||
if (ntq.lmchallenge.length != 8)
|
||||
goto failed;
|
||||
|
||||
if (ntq.ntChallengeResponce.length == 0)
|
||||
goto failed;
|
||||
|
||||
{
|
||||
krb5_principal client;
|
||||
|
||||
ret = krb5_make_principal(context, &client, domain,
|
||||
ntq.loginUserName, NULL);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
krb5_principal_set_type(context, client, KRB5_NT_NTLM);
|
||||
|
||||
ret = _kdc_db_fetch(context, config, client,
|
||||
HDB_F_GET_CLIENT, NULL, &db, &user);
|
||||
krb5_free_principal(context, client);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = hdb_enctype2key(context, user, NULL,
|
||||
ETYPE_ARCFOUR_HMAC_MD5, &key);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, ret, "NTLM missing arcfour key");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
kdc_log(context, config, 5,
|
||||
"digest-request: found user, processing ntlm request");
|
||||
|
||||
if (ntq.ntChallengeResponce.length != 24) {
|
||||
struct ntlm_buf infotarget, answer;
|
||||
|
||||
answer.length = ntq.ntChallengeResponce.length;
|
||||
answer.data = ntq.ntChallengeResponce.data;
|
||||
|
||||
ret = heim_ntlm_verify_ntlm2(key->key.keyvalue.data,
|
||||
key->key.keyvalue.length,
|
||||
ntq.loginUserName,
|
||||
ntq.loginDomainName,
|
||||
0,
|
||||
ntq.lmchallenge.data,
|
||||
&answer,
|
||||
&infotarget,
|
||||
sessionkey);
|
||||
if (ret) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
free(infotarget.data);
|
||||
/* XXX verify info target */
|
||||
|
||||
} else {
|
||||
struct ntlm_buf answer;
|
||||
|
||||
if (ntq.flags & NTLM_NEG_NTLM2_SESSION) {
|
||||
unsigned char sessionhash[MD5_DIGEST_LENGTH];
|
||||
EVP_MD_CTX *md5ctx;
|
||||
|
||||
/* the first first 8 bytes is the challenge, what is the other 16 bytes ? */
|
||||
if (ntq.lmChallengeResponce.length != 24)
|
||||
goto failed;
|
||||
|
||||
md5ctx = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(md5ctx, EVP_md5(), NULL);
|
||||
EVP_DigestUpdate(md5ctx, ntq.lmchallenge.data, 8);
|
||||
EVP_DigestUpdate(md5ctx, ntq.lmChallengeResponce.data, 8);
|
||||
EVP_DigestFinal_ex(md5ctx, sessionhash, NULL);
|
||||
EVP_MD_CTX_destroy(md5ctx);
|
||||
memcpy(ntq.lmchallenge.data, sessionhash, ntq.lmchallenge.length);
|
||||
}
|
||||
|
||||
ret = heim_ntlm_calculate_ntlm1(key->key.keyvalue.data,
|
||||
key->key.keyvalue.length,
|
||||
ntq.lmchallenge.data, &answer);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
if (ntq.ntChallengeResponce.length != answer.length ||
|
||||
ct_memcmp(ntq.ntChallengeResponce.data, answer.data, answer.length) != 0) {
|
||||
free(answer.data);
|
||||
ret = EINVAL;
|
||||
goto failed;
|
||||
}
|
||||
free(answer.data);
|
||||
|
||||
{
|
||||
EVP_MD_CTX *ctxp;
|
||||
|
||||
ctxp = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(ctxp, EVP_md4(), NULL);
|
||||
EVP_DigestUpdate(ctxp, key->key.keyvalue.data, key->key.keyvalue.length);
|
||||
EVP_DigestFinal_ex(ctxp, sessionkey, NULL);
|
||||
EVP_MD_CTX_destroy(ctxp);
|
||||
}
|
||||
}
|
||||
|
||||
ntp.success = 1;
|
||||
|
||||
ASN1_MALLOC_ENCODE(NTLMReply, rep.data, rep.length, &ntp, &size, ret);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (rep.length != size)
|
||||
abort();
|
||||
|
||||
failed:
|
||||
kdc_log(context, config, 4, "digest-request: %d", ret);
|
||||
|
||||
(*complete)(cctx, ret, &rep);
|
||||
|
||||
free(rep.data);
|
||||
|
||||
free_NTLMRequest2(&ntq);
|
||||
if (user)
|
||||
_kdc_free_ent (context, db, user);
|
||||
}
|
||||
|
||||
static int help_flag;
|
||||
static int version_flag;
|
||||
|
||||
static struct getargs args[] = {
|
||||
{ "help", 'h', arg_flag, &help_flag, NULL, NULL },
|
||||
{ "version", 'v', arg_flag, &version_flag, NULL, NULL }
|
||||
};
|
||||
|
||||
static int num_args = sizeof(args) / sizeof(args[0]);
|
||||
|
||||
static void
|
||||
usage(int ret)
|
||||
{
|
||||
arg_printusage (args, num_args, NULL, "");
|
||||
exit (ret);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
krb5_context context;
|
||||
int ret, optidx = 0;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
if (getarg(args, num_args, argc, argv, &optidx))
|
||||
usage(1);
|
||||
|
||||
if (help_flag)
|
||||
usage(0);
|
||||
|
||||
if (version_flag) {
|
||||
print_version(NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
ret = krb5_init_context(&context);
|
||||
if (ret)
|
||||
krb5_errx(context, 1, "krb5_init_context");
|
||||
|
||||
ret = krb5_kdc_get_config(context, &config);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_kdc_default_config");
|
||||
|
||||
kdc_openlog(context, "digest-service", config);
|
||||
|
||||
ret = krb5_kdc_set_dbinfo(context, config);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo");
|
||||
|
||||
#if __APPLE__
|
||||
{
|
||||
heim_sipc mach;
|
||||
heim_sipc_launchd_mach_init("org.h5l.ntlm-service",
|
||||
ntlm_service, context, &mach);
|
||||
heim_sipc_timeout(60);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_DOOR_CREATE
|
||||
{
|
||||
heim_sipc door;
|
||||
heim_sipc_service_door("org.h5l.ntlm-service", ntlm_service, NULL, &door);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
heim_sipc un;
|
||||
heim_sipc_service_unix("org.h5l.ntlm-service", ntlm_service, NULL, &un);
|
||||
}
|
||||
|
||||
heim_ipc_main();
|
||||
return 0;
|
||||
}
|
||||
-1520
File diff suppressed because it is too large
Load Diff
+14
@@ -47,6 +47,8 @@ static int decrypt_flag;
|
||||
static hdb_master_key mkey5;
|
||||
|
||||
static char *source_type;
|
||||
static char *ossl_cnf;
|
||||
static char *ossl_propq;
|
||||
|
||||
static char *local_realm=NULL;
|
||||
|
||||
@@ -143,6 +145,12 @@ struct getargs args[] = {
|
||||
{ "encrypt", 'E', arg_flag, &encrypt_flag, "encrypt keys", NULL },
|
||||
{ "stdout", 'n', arg_flag, &to_stdout, "dump to stdout", NULL },
|
||||
{ "verbose", 'v', arg_flag, &verbose_flag, NULL, NULL },
|
||||
{ "ossl-cnf", 0, arg_string, &ossl_cnf,
|
||||
"OpenSSL configuration file", "FILE"
|
||||
},
|
||||
{ "ossl-propq", 0, arg_string, &ossl_propq,
|
||||
"OpenSSL property query string (e.g., provider=pkcs11)", "PROPQ"
|
||||
},
|
||||
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
||||
{ "help", 'h', arg_flag, &help_flag, NULL, NULL }
|
||||
};
|
||||
@@ -422,6 +430,12 @@ main(int argc, char **argv)
|
||||
if(ret)
|
||||
exit(1);
|
||||
|
||||
if (ossl_cnf || ossl_propq) {
|
||||
ret = krb5_set_ossl_cnf_propq(context, ossl_cnf, ossl_propq);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_set_ossl_cnf_propq");
|
||||
}
|
||||
|
||||
/* We may be reading an old database encrypted with a DES master key. */
|
||||
ret = krb5_allow_weak_crypto(context, 1);
|
||||
if(ret)
|
||||
|
||||
@@ -41,6 +41,8 @@ static const char *database;
|
||||
static int from_stdin;
|
||||
static char *local_realm;
|
||||
static char *ktname = NULL;
|
||||
static char *ossl_cnf = NULL;
|
||||
static char *ossl_propq = NULL;
|
||||
|
||||
struct getargs args[] = {
|
||||
{ "database", 'd', arg_string, rk_UNCONST(&database), "database", "file" },
|
||||
@@ -52,6 +54,12 @@ struct getargs args[] = {
|
||||
#endif
|
||||
{ "keytab", 'k', arg_string, &ktname, "keytab to use for authentication", "keytab" },
|
||||
{ "realm", 'r', arg_string, &local_realm, "realm to use", NULL },
|
||||
{ "ossl-cnf", 0, arg_string, &ossl_cnf,
|
||||
"OpenSSL configuration file", "FILE"
|
||||
},
|
||||
{ "ossl-propq", 0, arg_string, &ossl_propq,
|
||||
"OpenSSL property query string (e.g., provider=pkcs11)", "PROPQ"
|
||||
},
|
||||
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
||||
{ "help", 'h', arg_flag, &help_flag, NULL, NULL}
|
||||
};
|
||||
@@ -112,6 +120,12 @@ main(int argc, char **argv)
|
||||
if (argc != 0)
|
||||
usage(1);
|
||||
|
||||
if (ossl_cnf || ossl_propq) {
|
||||
ret = krb5_set_ossl_cnf_propq(context, ossl_cnf, ossl_propq);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_set_ossl_cnf_propq");
|
||||
}
|
||||
|
||||
if (database == NULL)
|
||||
database = hdb_default_db(context);
|
||||
|
||||
|
||||
+36
-22
@@ -353,6 +353,8 @@ static const char *writable_kadmin_server;
|
||||
static const char *stash_file;
|
||||
static const char *kadmin_client_name = "httpkadmind/admin";
|
||||
static const char *kadmin_client_keytab;
|
||||
static const char *ossl_cnf;
|
||||
static const char *ossl_propq;
|
||||
static struct getarg_strings auth_types;
|
||||
|
||||
#define set_conf(c, f, v, b) \
|
||||
@@ -1923,9 +1925,9 @@ mac_csrf_token(kadmin_request_desc r, krb5_storage *sp)
|
||||
krb5_error_code ret;
|
||||
krb5_principal p = NULL;
|
||||
krb5_data data;
|
||||
char mac[EVP_MAX_MD_SIZE];
|
||||
unsigned int maclen = sizeof(mac);
|
||||
HMAC_CTX *ctx = NULL;
|
||||
unsigned char mac[EVP_MAX_MD_SIZE];
|
||||
size_t maclen = sizeof(mac);
|
||||
EVP_MAC_CTX *ctx = NULL;
|
||||
size_t i = 0;
|
||||
int freeit = 0;
|
||||
|
||||
@@ -1955,32 +1957,32 @@ mac_csrf_token(kadmin_request_desc r, krb5_storage *sp)
|
||||
if (ret == 0 && i == princ.n_key_data)
|
||||
i = 0; /* Weird, but can't happen */
|
||||
|
||||
if (ret == 0 && (ctx = HMAC_CTX_new()) == NULL)
|
||||
ret = krb5_enomem(r->context);
|
||||
/* HMAC the token body and the client principal name */
|
||||
if (ret == 0)
|
||||
ret = _krb5_hmac_start_ossl(r->context,
|
||||
princ.key_data[i].key_data_contents[0],
|
||||
princ.key_data[i].key_data_length[0],
|
||||
EVP_sha256(), &ctx);
|
||||
if (ret == 0)
|
||||
ret = (EVP_MAC_update(ctx, data.data, data.length) == 1) ? 0 : EINVAL;
|
||||
if (ret == 0)
|
||||
ret = (EVP_MAC_update(ctx,
|
||||
(unsigned char *)r->cname,
|
||||
strlen(r->cname)) == 1) ? 0 : EINVAL;
|
||||
if (ret == 0)
|
||||
ret = (EVP_MAC_final(ctx, mac, &maclen, maclen) == 1) ? 0 : EINVAL;
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
|
||||
krb5_data_free(&data);
|
||||
data.length = maclen;
|
||||
data.data = mac;
|
||||
if (ret == 0) {
|
||||
if (HMAC_Init_ex(ctx, princ.key_data[i].key_data_contents[0],
|
||||
princ.key_data[i].key_data_length[0], EVP_sha256(),
|
||||
NULL) == 0) {
|
||||
HMAC_CTX_cleanup(ctx);
|
||||
if (krb5_storage_write(sp, mac, maclen) != maclen)
|
||||
ret = krb5_enomem(r->context);
|
||||
} else {
|
||||
HMAC_Update(ctx, data.data, data.length);
|
||||
HMAC_Update(ctx, r->cname, strlen(r->cname));
|
||||
HMAC_Final(ctx, mac, &maclen);
|
||||
HMAC_CTX_cleanup(ctx);
|
||||
krb5_data_free(&data);
|
||||
data.length = maclen;
|
||||
data.data = mac;
|
||||
if (krb5_storage_write(sp, mac, maclen) != maclen)
|
||||
ret = krb5_enomem(r->context);
|
||||
}
|
||||
}
|
||||
krb5_free_principal(r->context, p);
|
||||
if (freeit)
|
||||
kadm5_free_principal_ent(r->kadm_handle, &princ);
|
||||
if (ctx)
|
||||
HMAC_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2343,6 +2345,12 @@ static struct getargs args[] = {
|
||||
"Keytab with client credentials for remote kadmind", "KEYTAB" },
|
||||
{ "token-authentication-type", 'T', arg_strings, &auth_types,
|
||||
"Token authentication type(s) supported", "HTTP-AUTH-TYPE" },
|
||||
{ "ossl-cnf", 0, arg_string, &ossl_cnf,
|
||||
"OpenSSL configuration file", "FILE"
|
||||
},
|
||||
{ "ossl-propq", 0, arg_string, &ossl_propq,
|
||||
"OpenSSL property query string (e.g., provider=pkcs11)", "PROPQ"
|
||||
},
|
||||
{ "verbose", 'v', arg_counter, &verbose_counter, "verbose", "run verbosely" }
|
||||
};
|
||||
|
||||
@@ -2549,6 +2557,12 @@ main(int argc, char **argv)
|
||||
if ((errno = get_krb5_context(&context)))
|
||||
err(1, "Could not init krb5 context (config file issue?)");
|
||||
|
||||
if (ossl_cnf || ossl_propq) {
|
||||
ret = krb5_set_ossl_cnf_propq(context, ossl_cnf, ossl_propq);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_set_ossl_cnf_propq");
|
||||
}
|
||||
|
||||
get_csrf_prot_type(context);
|
||||
|
||||
if (!realm) {
|
||||
|
||||
@@ -231,8 +231,6 @@ extern int do_bonjour;
|
||||
|
||||
extern int testing_flag;
|
||||
|
||||
extern const struct units _kdc_digestunits[];
|
||||
|
||||
#define KDC_LOG_FILE "kdc.log"
|
||||
|
||||
extern struct timeval _kdc_now;
|
||||
|
||||
+2
-2
@@ -124,8 +124,8 @@ main(int argc, char **argv)
|
||||
buf[strcspn(buf, "\r\n")] = '\0';
|
||||
|
||||
} else {
|
||||
if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Master key: ",
|
||||
UI_UTIL_FLAG_VERIFY))
|
||||
if (_krb5_UI_UTIL_read_pw_string(buf, sizeof(buf), "Master key: ",
|
||||
UI_UTIL_FLAG_VERIFY))
|
||||
exit(1);
|
||||
}
|
||||
krb5_string_to_key_salt(context, enctype, buf, salt, &key);
|
||||
|
||||
+51
-38
@@ -147,7 +147,9 @@ verify_req_hash(krb5_context context,
|
||||
krb5_keyblock *key)
|
||||
{
|
||||
unsigned char digest[SHA_DIGEST_LENGTH];
|
||||
HMAC_CTX ctx;
|
||||
EVP_MAC_CTX *ctx = NULL;
|
||||
size_t maclen = SHA_DIGEST_LENGTH;
|
||||
int ret;
|
||||
|
||||
if (req->pk_hash.length != sizeof(digest)) {
|
||||
krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
|
||||
@@ -156,21 +158,29 @@ verify_req_hash(krb5_context context,
|
||||
return KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
}
|
||||
|
||||
HMAC_CTX_init(&ctx);
|
||||
if (HMAC_Init_ex(&ctx, key->keyvalue.data, key->keyvalue.length,
|
||||
EVP_sha1(), NULL) == 0) {
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
return krb5_enomem(context);
|
||||
ret = _krb5_hmac_start_ossl(context, key->keyvalue.data, key->keyvalue.length,
|
||||
EVP_sha1(), &ctx);
|
||||
if (ret == 0 &&
|
||||
EVP_MAC_update(ctx, version_2_0, sizeof(version_2_0)) != 1) {
|
||||
ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
}
|
||||
if (ret == 0 && req->pk_key.length) {
|
||||
if (EVP_MAC_update(ctx, req->pk_key.data, req->pk_key.length) != 1)
|
||||
ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
} else if (ret == 0) {
|
||||
if (EVP_MAC_update(ctx, req->authenticator.data,
|
||||
req->authenticator.length) != 1)
|
||||
ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
}
|
||||
if (ret == 0 &&
|
||||
EVP_MAC_final(ctx, digest, &maclen, maclen) != 1)
|
||||
ret = KRB5KDC_ERR_PREAUTH_FAILED;
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
|
||||
"kx509 could not compute HMAC");
|
||||
return ret;
|
||||
}
|
||||
if (sizeof(digest) != HMAC_size(&ctx))
|
||||
krb5_abortx(context, "runtime error, hmac buffer wrong size in kx509");
|
||||
HMAC_Update(&ctx, version_2_0, sizeof(version_2_0));
|
||||
if (req->pk_key.length)
|
||||
HMAC_Update(&ctx, req->pk_key.data, req->pk_key.length);
|
||||
else
|
||||
HMAC_Update(&ctx, req->authenticator.data, req->authenticator.length);
|
||||
HMAC_Final(&ctx, digest, 0);
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
|
||||
if (ct_memcmp(req->pk_hash.data, digest, sizeof(digest)) != 0) {
|
||||
krb5_set_error_message(context, KRB5KDC_ERR_PREAUTH_FAILED,
|
||||
@@ -188,24 +198,20 @@ calculate_reply_hash(krb5_context context,
|
||||
krb5_keyblock *key,
|
||||
Kx509Response *rep)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
HMAC_CTX ctx;
|
||||
krb5_error_code ret;
|
||||
EVP_MAC_CTX *ctx = NULL;
|
||||
size_t maclen = SHA_DIGEST_LENGTH;
|
||||
|
||||
HMAC_CTX_init(&ctx);
|
||||
|
||||
if (HMAC_Init_ex(&ctx, key->keyvalue.data, key->keyvalue.length,
|
||||
EVP_sha1(), NULL) == 0)
|
||||
ret = _krb5_hmac_start_ossl(context, key->keyvalue.data, key->keyvalue.length,
|
||||
EVP_sha1(), &ctx);
|
||||
if (ret)
|
||||
ret = krb5_enomem(context);
|
||||
|
||||
if (ret == 0)
|
||||
ret = krb5_data_alloc(rep->hash, HMAC_size(&ctx));
|
||||
if (ret) {
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
return krb5_enomem(context);
|
||||
}
|
||||
|
||||
HMAC_Update(&ctx, version_2_0, sizeof(version_2_0));
|
||||
{
|
||||
ret = krb5_data_alloc(rep->hash, SHA_DIGEST_LENGTH);
|
||||
if (ret == 0 &&
|
||||
EVP_MAC_update(ctx, version_2_0, sizeof(version_2_0)) != 1)
|
||||
ret = EINVAL;
|
||||
if (ret == 0) {
|
||||
int32_t t = rep->error_code;
|
||||
unsigned char encint[sizeof(t) + 1];
|
||||
size_t k;
|
||||
@@ -224,16 +230,23 @@ calculate_reply_hash(krb5_context context,
|
||||
*/
|
||||
ret = der_put_integer(&encint[sizeof(encint) - 1],
|
||||
sizeof(encint), &t, &k);
|
||||
if (ret == 0)
|
||||
HMAC_Update(&ctx, &encint[sizeof(encint)] - k, k);
|
||||
if (ret == 0 &&
|
||||
EVP_MAC_update(ctx, &encint[sizeof(encint)] - k, k) != 1)
|
||||
ret = EINVAL;
|
||||
}
|
||||
if (rep->certificate)
|
||||
HMAC_Update(&ctx, rep->certificate->data, rep->certificate->length);
|
||||
if (rep->e_text)
|
||||
HMAC_Update(&ctx, (unsigned char *)*rep->e_text, strlen(*rep->e_text));
|
||||
if (ret == 0 && rep->certificate &&
|
||||
EVP_MAC_update(ctx, rep->certificate->data,
|
||||
rep->certificate->length) != 1)
|
||||
ret = EINVAL;
|
||||
if (ret == 0 && rep->e_text &&
|
||||
EVP_MAC_update(ctx, (unsigned char *)*rep->e_text,
|
||||
strlen(*rep->e_text)) != 1)
|
||||
ret = EINVAL;
|
||||
|
||||
HMAC_Final(&ctx, rep->hash->data, 0);
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
if (ret == 0 &&
|
||||
EVP_MAC_final(ctx, rep->hash->data, &maclen, maclen) != 1)
|
||||
ret = EINVAL;
|
||||
EVP_MAC_CTX_free(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-525
@@ -1,525 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. 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 <config.h>
|
||||
#include <roken.h>
|
||||
|
||||
#ifdef PKINIT
|
||||
|
||||
/*
|
||||
* As with the other *-ec.c files in Heimdal, this is a bit of a hack.
|
||||
*
|
||||
* XXX This is no longer relevant now that we've removed hcrypto.
|
||||
*
|
||||
* The idea _was_ to use OpenSSL for EC because hcrypto doesn't have the
|
||||
* required functionality at this time. To do this we segregate
|
||||
* EC-using code into separate source files and then we arrange for them
|
||||
* to get the OpenSSL headers and not the conflicting hcrypto ones.
|
||||
*
|
||||
* Because of auto-generated *-private.h headers, we end up needing to
|
||||
* make sure various types are defined before we include them, thus the
|
||||
* strange header include order here.
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/objects.h>
|
||||
#ifdef HAVE_OPENSSL_30
|
||||
#include <openssl/core_names.h>
|
||||
#endif
|
||||
#define HEIM_NO_CRYPTO_HDRS
|
||||
|
||||
#include "kdc_locl.h"
|
||||
#include <heim_asn1.h>
|
||||
#include <rfc2459_asn1.h>
|
||||
#include <cms_asn1.h>
|
||||
#include <pkinit_asn1.h>
|
||||
|
||||
#include <hx509.h>
|
||||
#include "../lib/hx509/hx_locl.h"
|
||||
#include <hx509-private.h>
|
||||
|
||||
void
|
||||
_kdc_pk_free_client_ec_param(krb5_context context,
|
||||
void *k0,
|
||||
void *k1)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_30
|
||||
EVP_PKEY_free(k0);
|
||||
EVP_PKEY_free(k1);
|
||||
#else
|
||||
EC_KEY_free(k0);
|
||||
EC_KEY_free(k1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_30
|
||||
static krb5_error_code
|
||||
generate_ecdh_keyblock_ossl30(krb5_context context,
|
||||
EVP_PKEY *ec_key_pub, /* the client's public key */
|
||||
EVP_PKEY **ec_key_priv, /* the KDC's ephemeral private */
|
||||
unsigned char **dh_gen_key, /* shared secret */
|
||||
size_t *dh_gen_keylen)
|
||||
{
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *ephemeral = NULL;
|
||||
krb5_error_code ret = 0;
|
||||
unsigned char *p = NULL;
|
||||
size_t size = 0;
|
||||
|
||||
if (ec_key_pub == NULL)
|
||||
/* XXX This seems like an internal error that should be impossible */
|
||||
krb5_set_error_message(context, ret = KRB5KRB_ERR_GENERIC,
|
||||
"Missing client ECDH key agreement public key");
|
||||
if (ret == 0 &&
|
||||
(ephemeral =
|
||||
EVP_EC_gen(OSSL_EC_curve_nid2name(NID_X9_62_prime256v1))) == NULL)
|
||||
krb5_set_error_message(context, ret = KRB5KRB_ERR_GENERIC,
|
||||
"Could not generate an ECDH key agreement private key");
|
||||
if (ret == 0 &&
|
||||
(pctx = EVP_PKEY_CTX_new(ephemeral, NULL)) == NULL)
|
||||
ret = krb5_enomem(context);
|
||||
if (ret == 0 && EVP_PKEY_derive_init(pctx) != 1)
|
||||
ret = krb5_enomem(context);
|
||||
if (ret == 0 &&
|
||||
EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_NONE) != 1)
|
||||
krb5_set_error_message(context, ret = KRB5KRB_ERR_GENERIC,
|
||||
"Could not generate an ECDH key agreement private key "
|
||||
"(EVP_PKEY_CTX_set_dh_kdf_type)");
|
||||
if (ret == 0 &&
|
||||
EVP_PKEY_derive_set_peer_ex(pctx, ec_key_pub, 1) != 1)
|
||||
krb5_set_error_message(context, ret = KRB5KRB_ERR_GENERIC,
|
||||
"Could not generate an ECDH key agreement private key "
|
||||
"(EVP_PKEY_derive_set_peer_ex)");
|
||||
if (ret == 0 &&
|
||||
(EVP_PKEY_derive(pctx, NULL, &size) != 1 || size == 0))
|
||||
krb5_set_error_message(context, ret = KRB5KRB_ERR_GENERIC,
|
||||
"Could not generate an ECDH key agreement private key "
|
||||
"(EVP_PKEY_derive)");
|
||||
if (ret == 0 && (p = malloc(size)) == NULL)
|
||||
ret = krb5_enomem(context);
|
||||
if (ret == 0 &&
|
||||
(EVP_PKEY_derive(pctx, p, &size) != 1 || size == 0))
|
||||
krb5_set_error_message(context, ret = KRB5KRB_ERR_GENERIC,
|
||||
"Could not generate an ECDH key agreement private key "
|
||||
"(EVP_PKEY_derive)");
|
||||
|
||||
if (ret) {
|
||||
EVP_PKEY_free(ephemeral);
|
||||
ephemeral = NULL;
|
||||
free(p);
|
||||
p = NULL;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
*ec_key_priv = ephemeral;
|
||||
*dh_gen_keylen = size;
|
||||
*dh_gen_key = p;
|
||||
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
|
||||
/* The empty line above is intentional to work around an mkproto bug */
|
||||
static krb5_error_code
|
||||
generate_ecdh_keyblock_ossl11(krb5_context context,
|
||||
EC_KEY *ec_key_pk, /* the client's public key */
|
||||
EC_KEY **ec_key_key, /* the KDC's ephemeral private */
|
||||
unsigned char **dh_gen_key, /* shared secret */
|
||||
size_t *dh_gen_keylen)
|
||||
{
|
||||
const EC_GROUP *group;
|
||||
EC_KEY *ephemeral;
|
||||
krb5_keyblock key;
|
||||
krb5_error_code ret;
|
||||
unsigned char *p;
|
||||
size_t size;
|
||||
int len;
|
||||
|
||||
*dh_gen_key = NULL;
|
||||
*dh_gen_keylen = 0;
|
||||
*ec_key_key = NULL;
|
||||
|
||||
memset(&key, 0, sizeof(key));
|
||||
|
||||
if (ec_key_pk == NULL) {
|
||||
ret = KRB5KRB_ERR_GENERIC;
|
||||
krb5_set_error_message(context, ret, "public_key");
|
||||
return ret;
|
||||
}
|
||||
|
||||
group = EC_KEY_get0_group(ec_key_pk);
|
||||
if (group == NULL) {
|
||||
ret = KRB5KRB_ERR_GENERIC;
|
||||
krb5_set_error_message(context, ret, "failed to get the group of "
|
||||
"the client's public key");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ephemeral = EC_KEY_new();
|
||||
if (ephemeral == NULL)
|
||||
return krb5_enomem(context);
|
||||
|
||||
EC_KEY_set_group(ephemeral, group);
|
||||
|
||||
if (EC_KEY_generate_key(ephemeral) != 1) {
|
||||
EC_KEY_free(ephemeral);
|
||||
return krb5_enomem(context);
|
||||
}
|
||||
|
||||
size = (EC_GROUP_get_degree(group) + 7) / 8;
|
||||
p = malloc(size);
|
||||
if (p == NULL) {
|
||||
EC_KEY_free(ephemeral);
|
||||
return krb5_enomem(context);
|
||||
}
|
||||
|
||||
len = ECDH_compute_key(p, size,
|
||||
EC_KEY_get0_public_key(ec_key_pk),
|
||||
ephemeral, NULL);
|
||||
if (len <= 0) {
|
||||
free(p);
|
||||
EC_KEY_free(ephemeral);
|
||||
ret = KRB5KRB_ERR_GENERIC;
|
||||
krb5_set_error_message(context, ret, "Failed to compute ECDH "
|
||||
"public shared secret");
|
||||
return ret;
|
||||
}
|
||||
|
||||
*ec_key_key = ephemeral;
|
||||
*dh_gen_key = p;
|
||||
*dh_gen_keylen = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
krb5_error_code
|
||||
_kdc_generate_ecdh_keyblock(krb5_context context,
|
||||
void *ec_key_pk, /* the client's public key */
|
||||
void **ec_key_key, /* the KDC's ephemeral private */
|
||||
unsigned char **dh_gen_key, /* shared secret */
|
||||
size_t *dh_gen_keylen)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_30
|
||||
return generate_ecdh_keyblock_ossl30(context, ec_key_pk,
|
||||
(EVP_PKEY **)ec_key_key,
|
||||
dh_gen_key, dh_gen_keylen);
|
||||
#else
|
||||
return generate_ecdh_keyblock_ossl11(context, ec_key_pk,
|
||||
(EC_KEY **)ec_key_key,
|
||||
dh_gen_key, dh_gen_keylen);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_30
|
||||
static krb5_error_code
|
||||
get_ecdh_param_ossl30(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
SubjectPublicKeyInfo *dh_key_info,
|
||||
EVP_PKEY **out)
|
||||
{
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *template = NULL;
|
||||
EVP_PKEY *public = NULL;
|
||||
OSSL_PARAM params[2];
|
||||
krb5_error_code ret = 0;
|
||||
ECParameters ecp;
|
||||
const unsigned char *p;
|
||||
const char *curve_sn = NULL;
|
||||
size_t len;
|
||||
char *curve_sn_dup = NULL;
|
||||
int groupnid = NID_undef;
|
||||
|
||||
/* XXX Algorithm agility; XXX KRB5_BADMSGTYPE?? */
|
||||
|
||||
/*
|
||||
* In order for d2i_PublicKey() to work we need to create a template key
|
||||
* that has the curve parameters for the subjectPublicKey.
|
||||
*
|
||||
* Or maybe we could learn to use the OSSL_DECODER(3) API. But this works,
|
||||
* at least until OpenSSL deprecates d2i_PublicKey() and forces us to use
|
||||
* OSSL_DECODER(3).
|
||||
*/
|
||||
|
||||
memset(&ecp, 0, sizeof(ecp));
|
||||
|
||||
if (dh_key_info->algorithm.parameters == NULL)
|
||||
krb5_set_error_message(context, ret = KRB5_BADMSGTYPE,
|
||||
"PKINIT missing algorithm parameter "
|
||||
"in clientPublicValue");
|
||||
if (ret == 0)
|
||||
ret = decode_ECParameters(dh_key_info->algorithm.parameters->data,
|
||||
dh_key_info->algorithm.parameters->length,
|
||||
&ecp, &len);
|
||||
if (ret == 0 && ecp.element != choice_ECParameters_namedCurve)
|
||||
krb5_set_error_message(context, ret = KRB5_BADMSGTYPE,
|
||||
"PKINIT client used an unnamed curve");
|
||||
if (ret == 0 &&
|
||||
(groupnid = _hx509_ossl_oid2nid(&ecp.u.namedCurve)) == NID_undef)
|
||||
krb5_set_error_message(context, ret = KRB5_BADMSGTYPE,
|
||||
"PKINIT client used an unsupported curve");
|
||||
if (ret == 0 && (curve_sn = OBJ_nid2sn(groupnid)) == NULL)
|
||||
krb5_set_error_message(context, ret = KRB5_BADMSGTYPE,
|
||||
"Could not resolve curve NID %d to its short name",
|
||||
groupnid);
|
||||
if (ret == 0 && (curve_sn_dup = strdup(curve_sn)) == NULL)
|
||||
ret = krb5_enomem(context);
|
||||
if (ret == 0) {
|
||||
if (der_heim_oid_cmp(&ecp.u.namedCurve, &asn1_oid_id_ec_group_secp256r1) != 0)
|
||||
krb5_set_error_message(context, ret = KRB5_BADMSGTYPE,
|
||||
"PKINIT client used an unsupported curve");
|
||||
}
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* Apparently there's no error checking to be done here? Why does
|
||||
* OSSL_PARAM_construct_utf8_string() want a non-const for the value?
|
||||
* Is that a bug in OpenSSL?
|
||||
*/
|
||||
params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
|
||||
curve_sn_dup, 0);
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
if ((pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL)
|
||||
ret = krb5_enomem(context);
|
||||
}
|
||||
if (ret == 0 && EVP_PKEY_fromdata_init(pctx) != 1)
|
||||
ret = krb5_enomem(context);
|
||||
if (ret == 0 &&
|
||||
EVP_PKEY_fromdata(pctx, &template, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
|
||||
params) != 1)
|
||||
krb5_set_error_message(context, ret = KRB5_BADMSGTYPE,
|
||||
"Could not set up to parse key for curve %s",
|
||||
curve_sn);
|
||||
|
||||
p = dh_key_info->subjectPublicKey.data;
|
||||
len = dh_key_info->subjectPublicKey.length / 8;
|
||||
if (ret == 0 &&
|
||||
(public = d2i_PublicKey(EVP_PKEY_EC, &template, &p, len)) == NULL)
|
||||
krb5_set_error_message(context, ret = KRB5_BADMSGTYPE,
|
||||
"Could not decode PKINIT client ECDH key");
|
||||
|
||||
if (ret) {
|
||||
EVP_PKEY_free(public);
|
||||
public = NULL;
|
||||
}
|
||||
|
||||
*out = public;
|
||||
|
||||
/* FYI the EVP_PKEY_CTX takes ownership of the `template' key */
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
free_ECParameters(&ecp);
|
||||
free(curve_sn_dup);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
|
||||
static krb5_error_code
|
||||
get_ecdh_param_ossl11(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
SubjectPublicKeyInfo *dh_key_info,
|
||||
EC_KEY **out)
|
||||
{
|
||||
ECParameters ecp;
|
||||
EC_KEY *public = NULL;
|
||||
krb5_error_code ret;
|
||||
const unsigned char *p;
|
||||
size_t len;
|
||||
int nid;
|
||||
|
||||
if (dh_key_info->algorithm.parameters == NULL) {
|
||||
krb5_set_error_message(context, KRB5_BADMSGTYPE,
|
||||
"PKINIT missing algorithm parameter "
|
||||
"in clientPublicValue");
|
||||
return KRB5_BADMSGTYPE;
|
||||
}
|
||||
/* XXX Algorithm agility; XXX KRB5_BADMSGTYPE?? */
|
||||
|
||||
memset(&ecp, 0, sizeof(ecp));
|
||||
|
||||
ret = decode_ECParameters(dh_key_info->algorithm.parameters->data,
|
||||
dh_key_info->algorithm.parameters->length, &ecp, &len);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (ecp.element != choice_ECParameters_namedCurve) {
|
||||
ret = KRB5_BADMSGTYPE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (der_heim_oid_cmp(&ecp.u.namedCurve, &asn1_oid_id_ec_group_secp256r1) == 0)
|
||||
nid = NID_X9_62_prime256v1;
|
||||
else {
|
||||
ret = KRB5_BADMSGTYPE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* XXX verify group is ok */
|
||||
|
||||
public = EC_KEY_new_by_curve_name(nid);
|
||||
|
||||
p = dh_key_info->subjectPublicKey.data;
|
||||
len = dh_key_info->subjectPublicKey.length / 8;
|
||||
if (o2i_ECPublicKey(&public, &p, len) == NULL) {
|
||||
ret = KRB5_BADMSGTYPE;
|
||||
krb5_set_error_message(context, ret,
|
||||
"PKINIT failed to decode ECDH key");
|
||||
goto out;
|
||||
}
|
||||
*out = public;
|
||||
public = NULL;
|
||||
|
||||
out:
|
||||
if (public)
|
||||
EC_KEY_free(public);
|
||||
free_ECParameters(&ecp);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
krb5_error_code
|
||||
_kdc_get_ecdh_param(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
SubjectPublicKeyInfo *dh_key_info,
|
||||
void **out)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_30
|
||||
return get_ecdh_param_ossl30(context, config, dh_key_info, (EVP_PKEY **)out);
|
||||
#else
|
||||
return get_ecdh_param_ossl11(context, config, dh_key_info, (EC_KEY **)out);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_OPENSSL_30
|
||||
static krb5_error_code
|
||||
serialize_ecdh_key_ossl30(krb5_context context,
|
||||
EVP_PKEY *key,
|
||||
unsigned char **out,
|
||||
size_t *out_len)
|
||||
{
|
||||
unsigned char *p;
|
||||
int len;
|
||||
|
||||
*out = NULL;
|
||||
*out_len = 0;
|
||||
|
||||
len = i2d_PublicKey(key, NULL);
|
||||
if (len <= 0) {
|
||||
krb5_set_error_message(context, EOVERFLOW,
|
||||
"PKINIT failed to encode ECDH key");
|
||||
return EOVERFLOW;
|
||||
}
|
||||
|
||||
*out = malloc(len);
|
||||
if (*out == NULL)
|
||||
return krb5_enomem(context);
|
||||
|
||||
p = *out;
|
||||
len = i2d_PublicKey(key, &p);
|
||||
if (len <= 0) {
|
||||
free(*out);
|
||||
*out = NULL;
|
||||
krb5_set_error_message(context, EINVAL /* XXX Better error please */,
|
||||
"PKINIT failed to encode ECDH key");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*out_len = len * 8;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
static krb5_error_code
|
||||
serialize_ecdh_key_ossl11(krb5_context context,
|
||||
EC_KEY *key,
|
||||
unsigned char **out,
|
||||
size_t *out_len)
|
||||
{
|
||||
unsigned char *p;
|
||||
int len;
|
||||
|
||||
*out = NULL;
|
||||
*out_len = 0;
|
||||
|
||||
len = i2o_ECPublicKey(key, NULL);
|
||||
if (len <= 0) {
|
||||
krb5_set_error_message(context, EOVERFLOW,
|
||||
"PKINIT failed to encode ECDH key");
|
||||
return EOVERFLOW;
|
||||
}
|
||||
|
||||
*out = malloc(len);
|
||||
if (*out == NULL)
|
||||
return krb5_enomem(context);
|
||||
|
||||
p = *out;
|
||||
len = i2o_ECPublicKey(key, &p);
|
||||
if (len <= 0) {
|
||||
free(*out);
|
||||
*out = NULL;
|
||||
krb5_set_error_message(context, EINVAL /* XXX Better error please */,
|
||||
"PKINIT failed to encode ECDH key");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*out_len = len * 8;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
krb5_error_code
|
||||
_kdc_serialize_ecdh_key(krb5_context context,
|
||||
void *key,
|
||||
unsigned char **out,
|
||||
size_t *out_len)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_30
|
||||
return serialize_ecdh_key_ossl30(context, key, out, out_len);
|
||||
#else
|
||||
return serialize_ecdh_key_ossl11(context, key, out, out_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
+748
-342
File diff suppressed because it is too large
Load Diff
@@ -301,34 +301,6 @@ kdc_tgs_req(kdc_request_t *rptr, int *claim)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef DIGEST
|
||||
|
||||
static krb5_error_code
|
||||
kdc_digest(kdc_request_t *rptr, int *claim)
|
||||
{
|
||||
kdc_request_t r;
|
||||
DigestREQ digestreq;
|
||||
krb5_error_code ret;
|
||||
size_t len;
|
||||
|
||||
r = *rptr;
|
||||
|
||||
ret = decode_DigestREQ(r->request.data, r->request.length,
|
||||
&digestreq, &len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
r->use_request_t = 0;
|
||||
*claim = 1;
|
||||
|
||||
ret = _kdc_do_digest(r->context, r->config, &digestreq,
|
||||
r->reply, r->from, r->addr);
|
||||
free_DigestREQ(&digestreq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef KX509
|
||||
|
||||
static krb5_error_code
|
||||
@@ -357,9 +329,6 @@ kdc_kx509(kdc_request_t *rptr, int *claim)
|
||||
static struct krb5_kdc_service services[] = {
|
||||
{ KS_KRB5, "AS-REQ", kdc_as_req },
|
||||
{ KS_KRB5, "TGS-REQ", kdc_tgs_req },
|
||||
#ifdef DIGEST
|
||||
{ 0, "DIGEST", kdc_digest },
|
||||
#endif
|
||||
#ifdef KX509
|
||||
{ 0, "KX509", kdc_kx509 },
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -157,7 +157,7 @@ main(int argc, char **argv)
|
||||
if(argv[0])
|
||||
password = argv[0];
|
||||
if(password == NULL){
|
||||
if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Password: ", 0))
|
||||
if (_krb5_UI_UTIL_read_pw_string(buf, sizeof(buf), "Password: ", 0))
|
||||
return 1;
|
||||
password = buf;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,16 @@
|
||||
|
||||
include $(top_srcdir)/Makefile.am.common
|
||||
|
||||
AM_CPPFLAGS += -I$(srcdir)/../lib/krb5
|
||||
|
||||
man_MANS = kpasswd.1 kpasswdd.8
|
||||
|
||||
bin_PROGRAMS = kpasswd
|
||||
|
||||
kpasswd_SOURCES = kpasswd.c kpasswd_locl.h
|
||||
|
||||
kpasswd_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/../lib/krb5
|
||||
|
||||
libexec_PROGRAMS = kpasswdd
|
||||
|
||||
noinst_PROGRAMS = kpasswd-generator
|
||||
|
||||
+2
-2
@@ -83,8 +83,8 @@ change_password(krb5_context context,
|
||||
if (aret == -1 || msg == NULL)
|
||||
krb5_errx (context, 1, "out of memory");
|
||||
|
||||
ret = UI_UTIL_read_pw_string (pwbuf, sizeof(pwbuf), msg,
|
||||
UI_UTIL_FLAG_VERIFY);
|
||||
ret = _krb5_UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), msg,
|
||||
UI_UTIL_FLAG_VERIFY);
|
||||
free(msg);
|
||||
if (name)
|
||||
free(name);
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
#include <err.h>
|
||||
#include <getarg.h>
|
||||
#include <krb5.h>
|
||||
#include <krb5_locl.h>
|
||||
#include "crypto-headers.h" /* for des_read_pw_string */
|
||||
|
||||
#endif /* __KPASSWD_LOCL_H__ */
|
||||
|
||||
+2
-21
@@ -16,13 +16,12 @@ man_MANS = \
|
||||
klist.1 \
|
||||
kdestroy.1 \
|
||||
kswitch.1 \
|
||||
kdigest.8 \
|
||||
kgetcred.1 \
|
||||
kimpersonate.8 \
|
||||
kx509.1
|
||||
|
||||
bin_PROGRAMS = kinit kdestroy kgetcred heimtools
|
||||
libexec_PROGRAMS = kdigest kimpersonate
|
||||
libexec_PROGRAMS = kimpersonate
|
||||
|
||||
noinst_PROGRAMS = kverify kdecode_ticket generate-requests
|
||||
|
||||
@@ -32,7 +31,6 @@ kinit_LDADD = \
|
||||
$(top_builddir)/lib/krb5/libkrb5.la \
|
||||
$(top_builddir)/lib/gssapi/libgssapi.la \
|
||||
$(top_builddir)/lib/gss_preauth/libgss_preauth.la \
|
||||
$(top_builddir)/lib/ntlm/libheimntlm.la \
|
||||
$(top_builddir)/lib/asn1/libasn1.la \
|
||||
$(LIB_libintl) \
|
||||
$(LIB_roken)
|
||||
@@ -55,25 +53,9 @@ nodist_heimtools_SOURCES = heimtools-commands.c
|
||||
|
||||
$(heimtools_OBJECTS): heimtools-commands.h
|
||||
|
||||
dist_kdigest_SOURCES = kdigest.c
|
||||
nodist_kdigest_SOURCES = kdigest-commands.c
|
||||
|
||||
kdigest_LDADD = \
|
||||
$(top_builddir)/lib/ntlm/libheimntlm.la \
|
||||
$(top_builddir)/lib/krb5/libkrb5.la \
|
||||
$(top_builddir)/lib/asn1/libasn1.la \
|
||||
$(top_builddir)/lib/sl/libsl.la \
|
||||
$(LIB_roken)
|
||||
|
||||
$(kdigest_OBJECTS): kdigest-commands.h
|
||||
|
||||
CLEANFILES = \
|
||||
kdigest-commands.h kdigest-commands.c \
|
||||
heimtools-commands.h heimtools-commands.c
|
||||
|
||||
kdigest-commands.c kdigest-commands.h: kdigest-commands.in
|
||||
$(SLC) $(srcdir)/kdigest-commands.in
|
||||
|
||||
heimtools-commands.c heimtools-commands.h: heimtools-commands.in
|
||||
$(SLC) $(srcdir)/heimtools-commands.in
|
||||
|
||||
@@ -88,11 +70,10 @@ EXTRA_DIST = NTMakefile $(man_MANS) \
|
||||
kdeltkt.c \
|
||||
kvno.c \
|
||||
kdestroy-version.rc \
|
||||
kdigest-version.rc \
|
||||
kgetcred-version.rc \
|
||||
kimpersonate-version.rc \
|
||||
kinit-version.rc \
|
||||
kuser_locl.h heimtools-commands.in kdigest-commands.in copy_cred_cache.1
|
||||
kuser_locl.h heimtools-commands.in copy_cred_cache.1
|
||||
|
||||
# make sure install-exec-hook doesn't have any commands in Makefile.am.common
|
||||
install-exec-hook:
|
||||
|
||||
@@ -45,7 +45,6 @@ BINPROGRAMS=\
|
||||
$(BINDIR)\kdeltkt.exe
|
||||
|
||||
LIBEXECPROGRAMS=\
|
||||
$(LIBEXECDIR)\kdigest.exe \
|
||||
$(LIBEXECDIR)\kimpersonate.exe
|
||||
|
||||
NOINSTPROGRAMS=\
|
||||
@@ -59,7 +58,6 @@ BINLIBS=\
|
||||
$(LIBGSS_PREAUTH) \
|
||||
$(LIBGSSAPI) \
|
||||
$(LIBHEIMDAL) \
|
||||
$(LIBHEIMNTLM) \
|
||||
$(LIBHX509) \
|
||||
!if !defined(NO_AFS)
|
||||
$(LIBKAFS) \
|
||||
@@ -103,20 +101,6 @@ $(BINDIR)\kgetcred.exe: $(OBJ)\kgetcred.obj $(BINLIBS) $(OBJ)\kgetcred-version.r
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP)
|
||||
|
||||
|
||||
$(LIBEXECDIR)\kdigest.exe: $(OBJ)\kdigest-commands.obj $(OBJ)\kdigest.obj $(BINLIBS) $(LIBSL) $(OBJ)\kdigest-version.res
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP)
|
||||
|
||||
$(OBJ)\kdigest.obj: kdigest.c
|
||||
$(C2OBJ) -I$(OBJ)
|
||||
|
||||
$(OBJ)\kdigest-commands.c $(OBJ)\kdigest-commands.h: kdigest-commands.in
|
||||
cd $(OBJ)
|
||||
$(CP) $(SRCDIR)\kdigest-commands.in $(OBJ)
|
||||
$(BINDIR)\slc.exe kdigest-commands.in
|
||||
cd $(SRCDIR)
|
||||
|
||||
$(OBJ)\heimtools-commands.c $(OBJ)\heimtools-commands.h: heimtools-commands.in
|
||||
cd $(OBJ)
|
||||
$(CP) $(SRCDIR)\heimtools-commands.in $(OBJ)
|
||||
|
||||
@@ -37,9 +37,6 @@ static const char *cache;
|
||||
static const char *credential;
|
||||
static int help_flag;
|
||||
static int version_flag;
|
||||
#ifndef NO_AFS
|
||||
static int unlog_flag = 1;
|
||||
#endif
|
||||
static int dest_tkt_flag = 1;
|
||||
static int all_flag = 0;
|
||||
|
||||
@@ -48,10 +45,6 @@ struct getargs args[] = {
|
||||
"remove one credential", "principal" },
|
||||
{ "cache", 'c', arg_string, rk_UNCONST(&cache), "cache to destroy", "cache" },
|
||||
{ "all", 'A', arg_flag, &all_flag, "destroy all caches", NULL },
|
||||
#ifndef NO_AFS
|
||||
{ "unlog", 0, arg_negative_flag, &unlog_flag,
|
||||
"do not destroy tokens", NULL },
|
||||
#endif
|
||||
{ "delete-v4", 0, arg_negative_flag, &dest_tkt_flag,
|
||||
"do not destroy v4 tickets", NULL },
|
||||
{ "version", 0, arg_flag, &version_flag, NULL, NULL },
|
||||
@@ -161,12 +154,5 @@ main (int argc, char **argv)
|
||||
|
||||
krb5_free_context (context);
|
||||
|
||||
#ifndef NO_AFS
|
||||
if (unlog_flag && k_hasafs ()) {
|
||||
if (k_unlog ())
|
||||
exit_val = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return exit_val;
|
||||
}
|
||||
|
||||
@@ -1,280 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
/* $Id$ */
|
||||
|
||||
command = {
|
||||
name = "digest-probe"
|
||||
option = {
|
||||
long = "realm"
|
||||
type = "string"
|
||||
help = "Kerberos realm to communicate with"
|
||||
}
|
||||
help = "probe what mech is allowed/supported for this server"
|
||||
}
|
||||
command = {
|
||||
name = "digest-server-init"
|
||||
option = {
|
||||
long = "type"
|
||||
type = "string"
|
||||
help = "digest type"
|
||||
default = "sasl"
|
||||
}
|
||||
option = {
|
||||
long = "kerberos-realm"
|
||||
type = "string"
|
||||
argument = "realm"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "digest"
|
||||
type = "string"
|
||||
argument = "digest-type"
|
||||
help = "digest type to use in the algorithm"
|
||||
}
|
||||
option = {
|
||||
long = "cb-type"
|
||||
type = "string"
|
||||
argument = "type"
|
||||
help = "type of channel bindings"
|
||||
}
|
||||
option = {
|
||||
long = "cb-value"
|
||||
type = "string"
|
||||
argument = "value"
|
||||
help = "value of channel bindings"
|
||||
}
|
||||
option = {
|
||||
long = "hostname"
|
||||
type = "string"
|
||||
argument = "hostname"
|
||||
help = "hostname of the server"
|
||||
}
|
||||
option = {
|
||||
long = "realm"
|
||||
type = "string"
|
||||
help = "Kerberos realm to communicate with"
|
||||
}
|
||||
help = "Sets up a digest context and return initial parameters"
|
||||
}
|
||||
command = {
|
||||
name = "digest-server-request"
|
||||
option = {
|
||||
long = "type"
|
||||
type = "string"
|
||||
help = "digest type"
|
||||
default = "sasl"
|
||||
}
|
||||
option = {
|
||||
long = "kerberos-realm"
|
||||
type = "string"
|
||||
argument = "realm"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "username"
|
||||
type = "string"
|
||||
argument = "name"
|
||||
help = "digest type"
|
||||
}
|
||||
option = {
|
||||
long = "server-nonce"
|
||||
type = "string"
|
||||
argument = "nonce"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "server-identifier"
|
||||
type = "string"
|
||||
argument = "nonce"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "client-nonce"
|
||||
type = "string"
|
||||
argument = "nonce"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "client-response"
|
||||
type = "string"
|
||||
argument = "response"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "opaque"
|
||||
type = "string"
|
||||
argument = "string"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "authentication-name"
|
||||
type = "string"
|
||||
argument = "name"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "realm"
|
||||
type = "string"
|
||||
argument = "realm"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "method"
|
||||
type = "string"
|
||||
argument = "method"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "uri"
|
||||
type = "string"
|
||||
argument = "uri"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "nounce-count"
|
||||
type = "string"
|
||||
argument = "count"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "qop"
|
||||
type = "string"
|
||||
argument = "qop"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "ccache"
|
||||
type = "string"
|
||||
argument = "ccache"
|
||||
help = "Where the the credential cache is created when the KDC returns tickets"
|
||||
}
|
||||
help = "Completes digest negotiation and return final parameters"
|
||||
}
|
||||
command = {
|
||||
name = "digest-client-request"
|
||||
option = {
|
||||
long = "type"
|
||||
type = "string"
|
||||
help = "digest type"
|
||||
default = "sasl"
|
||||
}
|
||||
option = {
|
||||
long = "username"
|
||||
type = "string"
|
||||
argument = "name"
|
||||
help = "digest type"
|
||||
}
|
||||
option = {
|
||||
long = "password"
|
||||
type = "string"
|
||||
argument = "password"
|
||||
}
|
||||
option = {
|
||||
long = "server-nonce"
|
||||
type = "string"
|
||||
argument = "nonce"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "server-identifier"
|
||||
type = "string"
|
||||
argument = "nonce"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "client-nonce"
|
||||
type = "string"
|
||||
argument = "nonce"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "opaque"
|
||||
type = "string"
|
||||
argument = "string"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "realm"
|
||||
type = "string"
|
||||
argument = "realm"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "method"
|
||||
type = "string"
|
||||
argument = "method"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "uri"
|
||||
type = "string"
|
||||
argument = "uri"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "nounce-count"
|
||||
type = "string"
|
||||
argument = "count"
|
||||
help = ""
|
||||
}
|
||||
option = {
|
||||
long = "qop"
|
||||
type = "string"
|
||||
argument = "qop"
|
||||
help = ""
|
||||
}
|
||||
help = "Client part of a digest exchange"
|
||||
}
|
||||
command = {
|
||||
name = "ntlm-server-init"
|
||||
option = {
|
||||
long = "version"
|
||||
type = "integer"
|
||||
help = "ntlm version"
|
||||
default = "1"
|
||||
}
|
||||
option = {
|
||||
long = "kerberos-realm"
|
||||
type = "string"
|
||||
help = "Kerberos realm to communicate with"
|
||||
}
|
||||
help = "Sets up a digest context and return initial parameters"
|
||||
}
|
||||
command = {
|
||||
name = "help"
|
||||
name = "?"
|
||||
argument = "[command]"
|
||||
min_args = "0"
|
||||
max_args = "1"
|
||||
help = "Help! I need somebody."
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/***********************************************************************
|
||||
* Copyright (c) 2010, Secure Endpoints Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
|
||||
* COPYRIGHT HOLDER 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.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
#define RC_FILE_TYPE VFT_APP
|
||||
#define RC_FILE_DESC_0409 "KDC Digest Interface Tool"
|
||||
#define RC_FILE_ORIG_0409 "kdigest.exe"
|
||||
|
||||
#include "../windows/version.rc"
|
||||
-257
@@ -1,257 +0,0 @@
|
||||
.\" Copyright (c) 2008 Kungliga Tekniska Högskolan
|
||||
.\" (Royal Institute of Technology, Stockholm, Sweden).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\"
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\"
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" 3. Neither the name of the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd September 25, 2008
|
||||
.Dt KDIGEST 8
|
||||
.Os HEIMDAL
|
||||
.Sh NAME
|
||||
.Nm kdigest
|
||||
.Nd userland tool to access digest interface in the KDC
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl Fl ccache= Ns Ar string
|
||||
.Op Fl Fl version
|
||||
.Op Fl Fl help
|
||||
command
|
||||
.Op arguments
|
||||
.Sh DESCRIPTION
|
||||
Supported options:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo
|
||||
.Fl Fl ccache= Ns Ar string
|
||||
.Xc
|
||||
credential cache
|
||||
.It Xo
|
||||
.Fl Fl version
|
||||
.Xc
|
||||
print version
|
||||
.It Xo
|
||||
.Fl Fl help
|
||||
.Xc
|
||||
.El
|
||||
.Pp
|
||||
Available commands are:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo digest-probe
|
||||
.Op Fl Fl realm= Ns Ar string
|
||||
.Op Fl h | Fl Fl help
|
||||
.Xc
|
||||
.Bl -tag -width Ds
|
||||
.It Xo
|
||||
.Fl Fl realm= Ns Ar string
|
||||
.Xc
|
||||
Kerberos realm to communicate with
|
||||
.El
|
||||
.It Xo digest-server-init
|
||||
.Op Fl Fl type= Ns Ar string
|
||||
.Op Fl Fl kerberos-realm= Ns Ar realm
|
||||
.Op Fl Fl digest= Ns Ar digest-type
|
||||
.Op Fl Fl cb-type= Ns Ar type
|
||||
.Op Fl Fl cb-value= Ns Ar value
|
||||
.Op Fl Fl hostname= Ns Ar hostname
|
||||
.Op Fl Fl realm= Ns Ar string
|
||||
.Xc
|
||||
.Bl -tag -width Ds
|
||||
.It Xo
|
||||
.Fl Fl type= Ns Ar string
|
||||
.Xc
|
||||
digest type
|
||||
.It Xo
|
||||
.Fl Fl kerberos-realm= Ns Ar realm
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl digest= Ns Ar digest-type
|
||||
.Xc
|
||||
digest type to use in the algorithm
|
||||
.It Xo
|
||||
.Fl Fl cb-type= Ns Ar type
|
||||
.Xc
|
||||
type of channel bindings
|
||||
.It Xo
|
||||
.Fl Fl cb-value= Ns Ar value
|
||||
.Xc
|
||||
value of channel bindings
|
||||
.It Xo
|
||||
.Fl Fl hostname= Ns Ar hostname
|
||||
.Xc
|
||||
hostname of the server
|
||||
.It Xo
|
||||
.Fl Fl realm= Ns Ar string
|
||||
.Xc
|
||||
Kerberos realm to communicate with
|
||||
.El
|
||||
.It Xo digest-server-request
|
||||
.Op Fl Fl type= Ns Ar string
|
||||
.Op Fl Fl kerberos-realm= Ns Ar realm
|
||||
.Op Fl Fl username= Ns Ar name
|
||||
.Op Fl Fl server-nonce= Ns Ar nonce
|
||||
.Op Fl Fl server-identifier= Ns Ar nonce
|
||||
.Op Fl Fl client-nonce= Ns Ar nonce
|
||||
.Op Fl Fl client-response= Ns Ar response
|
||||
.Op Fl Fl opaque= Ns Ar string
|
||||
.Op Fl Fl authentication-name= Ns Ar name
|
||||
.Op Fl Fl realm= Ns Ar realm
|
||||
.Op Fl Fl method= Ns Ar method
|
||||
.Op Fl Fl uri= Ns Ar uri
|
||||
.Op Fl Fl nounce-count= Ns Ar count
|
||||
.Op Fl Fl qop= Ns Ar qop
|
||||
.Op Fl Fl ccache= Ns Ar ccache
|
||||
.Xc
|
||||
.Bl -tag -width Ds
|
||||
.It Xo
|
||||
.Fl Fl type= Ns Ar string
|
||||
.Xc
|
||||
digest type
|
||||
.It Xo
|
||||
.Fl Fl kerberos-realm= Ns Ar realm
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl username= Ns Ar name
|
||||
.Xc
|
||||
digest type
|
||||
.It Xo
|
||||
.Fl Fl server-nonce= Ns Ar nonce
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl server-identifier= Ns Ar nonce
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl client-nonce= Ns Ar nonce
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl client-response= Ns Ar response
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl opaque= Ns Ar string
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl authentication-name= Ns Ar name
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl realm= Ns Ar realm
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl method= Ns Ar method
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl uri= Ns Ar uri
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl nounce-count= Ns Ar count
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl qop= Ns Ar qop
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl ccache= Ns Ar ccache
|
||||
.Xc
|
||||
Where the the credential cache is created when the KDC returns tickets
|
||||
.El
|
||||
.It Xo digest-client-request
|
||||
.Op Fl Fl type= Ns Ar string
|
||||
.Op Fl Fl username= Ns Ar name
|
||||
.Op Fl Fl password= Ns Ar password
|
||||
.Op Fl Fl server-nonce= Ns Ar nonce
|
||||
.Op Fl Fl server-identifier= Ns Ar nonce
|
||||
.Op Fl Fl client-nonce= Ns Ar nonce
|
||||
.Op Fl Fl opaque= Ns Ar string
|
||||
.Op Fl Fl realm= Ns Ar realm
|
||||
.Op Fl Fl method= Ns Ar method
|
||||
.Op Fl Fl uri= Ns Ar uri
|
||||
.Op Fl Fl nounce-count= Ns Ar count
|
||||
.Op Fl Fl qop= Ns Ar qop
|
||||
.Xc
|
||||
.Bl -tag -width Ds
|
||||
.It Xo
|
||||
.Fl Fl type= Ns Ar string
|
||||
.Xc
|
||||
digest type
|
||||
.It Xo
|
||||
.Fl Fl username= Ns Ar name
|
||||
.Xc
|
||||
digest type
|
||||
.It Xo
|
||||
.Fl Fl password= Ns Ar password
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl server-nonce= Ns Ar nonce
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl server-identifier= Ns Ar nonce
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl client-nonce= Ns Ar nonce
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl opaque= Ns Ar string
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl realm= Ns Ar realm
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl method= Ns Ar method
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl uri= Ns Ar uri
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl nounce-count= Ns Ar count
|
||||
.Xc
|
||||
.It Xo
|
||||
.Fl Fl qop= Ns Ar qop
|
||||
.Xc
|
||||
.El
|
||||
.It Xo ntlm-server-init
|
||||
.Op Fl Fl version= Ns Ar integer
|
||||
.Op Fl Fl kerberos-realm= Ns Ar string
|
||||
.Xc
|
||||
.Bl -tag -width Ds
|
||||
.It Xo
|
||||
.Fl Fl version= Ns Ar integer
|
||||
.Xc
|
||||
ntlm version
|
||||
.It Xo
|
||||
.Fl Fl kerberos-realm= Ns Ar string
|
||||
.Xc
|
||||
Kerberos realm to communicate with
|
||||
.El
|
||||
.El
|
||||
.\".Sh ENVIRONMENT
|
||||
.\".Sh FILES
|
||||
.\".Sh EXAMPLES
|
||||
.\".Sh DIAGNOSTICS
|
||||
.\".Sh SEE ALSO
|
||||
.\".Sh STANDARDS
|
||||
.\".Sh HISTORY
|
||||
.\".Sh AUTHORS
|
||||
.\".Sh BUGS
|
||||
-570
@@ -1,570 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006 - 2007 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 "kuser_locl.h"
|
||||
|
||||
#include <kdigest-commands.h>
|
||||
#include <hex.h>
|
||||
#include <base64.h>
|
||||
#include <heimntlm.h>
|
||||
#include "crypto-headers.h"
|
||||
|
||||
static int version_flag = 0;
|
||||
static int help_flag = 0;
|
||||
static char *ccache_string;
|
||||
static krb5_ccache id;
|
||||
|
||||
static struct getargs args[] = {
|
||||
{"ccache", 0, arg_string, &ccache_string, "credential cache", NULL },
|
||||
{"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);
|
||||
}
|
||||
|
||||
static krb5_context context;
|
||||
|
||||
int
|
||||
digest_probe(struct digest_probe_options *opt,
|
||||
int argc, char ** argv)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_realm realm;
|
||||
unsigned flags;
|
||||
|
||||
realm = opt->realm_string;
|
||||
|
||||
if (realm == NULL)
|
||||
errx(1, "realm missing");
|
||||
|
||||
ret = krb5_digest_probe(context, realm, id, &flags);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "digest_probe");
|
||||
|
||||
printf("flags: %u\n", flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
digest_server_init(struct digest_server_init_options *opt,
|
||||
int argc, char ** argv)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_digest digest;
|
||||
|
||||
ret = krb5_digest_alloc(context, &digest);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "digest_alloc");
|
||||
|
||||
ret = krb5_digest_set_type(context, digest, opt->type_string);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_set_type");
|
||||
|
||||
if (opt->cb_type_string && opt->cb_value_string) {
|
||||
ret = krb5_digest_set_server_cb(context, digest,
|
||||
opt->cb_type_string,
|
||||
opt->cb_value_string);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_set_server_cb");
|
||||
}
|
||||
ret = krb5_digest_init_request(context,
|
||||
digest,
|
||||
opt->kerberos_realm_string,
|
||||
id);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_init_request");
|
||||
|
||||
printf("type=%s\n", opt->type_string);
|
||||
printf("server-nonce=%s\n",
|
||||
krb5_digest_get_server_nonce(context, digest));
|
||||
{
|
||||
const char *s = krb5_digest_get_identifier(context, digest);
|
||||
if (s)
|
||||
printf("identifier=%s\n", s);
|
||||
}
|
||||
printf("opaque=%s\n", krb5_digest_get_opaque(context, digest));
|
||||
|
||||
krb5_digest_free(digest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
digest_server_request(struct digest_server_request_options *opt,
|
||||
int argc, char **argv)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_digest digest;
|
||||
const char *status, *rsp;
|
||||
krb5_data session_key;
|
||||
|
||||
if (opt->server_nonce_string == NULL)
|
||||
errx(1, "server nonce missing");
|
||||
if (opt->type_string == NULL)
|
||||
errx(1, "type missing");
|
||||
if (opt->opaque_string == NULL)
|
||||
errx(1, "opaque missing");
|
||||
if (opt->client_response_string == NULL)
|
||||
errx(1, "client response missing");
|
||||
|
||||
ret = krb5_digest_alloc(context, &digest);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "digest_alloc");
|
||||
|
||||
if (strcasecmp(opt->type_string, "CHAP") == 0) {
|
||||
if (opt->server_identifier_string == NULL)
|
||||
errx(1, "server identifier missing");
|
||||
|
||||
ret = krb5_digest_set_identifier(context, digest,
|
||||
opt->server_identifier_string);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_set_type");
|
||||
}
|
||||
|
||||
ret = krb5_digest_set_type(context, digest, opt->type_string);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_set_type");
|
||||
|
||||
ret = krb5_digest_set_username(context, digest, opt->username_string);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_set_username");
|
||||
|
||||
ret = krb5_digest_set_server_nonce(context, digest,
|
||||
opt->server_nonce_string);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_set_server_nonce");
|
||||
|
||||
if(opt->client_nonce_string) {
|
||||
ret = krb5_digest_set_client_nonce(context, digest,
|
||||
opt->client_nonce_string);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_set_client_nonce");
|
||||
}
|
||||
|
||||
|
||||
ret = krb5_digest_set_opaque(context, digest, opt->opaque_string);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_set_opaque");
|
||||
|
||||
ret = krb5_digest_set_responseData(context, digest,
|
||||
opt->client_response_string);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_set_responseData");
|
||||
|
||||
ret = krb5_digest_request(context, digest,
|
||||
opt->kerberos_realm_string, id);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_request");
|
||||
|
||||
status = krb5_digest_rep_get_status(context, digest) ? "ok" : "failed";
|
||||
rsp = krb5_digest_get_rsp(context, digest);
|
||||
|
||||
printf("status=%s\n", status);
|
||||
if (rsp)
|
||||
printf("rsp=%s\n", rsp);
|
||||
printf("tickets=no\n");
|
||||
|
||||
ret = krb5_digest_get_session_key(context, digest, &session_key);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_digest_get_session_key");
|
||||
|
||||
if (session_key.length) {
|
||||
char *key;
|
||||
hex_encode(session_key.data, session_key.length, &key);
|
||||
if (key == NULL)
|
||||
krb5_errx(context, 1, "hex_encode");
|
||||
krb5_data_free(&session_key);
|
||||
printf("session-key=%s\n", key);
|
||||
free(key);
|
||||
}
|
||||
|
||||
krb5_digest_free(digest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
client_chap(const void *server_nonce, size_t snoncelen,
|
||||
unsigned char server_identifier,
|
||||
const char *password)
|
||||
{
|
||||
EVP_MD_CTX *ctx;
|
||||
unsigned char md[MD5_DIGEST_LENGTH];
|
||||
char *h;
|
||||
|
||||
ctx = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
|
||||
|
||||
EVP_DigestUpdate(ctx, &server_identifier, 1);
|
||||
EVP_DigestUpdate(ctx, password, strlen(password));
|
||||
EVP_DigestUpdate(ctx, server_nonce, snoncelen);
|
||||
EVP_DigestFinal_ex(ctx, md, NULL);
|
||||
|
||||
EVP_MD_CTX_destroy(ctx);
|
||||
|
||||
hex_encode(md, 16, &h);
|
||||
|
||||
printf("responseData=%s\n", h);
|
||||
free(h);
|
||||
}
|
||||
|
||||
static const unsigned char ms_chap_v2_magic1[39] = {
|
||||
0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
|
||||
0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
|
||||
0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
|
||||
};
|
||||
static const unsigned char ms_chap_v2_magic2[41] = {
|
||||
0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
|
||||
0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
|
||||
0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
|
||||
0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
|
||||
0x6E
|
||||
};
|
||||
static const unsigned char ms_rfc3079_magic1[27] = {
|
||||
0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
|
||||
0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79
|
||||
};
|
||||
|
||||
static void
|
||||
client_mschapv2(const void *server_nonce, size_t snoncelen,
|
||||
const void *client_nonce, size_t cnoncelen,
|
||||
const char *username,
|
||||
const char *password)
|
||||
{
|
||||
EVP_MD_CTX *hctx, *ctx;
|
||||
unsigned char md[SHA_DIGEST_LENGTH], challenge[SHA_DIGEST_LENGTH];
|
||||
unsigned char hmd[MD4_DIGEST_LENGTH];
|
||||
struct ntlm_buf answer;
|
||||
int i, len, ret;
|
||||
char *h;
|
||||
|
||||
ctx = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
|
||||
|
||||
EVP_DigestUpdate(ctx, client_nonce, cnoncelen);
|
||||
EVP_DigestUpdate(ctx, server_nonce, snoncelen);
|
||||
EVP_DigestUpdate(ctx, username, strlen(username));
|
||||
EVP_DigestFinal_ex(ctx, md, NULL);
|
||||
|
||||
|
||||
hctx = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(hctx, EVP_md4(), NULL);
|
||||
len = strlen(password);
|
||||
for (i = 0; i < len; i++) {
|
||||
EVP_DigestUpdate(hctx, &password[i], 1);
|
||||
EVP_DigestUpdate(hctx, &password[len], 1);
|
||||
}
|
||||
EVP_DigestFinal_ex(hctx, hmd, NULL);
|
||||
|
||||
|
||||
/* ChallengeResponse */
|
||||
ret = heim_ntlm_calculate_ntlm1(hmd, sizeof(hmd), md, &answer);
|
||||
if (ret)
|
||||
errx(1, "heim_ntlm_calculate_ntlm1");
|
||||
|
||||
hex_encode(answer.data, answer.length, &h);
|
||||
printf("responseData=%s\n", h);
|
||||
free(h);
|
||||
|
||||
/* PasswordHash */
|
||||
EVP_DigestInit_ex(hctx, EVP_md4(), NULL);
|
||||
EVP_DigestUpdate(hctx, hmd, sizeof(hmd));
|
||||
EVP_DigestFinal_ex(hctx, hmd, NULL);
|
||||
|
||||
|
||||
/* GenerateAuthenticatorResponse */
|
||||
EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
|
||||
EVP_DigestUpdate(ctx, hmd, sizeof(hmd));
|
||||
EVP_DigestUpdate(ctx, answer.data, answer.length);
|
||||
EVP_DigestUpdate(ctx, ms_chap_v2_magic1, sizeof(ms_chap_v2_magic1));
|
||||
EVP_DigestFinal_ex(ctx, md, NULL);
|
||||
|
||||
/* ChallengeHash */
|
||||
EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
|
||||
EVP_DigestUpdate(ctx, client_nonce, cnoncelen);
|
||||
EVP_DigestUpdate(ctx, server_nonce, snoncelen);
|
||||
EVP_DigestUpdate(ctx, username, strlen(username));
|
||||
EVP_DigestFinal_ex(ctx, challenge, NULL);
|
||||
|
||||
EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
|
||||
EVP_DigestUpdate(ctx, md, sizeof(md));
|
||||
EVP_DigestUpdate(ctx, challenge, 8);
|
||||
EVP_DigestUpdate(ctx, ms_chap_v2_magic2, sizeof(ms_chap_v2_magic2));
|
||||
EVP_DigestFinal_ex(ctx, md, NULL);
|
||||
|
||||
hex_encode(md, sizeof(md), &h);
|
||||
printf("AuthenticatorResponse=%s\n", h);
|
||||
free(h);
|
||||
|
||||
/* get_master, rfc 3079 3.4 */
|
||||
EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
|
||||
EVP_DigestUpdate(ctx, hmd, sizeof(hmd));
|
||||
EVP_DigestUpdate(ctx, answer.data, answer.length);
|
||||
EVP_DigestUpdate(ctx, ms_rfc3079_magic1, sizeof(ms_rfc3079_magic1));
|
||||
EVP_DigestFinal_ex(ctx, md, NULL);
|
||||
|
||||
free(answer.data);
|
||||
|
||||
hex_encode(md, 16, &h);
|
||||
printf("session-key=%s\n", h);
|
||||
free(h);
|
||||
|
||||
EVP_MD_CTX_destroy(hctx);
|
||||
EVP_MD_CTX_destroy(ctx);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
digest_client_request(struct digest_client_request_options *opt,
|
||||
int argc, char **argv)
|
||||
{
|
||||
char *server_nonce, *client_nonce = NULL, server_identifier;
|
||||
ssize_t snoncelen, cnoncelen = 0;
|
||||
|
||||
if (opt->server_nonce_string == NULL)
|
||||
errx(1, "server nonce missing");
|
||||
if (opt->password_string == NULL)
|
||||
errx(1, "password missing");
|
||||
|
||||
if (opt->opaque_string == NULL)
|
||||
errx(1, "opaque missing");
|
||||
|
||||
snoncelen = strlen(opt->server_nonce_string);
|
||||
server_nonce = malloc(snoncelen);
|
||||
if (server_nonce == NULL)
|
||||
errx(1, "server_nonce");
|
||||
|
||||
snoncelen = hex_decode(opt->server_nonce_string, server_nonce, snoncelen);
|
||||
if (snoncelen <= 0)
|
||||
errx(1, "server nonce wrong");
|
||||
|
||||
if (opt->client_nonce_string) {
|
||||
cnoncelen = strlen(opt->client_nonce_string);
|
||||
client_nonce = malloc(cnoncelen);
|
||||
if (client_nonce == NULL)
|
||||
errx(1, "client_nonce");
|
||||
|
||||
cnoncelen = hex_decode(opt->client_nonce_string,
|
||||
client_nonce, cnoncelen);
|
||||
if (cnoncelen <= 0)
|
||||
errx(1, "client nonce wrong");
|
||||
}
|
||||
|
||||
if (opt->server_identifier_string) {
|
||||
int ret;
|
||||
|
||||
ret = hex_decode(opt->server_identifier_string, &server_identifier, 1);
|
||||
if (ret != 1)
|
||||
errx(1, "server identifier wrong length");
|
||||
}
|
||||
|
||||
if (strcasecmp(opt->type_string, "CHAP") == 0) {
|
||||
if (opt->server_identifier_string == NULL)
|
||||
errx(1, "server identifier missing");
|
||||
|
||||
client_chap(server_nonce, snoncelen, server_identifier,
|
||||
opt->password_string);
|
||||
|
||||
} else if (strcasecmp(opt->type_string, "MS-CHAP-V2") == 0) {
|
||||
if (opt->client_nonce_string == NULL)
|
||||
errx(1, "client nonce missing");
|
||||
if (opt->username_string == NULL)
|
||||
errx(1, "client nonce missing");
|
||||
|
||||
client_mschapv2(server_nonce, snoncelen,
|
||||
client_nonce, cnoncelen,
|
||||
opt->username_string,
|
||||
opt->password_string);
|
||||
}
|
||||
if (client_nonce)
|
||||
free(client_nonce);
|
||||
free(server_nonce);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <heimntlm.h>
|
||||
|
||||
int
|
||||
ntlm_server_init(struct ntlm_server_init_options *opt,
|
||||
int argc, char ** argv)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_ntlm ntlm;
|
||||
struct ntlm_type2 type2;
|
||||
krb5_data challenge, opaque;
|
||||
struct ntlm_buf data;
|
||||
char *s;
|
||||
static char zero2[] = "\x00\x00";
|
||||
|
||||
memset(&type2, 0, sizeof(type2));
|
||||
|
||||
ret = krb5_ntlm_alloc(context, &ntlm);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_ntlm_alloc");
|
||||
|
||||
ret = krb5_ntlm_init_request(context,
|
||||
ntlm,
|
||||
opt->kerberos_realm_string,
|
||||
id,
|
||||
NTLM_NEG_UNICODE|NTLM_NEG_NTLM,
|
||||
"NUTCRACKER",
|
||||
"L");
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_ntlm_init_request");
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
ret = krb5_ntlm_init_get_challenge(context, ntlm, &challenge);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_ntlm_init_get_challenge");
|
||||
|
||||
if (challenge.length != sizeof(type2.challenge))
|
||||
krb5_errx(context, 1, "ntlm challenge have wrong length");
|
||||
memcpy(type2.challenge, challenge.data, sizeof(type2.challenge));
|
||||
krb5_data_free(&challenge);
|
||||
|
||||
ret = krb5_ntlm_init_get_flags(context, ntlm, &type2.flags);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_ntlm_init_get_flags");
|
||||
|
||||
krb5_ntlm_init_get_targetname(context, ntlm, &type2.targetname);
|
||||
type2.targetinfo.data = zero2;
|
||||
type2.targetinfo.length = 2;
|
||||
|
||||
ret = heim_ntlm_encode_type2(&type2, &data);
|
||||
if (ret)
|
||||
krb5_errx(context, 1, "heim_ntlm_encode_type2");
|
||||
|
||||
free(type2.targetname);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
rk_base64_encode(data.data, data.length, &s);
|
||||
free(data.data);
|
||||
printf("type2=%s\n", s);
|
||||
free(s);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
ret = krb5_ntlm_init_get_opaque(context, ntlm, &opaque);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_ntlm_init_get_opaque");
|
||||
|
||||
rk_base64_encode(opaque.data, opaque.length, &s);
|
||||
krb5_data_free(&opaque);
|
||||
printf("opaque=%s\n", s);
|
||||
free(s);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
krb5_ntlm_free(context, ntlm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
help(void *opt, int argc, char **argv)
|
||||
{
|
||||
sl_slc_help(commands, argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
int optidx = 0;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
ret = krb5_init_context (&context);
|
||||
if (ret == KRB5_CONFIG_BADFORMAT)
|
||||
errx (1, "krb5_init_context failed to parse configuration file");
|
||||
else if (ret)
|
||||
errx(1, "krb5_init_context failed: %d", ret);
|
||||
|
||||
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;
|
||||
|
||||
if (argc == 0) {
|
||||
help(NULL, argc, argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ccache_string) {
|
||||
ret = krb5_cc_resolve(context, ccache_string, &id);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_cc_resolve");
|
||||
}
|
||||
|
||||
ret = sl_command (commands, argc, argv);
|
||||
if (ret == -1) {
|
||||
help(NULL, argc, argv);
|
||||
return 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
+38
-83
@@ -40,9 +40,6 @@
|
||||
#include <Security/Security.h>
|
||||
#endif
|
||||
|
||||
#ifndef NO_NTLM
|
||||
#include "heimntlm.h"
|
||||
#endif
|
||||
|
||||
#ifndef SIGINFO
|
||||
#define SIGINFO SIGUSR1
|
||||
@@ -88,10 +85,12 @@ static int enterprise_flag = 0;
|
||||
static int ok_as_delegate_flag = 0;
|
||||
static char *fast_armor_cache_string = NULL;
|
||||
static int use_referrals_flag = 0;
|
||||
static char *dh_alg = NULL;
|
||||
static char *sig_alg = NULL;
|
||||
static char *kdf_alg = NULL;
|
||||
static char *ossl_cnf = NULL;
|
||||
static char *ossl_propq = NULL;
|
||||
static int windows_flag = 0;
|
||||
#ifndef NO_NTLM
|
||||
static char *ntlm_domain;
|
||||
#endif
|
||||
|
||||
|
||||
static struct getargs args[] = {
|
||||
@@ -202,11 +201,6 @@ static struct getargs args[] = {
|
||||
{ "kdc-hostname", 0, arg_string, &kdc_hostname,
|
||||
NP_("KDC host name", ""), "hostname" },
|
||||
|
||||
#ifndef NO_NTLM
|
||||
{ "ntlm-domain", 0, arg_string, &ntlm_domain,
|
||||
NP_("NTLM domain", ""), "domain" },
|
||||
#endif
|
||||
|
||||
{ "change-default", 0, arg_negative_flag, &switch_cache_flags,
|
||||
NP_("switch the default cache to the new credentials cache", ""), NULL },
|
||||
|
||||
@@ -222,6 +216,23 @@ static struct getargs args[] = {
|
||||
{ "use-referrals", 0, arg_flag, &use_referrals_flag,
|
||||
NP_("only use referrals, no dns canonicalisation", ""), NULL },
|
||||
|
||||
{ "key-agreement", 0, arg_string, &dh_alg,
|
||||
"request given PKINIT key agreement algorithm", "ALGORITHM" },
|
||||
|
||||
{ "signature-algorithm", 0, arg_string, &sig_alg,
|
||||
"prefer PKINIT certificate with given key algorithm (ed25519, ed448, rsa)", "ALGORITHM" },
|
||||
|
||||
{ "kdf", 0, arg_string, &kdf_alg,
|
||||
"request given PKINIT key derivation algorithm", "ALGORITHM" },
|
||||
|
||||
{ "ossl-cnf", 0, arg_string, &ossl_cnf,
|
||||
"OpenSSL configuration file", "FILE"
|
||||
},
|
||||
|
||||
{ "ossl-propq", 0, arg_string, &ossl_propq,
|
||||
"OpenSSL property query string (e.g., provider=pkcs11)", "PROPQ"
|
||||
},
|
||||
|
||||
{ "windows", 0, arg_flag, &windows_flag,
|
||||
NP_("get windows behavior", ""), NULL },
|
||||
|
||||
@@ -684,41 +695,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef NO_NTLM
|
||||
|
||||
static krb5_error_code
|
||||
store_ntlmkey(krb5_context context, krb5_ccache id,
|
||||
const char *domain, struct ntlm_buf *buf)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_data data;
|
||||
char *name;
|
||||
int aret;
|
||||
|
||||
ret = krb5_cc_get_config(context, id, NULL, "default-ntlm-domain", &data);
|
||||
if (ret == 0) {
|
||||
krb5_data_free(&data);
|
||||
} else {
|
||||
data.length = strlen(domain);
|
||||
data.data = rk_UNCONST(domain);
|
||||
ret = krb5_cc_set_config(context, id, NULL, "default-ntlm-domain", &data);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
aret = asprintf(&name, "ntlm-key-%s", domain);
|
||||
if (aret == -1 || name == NULL)
|
||||
return krb5_enomem(context);
|
||||
|
||||
data.length = buf->length;
|
||||
data.data = buf->data;
|
||||
|
||||
ret = krb5_cc_set_config(context, id, NULL, name, &data);
|
||||
free(name);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static krb5_error_code
|
||||
get_new_tickets(krb5_context context,
|
||||
krb5_principal principal,
|
||||
@@ -742,10 +718,6 @@ get_new_tickets(krb5_context context,
|
||||
gss_OID gss_mech = GSS_C_NO_OID;
|
||||
krb5_principal federated_name = NULL;
|
||||
|
||||
#ifndef NO_NTLM
|
||||
struct ntlm_buf ntlmkey;
|
||||
memset(&ntlmkey, 0, sizeof(ntlmkey));
|
||||
#endif
|
||||
passwd[0] = '\0';
|
||||
|
||||
if (!interactive)
|
||||
@@ -900,6 +872,15 @@ get_new_tickets(krb5_context context,
|
||||
}
|
||||
if (ent_user_id)
|
||||
krb5_get_init_creds_opt_set_pkinit_user_certs(context, opt, ent_user_id);
|
||||
if (dh_alg || sig_alg || kdf_alg) {
|
||||
ret = krb5_get_init_creds_opt_set_pkinit_allowed_algs(context, opt,
|
||||
dh_alg, sig_alg,
|
||||
kdf_alg);
|
||||
if (ret) {
|
||||
krb5_warn(context, ret, "krb5_get_init_creds_opt_set_pkinit_allowed_algs");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (addrs_flag != -1)
|
||||
@@ -1072,7 +1053,7 @@ get_new_tickets(krb5_context context,
|
||||
if (aret == -1)
|
||||
errx(1, "failed to generate passwd prompt: not enough memory");
|
||||
|
||||
if (UI_UTIL_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){
|
||||
if (_krb5_UI_UTIL_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)) {
|
||||
memset(passwd, 0, sizeof(passwd));
|
||||
errx(1, "failed to read password");
|
||||
}
|
||||
@@ -1090,10 +1071,6 @@ get_new_tickets(krb5_context context,
|
||||
|
||||
ret = krb5_init_creds_get(context, ctx);
|
||||
|
||||
#ifndef NO_NTLM
|
||||
if (ntlm_domain && passwd[0])
|
||||
heim_ntlm_nt_key(passwd, &ntlmkey);
|
||||
#endif
|
||||
memset_s(passwd, sizeof(passwd), 0, sizeof(passwd));
|
||||
|
||||
switch(ret){
|
||||
@@ -1184,10 +1161,6 @@ get_new_tickets(krb5_context context,
|
||||
if (switch_cache_flags)
|
||||
krb5_cc_switch(context, ccache);
|
||||
|
||||
#ifndef NO_NTLM
|
||||
if (ntlm_domain && ntlmkey.data)
|
||||
store_ntlmkey(context, ccache, ntlm_domain, &ntlmkey);
|
||||
#endif
|
||||
|
||||
if (ok_as_delegate_flag || windows_flag || use_referrals_flag) {
|
||||
unsigned char d = 0;
|
||||
@@ -1378,11 +1351,6 @@ renew_func(void *ptr)
|
||||
if (ret == 0) {
|
||||
expire = ticket_lifetime(ctx->context, ctx->ccache, ctx->principal,
|
||||
server_str, &renew_expire);
|
||||
|
||||
#ifndef NO_AFS
|
||||
if (server_str == NULL && do_afslog && k_hasafs())
|
||||
krb5_afslog(ctx->context, ctx->ccache, NULL, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
update_siginfo_msg(expire, server_str);
|
||||
@@ -1714,6 +1682,12 @@ main(int argc, char **argv)
|
||||
argc -= optidx;
|
||||
argv += optidx;
|
||||
|
||||
if (ossl_cnf || ossl_propq) {
|
||||
ret = krb5_set_ossl_cnf_propq(context, ossl_cnf, ossl_propq);
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, "krb5_set_ossl_cnf_propq");
|
||||
}
|
||||
|
||||
krb5_appdefault_boolean(context, "kinit", NULL, "historical_anon_pkinit",
|
||||
FALSE, &historical_anon_pkinit);
|
||||
|
||||
@@ -1870,11 +1844,6 @@ main(int argc, char **argv)
|
||||
if (ret)
|
||||
krb5_err(context, 1, ret, N_("resolving credentials cache", ""));
|
||||
|
||||
#ifndef NO_AFS
|
||||
if (argc > 1 && k_hasafs())
|
||||
k_setpag();
|
||||
#endif
|
||||
|
||||
if (lifetime) {
|
||||
int tmp = parse_time(lifetime, "s");
|
||||
if (tmp < 0)
|
||||
@@ -1908,11 +1877,6 @@ main(int argc, char **argv)
|
||||
default_for ? TRUE : FALSE, server_str,
|
||||
ticket_life);
|
||||
|
||||
#ifndef NO_AFS
|
||||
if (ret == 0 && server_str == NULL && do_afslog && k_hasafs())
|
||||
krb5_afslog(context, ccache, NULL, NULL);
|
||||
#endif
|
||||
|
||||
if (unique_ccache)
|
||||
krb5_cc_destroy(context, ccache);
|
||||
exit(ret != 0);
|
||||
@@ -1926,11 +1890,6 @@ main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifndef NO_AFS
|
||||
if (ret == 0 && server_str == NULL && do_afslog && k_hasafs())
|
||||
krb5_afslog(context, ccache, NULL, NULL);
|
||||
#endif
|
||||
|
||||
if (argc > 1) {
|
||||
struct renew_ctx ctx;
|
||||
time_t timeout;
|
||||
@@ -1965,10 +1924,6 @@ main(int argc, char **argv)
|
||||
krb5_warnx(context, N_("command not found: %s", ""), argv[1]);
|
||||
|
||||
krb5_cc_destroy(context, ccache);
|
||||
#ifndef NO_AFS
|
||||
if (k_hasafs())
|
||||
k_unlog();
|
||||
#endif
|
||||
} else {
|
||||
krb5_cc_close(context, ccache);
|
||||
ret = 0;
|
||||
|
||||
@@ -605,78 +605,6 @@ check_expiration(krb5_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a list of all AFS tokens
|
||||
*/
|
||||
|
||||
#ifndef NO_AFS
|
||||
|
||||
static void
|
||||
display_tokens(int do_verbose)
|
||||
{
|
||||
uint32_t i;
|
||||
unsigned char t[4096];
|
||||
struct ViceIoctl parms;
|
||||
|
||||
parms.in = (void *)&i;
|
||||
parms.in_size = sizeof(i);
|
||||
parms.out = (void *)t;
|
||||
parms.out_size = sizeof(t);
|
||||
|
||||
for (i = 0;; i++) {
|
||||
int32_t size_secret_tok, size_public_tok;
|
||||
unsigned char *cell;
|
||||
struct ClearToken ct;
|
||||
unsigned char *r = t;
|
||||
struct timeval tv;
|
||||
char buf1[20], buf2[20];
|
||||
|
||||
if(k_pioctl(NULL, VIOCGETTOK, &parms, 0) < 0) {
|
||||
if(errno == EDOM)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if(parms.out_size > sizeof(t))
|
||||
continue;
|
||||
if(parms.out_size < sizeof(size_secret_tok))
|
||||
continue;
|
||||
t[min(parms.out_size,sizeof(t)-1)] = 0;
|
||||
memcpy(&size_secret_tok, r, sizeof(size_secret_tok));
|
||||
/* don't bother about the secret token */
|
||||
r += size_secret_tok + sizeof(size_secret_tok);
|
||||
if (parms.out_size < (r - t) + sizeof(size_public_tok))
|
||||
continue;
|
||||
memcpy(&size_public_tok, r, sizeof(size_public_tok));
|
||||
r += sizeof(size_public_tok);
|
||||
if (parms.out_size < (r - t) + size_public_tok + sizeof(int32_t))
|
||||
continue;
|
||||
memcpy(&ct, r, size_public_tok);
|
||||
r += size_public_tok;
|
||||
/* there is a int32_t with length of cellname, but we don't read it */
|
||||
r += sizeof(int32_t);
|
||||
cell = r;
|
||||
|
||||
gettimeofday (&tv, NULL);
|
||||
strlcpy (buf1, printable_time(ct.BeginTimestamp),
|
||||
sizeof(buf1));
|
||||
if (do_verbose || tv.tv_sec < ct.EndTimestamp)
|
||||
strlcpy (buf2, printable_time(ct.EndTimestamp),
|
||||
sizeof(buf2));
|
||||
else
|
||||
strlcpy (buf2, N_(">>> Expired <<<", ""), sizeof(buf2));
|
||||
|
||||
printf("%s %s ", buf1, buf2);
|
||||
|
||||
if ((ct.EndTimestamp - ct.BeginTimestamp) & 1)
|
||||
printf(N_("User's (AFS ID %d) tokens for %s", ""), ct.ViceId, cell);
|
||||
else
|
||||
printf(N_("Tokens for %s", ""), cell);
|
||||
if (do_verbose)
|
||||
printf(" (%d)", ct.AuthHandle);
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* display the ccache in `cred_cache'
|
||||
@@ -978,15 +906,5 @@ klist(struct klist_options *opt, int argc, char **argv)
|
||||
heim_release(s);
|
||||
}
|
||||
|
||||
if (!do_test) {
|
||||
#ifndef NO_AFS
|
||||
if (opt->tokens_flag && k_hasafs()) {
|
||||
if (opt->v5_flag)
|
||||
printf("\n");
|
||||
display_tokens(opt->verbose_flag);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return exit_status;
|
||||
}
|
||||
|
||||
@@ -84,9 +84,6 @@
|
||||
#ifdef HAVE_SYS_IOCCOM_H
|
||||
#include <sys/ioccom.h>
|
||||
#endif
|
||||
#ifndef NO_AFS
|
||||
#include <kafs.h>
|
||||
#endif
|
||||
#include "crypto-headers.h" /* for UI_UTIL_read_pw_string */
|
||||
|
||||
#include <rtbl.h>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# $Id$
|
||||
|
||||
include $(top_srcdir)/Makefile.am.common
|
||||
|
||||
if LIBEDIT
|
||||
@@ -17,9 +15,6 @@ endif
|
||||
if MAINTAINER_MODE
|
||||
dir_sqlite = sqlite
|
||||
endif
|
||||
if !NO_AFS
|
||||
dir_afs = kafs
|
||||
endif
|
||||
|
||||
SUBDIRS = \
|
||||
roken \
|
||||
@@ -34,8 +29,6 @@ SUBDIRS = \
|
||||
ipc \
|
||||
hx509 \
|
||||
krb5 \
|
||||
ntlm \
|
||||
$(dir_afs) \
|
||||
gssapi \
|
||||
gss_preauth \
|
||||
hdb \
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ assembly=..\packages\windows\assembly
|
||||
!endif
|
||||
|
||||
SUBDIRS = roken vers com_err base sl wind asn1 sqlite \
|
||||
hx509 krb5 heimdal ntlm kafs gssapi gss_preauth \
|
||||
hx509 krb5 heimdal gssapi gss_preauth \
|
||||
hdb kadm5 $(dir_dce) $(plugin) $(assembly)
|
||||
|
||||
!include ../windows/NTMakefile.w32
|
||||
|
||||
+11
-4
@@ -100,6 +100,8 @@ bin_PROGRAMS = asn1_compile asn1_print
|
||||
TESTS = check-der check-gen check-gen-template check-timegm check-ber check-template
|
||||
check_PROGRAMS = $(TESTS)
|
||||
|
||||
AM_TESTS_ENVIRONMENT = HEIM_TOP_SRCDIR='$(top_srcdir)'; export HEIM_TOP_SRCDIR; HEIM_SRCDIR='$(srcdir)'; export HEIM_SRCDIR;
|
||||
|
||||
asn1_gen_SOURCES = asn1_gen.c
|
||||
asn1_print_SOURCES = asn1_print.c
|
||||
asn1_print_SOURCES += $(gen_files_x690sample_template)
|
||||
@@ -405,8 +407,10 @@ ocsp_template_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/ocsp.asn1
|
||||
$(ASN1_COMPILE) --one-code-file --template --option-file=$(srcdir)/ocsp.opt $(srcdir)/ocsp.asn1 ocsp_template_asn1 || (rm -f ocsp_template_asn1_files ; exit 1)
|
||||
@$(CLANG_FORMAT) -style=$(CLANG_FORMAT_STYLE) -i asn1_ocsp_template_asn1.c
|
||||
|
||||
pkinit_template_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkinit.asn1
|
||||
$(ASN1_COMPILE) --one-code-file --template $(srcdir)/pkinit.asn1 pkinit_template_asn1 || (rm -f pkinit_template_asn1_files ; exit 1)
|
||||
pkinit_template_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkinit.asn1 $(srcdir)/pkinit.opt
|
||||
$(ASN1_COMPILE) --one-code-file --template \
|
||||
--option-file=$(srcdir)/pkinit.opt \
|
||||
$(srcdir)/pkinit.asn1 pkinit_template_asn1 || (rm -f pkinit_template_asn1_files ; exit 1)
|
||||
@$(CLANG_FORMAT) -style=$(CLANG_FORMAT_STYLE) -i asn1_pkinit_template_asn1.c
|
||||
|
||||
pkcs8_template_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkcs8.asn1
|
||||
@@ -459,8 +463,10 @@ ocsp_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/ocsp.asn1
|
||||
$(ASN1_COMPILE) --one-code-file $(TEMPLATE_OPTION) --option-file=$(srcdir)/ocsp.opt $(srcdir)/ocsp.asn1 ocsp_asn1 || (rm -f ocsp_asn1_files ; exit 1)
|
||||
@$(CLANG_FORMAT) -style=$(CLANG_FORMAT_STYLE) -i asn1_ocsp_asn1.c
|
||||
|
||||
pkinit_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkinit.asn1
|
||||
$(ASN1_COMPILE) --one-code-file $(TEMPLATE_OPTION) $(srcdir)/pkinit.asn1 pkinit_asn1 || (rm -f pkinit_asn1_files ; exit 1)
|
||||
pkinit_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkinit.asn1 $(srcdir)/pkinit.opt
|
||||
$(ASN1_COMPILE) --one-code-file $(TEMPLATE_OPTION) \
|
||||
--option-file=$(srcdir)/pkinit.opt \
|
||||
$(srcdir)/pkinit.asn1 pkinit_asn1 || (rm -f pkinit_asn1_files ; exit 1)
|
||||
@$(CLANG_FORMAT) -style=$(CLANG_FORMAT_STYLE) -i asn1_pkinit_asn1.c
|
||||
|
||||
pkcs8_asn1_files: asn1_compile$(EXEEXT) $(srcdir)/pkcs8.asn1
|
||||
@@ -531,6 +537,7 @@ EXTRA_DIST = \
|
||||
pkcs8.asn1 \
|
||||
pkcs9.asn1 \
|
||||
pkinit.asn1 \
|
||||
pkinit.opt \
|
||||
pku2u.asn1 \
|
||||
rfc2459.asn1 \
|
||||
rfc2459.opt \
|
||||
|
||||
+6
-2
@@ -299,9 +299,13 @@ $(OBJ)\asn1_ocsp_asn1.c $(OBJ)\ocsp_asn1.h: $(BINDIR)\asn1_compile.exe ocsp.asn1
|
||||
|| ($(RM) $(OBJ)\ocsp_asn1.h ; exit /b 1)
|
||||
cd $(SRCDIR)
|
||||
|
||||
$(OBJ)\asn1_pkinit_asn1.c $(OBJ)\pkinit_asn1.h: $(BINDIR)\asn1_compile.exe pkinit.asn1
|
||||
$(OBJ)\asn1_pkinit_asn1.c $(OBJ)\pkinit_asn1.h: $(BINDIR)\asn1_compile.exe pkinit.asn1 pkinit.opt
|
||||
cd $(OBJ)
|
||||
$(BINDIR)\asn1_compile.exe --template --one-code-file $(SRCDIR)\pkinit.asn1 pkinit_asn1 \
|
||||
$(BINDIR)\asn1_compile.exe \
|
||||
--template \
|
||||
--one-code-file \
|
||||
--option-file=$(SRCDIR)\pkinit.opt \
|
||||
$(SRCDIR)\pkinit.asn1 pkinit_asn1 \
|
||||
|| ($(RM) $(OBJ)\pkinit_asn1.h ; exit /b 1)
|
||||
cd $(SRCDIR)
|
||||
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
#define A1_OS_IS_SORTED (0x01000000)
|
||||
#define A1_OS_OT_IS_ARRAY (0x02000000)
|
||||
#define A1_OTI_IS_INTEGER (0x04000000)
|
||||
#define A1_OTF_IS_OPTIONAL (0x08000000) /* Open type field is optional */
|
||||
|
||||
|
||||
struct asn1_template {
|
||||
@@ -232,6 +233,7 @@ enum template_types {
|
||||
A1T_BOOLEAN,
|
||||
A1T_OID,
|
||||
A1T_TELETEX_STRING,
|
||||
A1T_NULL,
|
||||
A1T_NUM_ENTRY
|
||||
};
|
||||
|
||||
|
||||
@@ -1919,6 +1919,7 @@ new_type_field(char *n, int optional, Type *t)
|
||||
Field *f;
|
||||
|
||||
f = ecalloc(1, sizeof(*f));
|
||||
f->opentype = 1;
|
||||
f->optional = optional;
|
||||
f->unique = 0;
|
||||
f->defval = 0;
|
||||
|
||||
+51
-321
@@ -2282,321 +2282,50 @@ test_x690sample(void)
|
||||
}
|
||||
|
||||
#if ASN1_IOS_SUPPORTED
|
||||
/*
|
||||
* Read a file from a given file in lib/asn1/data, NUL-terminated in case
|
||||
* the file's contents are meant to be text.
|
||||
*/
|
||||
static void *
|
||||
read_file(const char *top_srcdir_rel_fn, size_t *szp)
|
||||
{
|
||||
struct stat st;
|
||||
unsigned char *s;
|
||||
char *fn = NULL;
|
||||
ssize_t bytes;
|
||||
int fd;
|
||||
|
||||
if (getenv("HEIM_TOP_SRCDIR") == NULL)
|
||||
errx(1, "Missing HEIM_TOP_SRCDIR environment variable!");
|
||||
|
||||
if (asprintf(&fn, "%s/lib/asn1/data/%s",
|
||||
getenv("HEIM_TOP_SRCDIR"), top_srcdir_rel_fn) == -1 ||
|
||||
fn == NULL ||
|
||||
(fd = open(fn, O_RDONLY)) == -1 ||
|
||||
fstat(fd, &st) == -1 ||
|
||||
st.st_size > 10 * 1024 * 1024 ||
|
||||
(s = malloc(st.st_size + 1 /* 1 for a NUL */)) == NULL ||
|
||||
(bytes = read(fd, s, st.st_size)) == -1)
|
||||
err(1, "Could not read %s/lib/asn1/data/%s",
|
||||
getenv("HEIM_TOP_SRCDIR"), top_srcdir_rel_fn);
|
||||
|
||||
(void) close(fd);
|
||||
if (bytes != st.st_size)
|
||||
errx(1, "Could not read %s/lib/asn1/data/%s",
|
||||
getenv("HEIM_TOP_SRCDIR"), top_srcdir_rel_fn);
|
||||
s[st.st_size] = '\0';
|
||||
if (szp)
|
||||
*szp = st.st_size;
|
||||
return s;
|
||||
}
|
||||
|
||||
static int
|
||||
test_ios(void)
|
||||
{
|
||||
unsigned char encoded_sample[] = {
|
||||
0x30, 0x82, 0x04, 0x8e, 0x30, 0x82, 0x03, 0x76,
|
||||
0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x6a,
|
||||
0x05, 0x97, 0xba, 0x71, 0xd7, 0xe6, 0xd3, 0xac,
|
||||
0x0e, 0xdc, 0x9e, 0xdc, 0x95, 0xa1, 0x5b, 0x99,
|
||||
0x8d, 0xe4, 0x0a, 0x30, 0x0d, 0x06, 0x09, 0x2a,
|
||||
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
|
||||
0x05, 0x00, 0x30, 0x55, 0x31, 0x0b, 0x30, 0x09,
|
||||
0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43,
|
||||
0x48, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55,
|
||||
0x04, 0x0a, 0x13, 0x15, 0x53, 0x54, 0x4d, 0x69,
|
||||
0x63, 0x72, 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74,
|
||||
0x72, 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x20, 0x4e,
|
||||
0x56, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55,
|
||||
0x04, 0x03, 0x13, 0x1d, 0x53, 0x54, 0x4d, 0x20,
|
||||
0x54, 0x50, 0x4d, 0x20, 0x45, 0x4b, 0x20, 0x49,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69,
|
||||
0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x20, 0x30,
|
||||
0x35, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x31,
|
||||
0x32, 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x32,
|
||||
0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x5a, 0x30, 0x00, 0x30, 0x82, 0x01, 0x22, 0x30,
|
||||
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
|
||||
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82,
|
||||
0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
|
||||
0x82, 0x01, 0x01, 0x00, 0xcc, 0x14, 0xeb, 0x27,
|
||||
0xa7, 0x8c, 0xeb, 0x0e, 0xa4, 0x86, 0xfa, 0x2d,
|
||||
0xf7, 0x83, 0x5f, 0x5f, 0xa8, 0xe9, 0x05, 0xb0,
|
||||
0x97, 0x01, 0x2b, 0x5b, 0xde, 0x50, 0x38, 0x0c,
|
||||
0x35, 0x5b, 0x1a, 0x2a, 0x72, 0x1b, 0xbc, 0x3d,
|
||||
0x08, 0xdd, 0x21, 0x79, 0x6c, 0xdb, 0x23, 0x9f,
|
||||
0xa9, 0x53, 0x10, 0x65, 0x1b, 0x1b, 0x56, 0xfd,
|
||||
0x2c, 0xfe, 0x53, 0xc8, 0x73, 0x52, 0xeb, 0xd9,
|
||||
0x96, 0xe3, 0x32, 0x56, 0x16, 0x04, 0x04, 0xce,
|
||||
0x93, 0x02, 0xa0, 0x80, 0x66, 0x80, 0x1e, 0x78,
|
||||
0x6a, 0x2f, 0x86, 0xe1, 0x81, 0xf9, 0x49, 0x96,
|
||||
0x6f, 0x49, 0x2a, 0x85, 0xb5, 0x8e, 0xaa, 0x4a,
|
||||
0x6a, 0x8c, 0xb3, 0x69, 0x75, 0x51, 0xbb, 0x23,
|
||||
0x6e, 0x87, 0xcc, 0x7b, 0xf8, 0xec, 0x13, 0x47,
|
||||
0x87, 0x1c, 0x91, 0xe1, 0x54, 0x37, 0xe8, 0xf2,
|
||||
0x66, 0xbf, 0x1e, 0xa5, 0xeb, 0x27, 0x1f, 0xdc,
|
||||
0xf3, 0x74, 0xd8, 0xb4, 0x7d, 0xf8, 0xbc, 0xe8,
|
||||
0x9e, 0x1f, 0xad, 0x61, 0xc2, 0xa0, 0x88, 0xcb,
|
||||
0x40, 0x36, 0xb3, 0x59, 0xcb, 0x72, 0xa2, 0x94,
|
||||
0x97, 0x3f, 0xed, 0xcc, 0xf0, 0xc3, 0x40, 0xaf,
|
||||
0xfd, 0x14, 0xb6, 0x4f, 0x04, 0x11, 0x65, 0x58,
|
||||
0x1a, 0xca, 0x34, 0x14, 0x7c, 0x1c, 0x75, 0x61,
|
||||
0x70, 0x47, 0x05, 0x8f, 0x7e, 0xd7, 0xd6, 0x03,
|
||||
0xe0, 0x32, 0x50, 0x80, 0x94, 0xfa, 0x73, 0xe8,
|
||||
0xb9, 0x15, 0x3d, 0xa3, 0xbf, 0x25, 0x5d, 0x2c,
|
||||
0xbb, 0xc5, 0xdf, 0x30, 0x1b, 0xa8, 0xf7, 0x4d,
|
||||
0x19, 0x8b, 0xeb, 0xce, 0x86, 0x04, 0x0f, 0xc1,
|
||||
0xd2, 0x92, 0x7c, 0x76, 0x57, 0x41, 0x44, 0x90,
|
||||
0xd8, 0x02, 0xf4, 0x82, 0xf3, 0xeb, 0xf2, 0xde,
|
||||
0x35, 0xee, 0x14, 0x9a, 0x1a, 0x6d, 0xe8, 0xd1,
|
||||
0x68, 0x91, 0xfb, 0xfb, 0xa0, 0x2a, 0x18, 0xaf,
|
||||
0xe5, 0x9f, 0x9d, 0x6f, 0x14, 0x97, 0x44, 0xe5,
|
||||
0xf0, 0xd5, 0x59, 0xb1, 0x02, 0x03, 0x01, 0x00,
|
||||
0x01, 0xa3, 0x82, 0x01, 0xa9, 0x30, 0x82, 0x01,
|
||||
0xa5, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23,
|
||||
0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x1a, 0xdb,
|
||||
0x99, 0x4a, 0xb5, 0x8b, 0xe5, 0x7a, 0x0c, 0xc9,
|
||||
0xb9, 0x00, 0xe7, 0x85, 0x1e, 0x1a, 0x43, 0xc0,
|
||||
0x86, 0x60, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d,
|
||||
0x20, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0x06,
|
||||
0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2f, 0x30,
|
||||
0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
|
||||
0x07, 0x02, 0x01, 0x16, 0x21, 0x68, 0x74, 0x74,
|
||||
0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e,
|
||||
0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54,
|
||||
0x50, 0x4d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73,
|
||||
0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x59,
|
||||
0x06, 0x03, 0x55, 0x1d, 0x11, 0x01, 0x01, 0xff,
|
||||
0x04, 0x4f, 0x30, 0x4d, 0xa4, 0x4b, 0x30, 0x49,
|
||||
0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67, 0x81,
|
||||
0x05, 0x02, 0x01, 0x0c, 0x0b, 0x69, 0x64, 0x3a,
|
||||
0x35, 0x33, 0x35, 0x34, 0x34, 0x44, 0x32, 0x30,
|
||||
0x31, 0x17, 0x30, 0x15, 0x06, 0x05, 0x67, 0x81,
|
||||
0x05, 0x02, 0x02, 0x0c, 0x0c, 0x53, 0x54, 0x33,
|
||||
0x33, 0x48, 0x54, 0x50, 0x48, 0x41, 0x48, 0x43,
|
||||
0x30, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x67,
|
||||
0x81, 0x05, 0x02, 0x03, 0x0c, 0x0b, 0x69, 0x64,
|
||||
0x3a, 0x30, 0x30, 0x34, 0x39, 0x30, 0x30, 0x30,
|
||||
0x38, 0x30, 0x67, 0x06, 0x03, 0x55, 0x1d, 0x09,
|
||||
0x04, 0x60, 0x30, 0x5e, 0x30, 0x17, 0x06, 0x05,
|
||||
0x67, 0x81, 0x05, 0x02, 0x10, 0x31, 0x0e, 0x30,
|
||||
0x0c, 0x0c, 0x03, 0x32, 0x2e, 0x30, 0x02, 0x01,
|
||||
0x00, 0x02, 0x02, 0x00, 0x8a, 0x30, 0x43, 0x06,
|
||||
0x05, 0x67, 0x81, 0x05, 0x02, 0x12, 0x31, 0x3a,
|
||||
0x30, 0x38, 0x02, 0x01, 0x00, 0x01, 0x01, 0xff,
|
||||
0xa0, 0x03, 0x0a, 0x01, 0x01, 0xa1, 0x03, 0x0a,
|
||||
0x01, 0x00, 0xa2, 0x03, 0x0a, 0x01, 0x00, 0xa3,
|
||||
0x10, 0x30, 0x0e, 0x16, 0x03, 0x33, 0x2e, 0x31,
|
||||
0x0a, 0x01, 0x04, 0x0a, 0x01, 0x02, 0x01, 0x01,
|
||||
0xff, 0xa4, 0x0f, 0x30, 0x0d, 0x16, 0x05, 0x31,
|
||||
0x34, 0x30, 0x2d, 0x32, 0x0a, 0x01, 0x02, 0x01,
|
||||
0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d,
|
||||
0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
|
||||
0x05, 0x20, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d,
|
||||
0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
|
||||
0x30, 0x10, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04,
|
||||
0x09, 0x30, 0x07, 0x06, 0x05, 0x67, 0x81, 0x05,
|
||||
0x08, 0x01, 0x30, 0x4a, 0x06, 0x08, 0x2b, 0x06,
|
||||
0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x3e,
|
||||
0x30, 0x3c, 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06,
|
||||
0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2e,
|
||||
0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73,
|
||||
0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x67, 0x6c,
|
||||
0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x74, 0x6d,
|
||||
0x74, 0x70, 0x6d, 0x65, 0x6b, 0x69, 0x6e, 0x74,
|
||||
0x30, 0x35, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d,
|
||||
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
|
||||
0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
|
||||
0x01, 0x00, 0x3d, 0x4c, 0x38, 0x1e, 0x5b, 0x4f,
|
||||
0x1b, 0xcb, 0xe0, 0x9c, 0x63, 0xd5, 0x2f, 0x1f,
|
||||
0x04, 0x57, 0x0c, 0xae, 0xa1, 0x42, 0xfd, 0x9c,
|
||||
0xd9, 0x42, 0x04, 0x3b, 0x11, 0xf8, 0xe3, 0xbd,
|
||||
0xcf, 0x50, 0x00, 0x7a, 0xe1, 0x6c, 0xf8, 0x86,
|
||||
0x90, 0x13, 0x04, 0x1e, 0x92, 0xcd, 0xd3, 0x28,
|
||||
0x0b, 0xa4, 0xb5, 0x1f, 0xbb, 0xd4, 0x05, 0x82,
|
||||
0xed, 0x75, 0x02, 0x19, 0xe2, 0x61, 0xa6, 0x95,
|
||||
0x09, 0x56, 0x74, 0x85, 0x5a, 0xac, 0xeb, 0x52,
|
||||
0x0a, 0xda, 0xff, 0x9e, 0x7e, 0x90, 0x84, 0x80,
|
||||
0xa3, 0x9c, 0xdc, 0xf9, 0x00, 0x46, 0x2d, 0x91,
|
||||
0x71, 0x96, 0x0f, 0xfe, 0x55, 0xd3, 0xac, 0x49,
|
||||
0xe8, 0xc9, 0x81, 0x34, 0x1b, 0xbd, 0x2e, 0xfb,
|
||||
0xcc, 0x25, 0x2a, 0x4c, 0x18, 0xa4, 0xf3, 0xb7,
|
||||
0xc8, 0x4c, 0xce, 0x42, 0xce, 0x70, 0xa2, 0x08,
|
||||
0xc8, 0x4d, 0x26, 0x30, 0xa7, 0xab, 0xfb, 0xe7,
|
||||
0x2d, 0x62, 0x71, 0xe7, 0x5b, 0x9f, 0xf1, 0xc9,
|
||||
0x71, 0xd2, 0x0e, 0xb3, 0xdb, 0xd7, 0x63, 0xf1,
|
||||
0xe0, 0x4d, 0x83, 0x4e, 0xaa, 0x69, 0x2d, 0x2e,
|
||||
0x40, 0x01, 0xbb, 0xf4, 0x73, 0x0a, 0x3e, 0x3f,
|
||||
0xda, 0x97, 0x11, 0xae, 0x38, 0x65, 0x24, 0xd9,
|
||||
0x1c, 0x63, 0xbe, 0x0e, 0x51, 0x6d, 0x00, 0xd5,
|
||||
0xc6, 0x14, 0x1f, 0xcc, 0xf6, 0xc5, 0x39, 0xf3,
|
||||
0x51, 0x8e, 0x18, 0x00, 0x49, 0x86, 0x5b, 0xe1,
|
||||
0x6b, 0x69, 0xca, 0xe1, 0xf8, 0xcb, 0x7f, 0xdc,
|
||||
0x47, 0x4b, 0x38, 0xf7, 0xee, 0x56, 0xcb, 0xe7,
|
||||
0xd8, 0xa8, 0x9d, 0x9b, 0xa9, 0x9b, 0x65, 0xd5,
|
||||
0x26, 0x5a, 0xef, 0x32, 0xaa, 0x62, 0x42, 0x6b,
|
||||
0x10, 0xe6, 0xd7, 0x5b, 0xb8, 0x67, 0x7e, 0xc4,
|
||||
0x4f, 0x75, 0x5b, 0xbc, 0x28, 0x06, 0xfd, 0x2b,
|
||||
0x4e, 0x04, 0xbd, 0xf5, 0xd4, 0x42, 0x59, 0xdb,
|
||||
0xea, 0xa4, 0x2b, 0x6f, 0x56, 0x3d, 0xf7, 0xaa,
|
||||
0x75, 0x06,
|
||||
};
|
||||
char cert_json[] = {
|
||||
"{\"_type\":\"Certificate\",\"tbsCertificate\":{\"_type\":\"TBSCertificate"
|
||||
"\",\"_save\":\"30820376A00302010202146A0597BA71D7E6D3AC0EDC9EDC95A15"
|
||||
"B998DE40A300D06092A864886F70D01010B05003055310B30090603550406130"
|
||||
"24348311E301C060355040A131553544D6963726F656C656374726F6E6963732"
|
||||
"04E56312630240603550403131D53544D2054504D20454B20496E7465726D656"
|
||||
"469617465204341203035301E170D3138313231343030303030305A170D32383"
|
||||
"13231343030303030305A300030820122300D06092A864886F70D01010105000"
|
||||
"382010F003082010A0282010100CC14EB27A78CEB0EA486FA2DF7835F5FA8E90"
|
||||
"5B097012B5BDE50380C355B1A2A721BBC3D08DD21796CDB239FA95310651B1B5"
|
||||
"6FD2CFE53C87352EBD996E33256160404CE9302A08066801E786A2F86E181F94"
|
||||
"9966F492A85B58EAA4A6A8CB3697551BB236E87CC7BF8EC1347871C91E15437E"
|
||||
"8F266BF1EA5EB271FDCF374D8B47DF8BCE89E1FAD61C2A088CB4036B359CB72A"
|
||||
"294973FEDCCF0C340AFFD14B64F041165581ACA34147C1C75617047058F7ED7D"
|
||||
"603E032508094FA73E8B9153DA3BF255D2CBBC5DF301BA8F74D198BEBCE86040"
|
||||
"FC1D2927C7657414490D802F482F3EBF2DE35EE149A1A6DE8D16891FBFBA02A1"
|
||||
"8AFE59F9D6F149744E5F0D559B10203010001A38201A9308201A5301F0603551"
|
||||
"D230418301680141ADB994AB58BE57A0CC9B900E7851E1A43C08660304206035"
|
||||
"51D20043B303930370604551D2000302F302D06082B060105050702011621687"
|
||||
"474703A2F2F7777772E73742E636F6D2F54504D2F7265706F7369746F72792F3"
|
||||
"0590603551D110101FF044F304DA44B304931163014060567810502010C0B696"
|
||||
"43A353335343444323031173015060567810502020C0C5354333348545048414"
|
||||
"8433031163014060567810502030C0B69643A303034393030303830670603551"
|
||||
"D090460305E301706056781050210310E300C0C03322E300201000202008A304"
|
||||
"306056781050212313A30380201000101FFA0030A0101A1030A0100A2030A010"
|
||||
"0A310300E1603332E310A01040A01020101FFA40F300D16053134302D320A010"
|
||||
"2010100300E0603551D0F0101FF040403020520300C0603551D130101FF04023"
|
||||
"00030100603551D250409300706056781050801304A06082B060105050701010"
|
||||
"43E303C303A06082B06010505073002862E687474703A2F2F7365637572652E6"
|
||||
"76C6F62616C7369676E2E636F6D2F73746D74706D656B696E7430352E637274\""
|
||||
",\"version\":\"rfc3280_version_3\",\"serialNumber\":\"6A0597BA71D7E6D3A"
|
||||
"C0EDC9EDC95A15B998DE40A\",\"signature\":{\"_type\":\"AlgorithmIdentifi"
|
||||
"er\",\"algorithm\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"1.2.840.1135"
|
||||
"49.1.1.11\",\"components\":[1,2,840,113549,1,1,11],\"name\":\"id-pkcs1"
|
||||
"-sha256WithRSAEncryption\"},\"parameters\":\"0500\"},\"issuer\":{\"_choi"
|
||||
"ce\":\"rdnSequence\",\"value\":[[{\"_type\":\"AttributeTypeAndValue\",\"ty"
|
||||
"pe\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5.4.6\",\"components\":[2"
|
||||
",5,4,6],\"name\":\"id-at-countryName\"},\"value\":{\"_choice\":\"printabl"
|
||||
"eString\",\"value\":\"CH\"}}],[{\"_type\":\"AttributeTypeAndValue\",\"type"
|
||||
"\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5.4.10\",\"components\":[2,"
|
||||
"5,4,10],\"name\":\"id-at-organizationName\"},\"value\":{\"_choice\":\"pri"
|
||||
"ntableString\",\"value\":\"STMicroelectronics NV\"}}],[{\"_type\":\"Attr"
|
||||
"ibuteTypeAndValue\",\"type\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2."
|
||||
"5.4.3\",\"components\":[2,5,4,3],\"name\":\"id-at-commonName\"},\"value\""
|
||||
":{\"_choice\":\"printableString\",\"value\":\"STM TPM EK Intermediate C"
|
||||
"A 05\"}}]]},\"validity\":{\"_type\":\"Validity\",\"notBefore\":{\"_choice\""
|
||||
":\"utcTime\",\"value\":\"2018-12-14T00:00:00Z\"},\"notAfter\":{\"_choice\""
|
||||
":\"utcTime\",\"value\":\"2028-12-14T00:00:00Z\"}},\"subject\":{\"_choice\""
|
||||
":\"rdnSequence\",\"value\":[]},\"subjectPublicKeyInfo\":{\"_type\":\"Subj"
|
||||
"ectPublicKeyInfo\",\"algorithm\":{\"_type\":\"AlgorithmIdentifier\",\"al"
|
||||
"gorithm\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"1.2.840.113549.1.1."
|
||||
"1\",\"components\":[1,2,840,113549,1,1,1],\"name\":\"id-pkcs1-rsaEncry"
|
||||
"ption\"},\"parameters\":\"0500\"},\"subjectPublicKey\":\"2160:3082010A02"
|
||||
"82010100CC14EB27A78CEB0EA486FA2DF7835F5FA8E905B097012B5BDE50380C"
|
||||
"355B1A2A721BBC3D08DD21796CDB239FA95310651B1B56FD2CFE53C87352EBD9"
|
||||
"96E33256160404CE9302A08066801E786A2F86E181F949966F492A85B58EAA4A"
|
||||
"6A8CB3697551BB236E87CC7BF8EC1347871C91E15437E8F266BF1EA5EB271FDC"
|
||||
"F374D8B47DF8BCE89E1FAD61C2A088CB4036B359CB72A294973FEDCCF0C340AF"
|
||||
"FD14B64F041165581ACA34147C1C75617047058F7ED7D603E032508094FA73E8"
|
||||
"B9153DA3BF255D2CBBC5DF301BA8F74D198BEBCE86040FC1D2927C7657414490"
|
||||
"D802F482F3EBF2DE35EE149A1A6DE8D16891FBFBA02A18AFE59F9D6F149744E5"
|
||||
"F0D559B10203010001\"},\"issuerUniqueID\":null,\"subjectUniqueID\":nul"
|
||||
"l,\"extensions\":[{\"_type\":\"Extension\",\"extnID\":{\"_type\":\"OBJECT I"
|
||||
"DENTIFIER\",\"oid\":\"2.5.29.35\",\"components\":[2,5,29,35],\"name\":\"id"
|
||||
"-x509-ce-authorityKeyIdentifier\"},\"critical\":false,\"extnValue\":\""
|
||||
"301680141ADB994AB58BE57A0CC9B900E7851E1A43C08660\",\"_extnValue_ch"
|
||||
"oice\":\"ext-AuthorityKeyIdentifier\",\"_extnValue\":{\"_type\":\"Author"
|
||||
"ityKeyIdentifier\",\"keyIdentifier\":\"1ADB994AB58BE57A0CC9B900E7851"
|
||||
"E1A43C08660\",\"authorityCertIssuer\":null,\"authorityCertSerialNumb"
|
||||
"er\":null}},{\"_type\":\"Extension\",\"extnID\":{\"_type\":\"OBJECT IDENTI"
|
||||
"FIER\",\"oid\":\"2.5.29.32\",\"components\":[2,5,29,32],\"name\":\"id-x509"
|
||||
"-ce-certificatePolicies\"},\"critical\":false,\"extnValue\":\"30393037"
|
||||
"0604551D2000302F302D06082B060105050702011621687474703A2F2F777777"
|
||||
"2E73742E636F6D2F54504D2F7265706F7369746F72792F\",\"_extnValue_choi"
|
||||
"ce\":\"ext-CertificatePolicies\",\"_extnValue\":[{\"_type\":\"PolicyInfo"
|
||||
"rmation\",\"policyIdentifier\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\""
|
||||
"2.5.29.32.0\",\"components\":[2,5,29,32,0],\"name\":\"id-x509-ce-certi"
|
||||
"ficatePolicies-anyPolicy\"},\"policyQualifiers\":[{\"_type\":\"PolicyQ"
|
||||
"ualifierInfo\",\"policyQualifierId\":{\"_type\":\"OBJECT IDENTIFIER\",\""
|
||||
"oid\":\"1.3.6.1.5.5.7.2.1\",\"components\":[1,3,6,1,5,5,7,2,1],\"name\""
|
||||
":\"id-pkix-qt-cps\"},\"qualifier\":\"1621687474703A2F2F7777772E73742E"
|
||||
"636F6D2F54504D2F7265706F7369746F72792F\",\"_qualifier_choice\":\"pq-"
|
||||
"CPS\"}]}]},{\"_type\":\"Extension\",\"extnID\":{\"_type\":\"OBJECT IDENTIF"
|
||||
"IER\",\"oid\":\"2.5.29.17\",\"components\":[2,5,29,17],\"name\":\"id-x509-"
|
||||
"ce-subjectAltName\"},\"critical\":true,\"extnValue\":\"304DA44B3049311"
|
||||
"63014060567810502010C0B69643A35333534344432303117301506056781050"
|
||||
"2020C0C53543333485450484148433031163014060567810502030C0B69643A3"
|
||||
"030343930303038\",\"_extnValue_choice\":\"ext-SubjectAltName\",\"_extn"
|
||||
"Value\":[{\"_choice\":\"directoryName\",\"value\":{\"_choice\":\"rdnSequen"
|
||||
"ce\",\"value\":[[{\"_type\":\"AttributeTypeAndValue\",\"type\":{\"_type\":\""
|
||||
"OBJECT IDENTIFIER\",\"oid\":\"2.23.133.2.1\",\"components\":[2,23,133,2"
|
||||
",1],\"name\":\"tcg-at-tpmManufacturer\"},\"value\":{\"_choice\":\"utf8Str"
|
||||
"ing\",\"value\":\"id:53544D20\"}}],[{\"_type\":\"AttributeTypeAndValue\","
|
||||
"\"type\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.23.133.2.2\",\"compon"
|
||||
"ents\":[2,23,133,2,2],\"name\":\"tcg-at-tpmModel\"},\"value\":{\"_choice"
|
||||
"\":\"utf8String\",\"value\":\"ST33HTPHAHC0\"}}],[{\"_type\":\"AttributeTyp"
|
||||
"eAndValue\",\"type\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.23.133.2"
|
||||
".3\",\"components\":[2,23,133,2,3],\"name\":\"tcg-at-tpmVersion\"},\"val"
|
||||
"ue\":{\"_choice\":\"utf8String\",\"value\":\"id:00490008\"}}]]}}]},{\"_typ"
|
||||
"e\":\"Extension\",\"extnID\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5."
|
||||
"29.9\",\"components\":[2,5,29,9],\"name\":\"id-x509-ce-subjectDirector"
|
||||
"yAttributes\"},\"critical\":false,\"extnValue\":\"305E3017060567810502"
|
||||
"10310E300C0C03322E300201000202008A304306056781050212313A30380201"
|
||||
"000101FFA0030A0101A1030A0100A2030A0100A310300E1603332E310A01040A"
|
||||
"01020101FFA40F300D16053134302D320A0102010100\",\"_extnValue_choice"
|
||||
"\":\"ext-SubjectDirectoryAttributes\",\"_extnValue\":[{\"_type\":\"Attri"
|
||||
"buteSet\",\"type\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.23.133.2.1"
|
||||
"6\",\"components\":[2,23,133,2,16],\"name\":\"tcg-at-tpmSpecification\""
|
||||
"},\"values\":[\"300C0C03322E300201000202008A\"],\"_values_choice\":\"at"
|
||||
"-TPMSpecification\",\"_values\":[{\"_type\":\"TPMSpecification\",\"famil"
|
||||
"y\":\"2.0\",\"level\":0,\"revision\":138}]},{\"_type\":\"AttributeSet\",\"ty"
|
||||
"pe\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.23.133.2.18\",\"componen"
|
||||
"ts\":[2,23,133,2,18],\"name\":\"tcg-at-tpmSecurityAssertions\"},\"valu"
|
||||
"es\":[\"30380201000101FFA0030A0101A1030A0100A2030A0100A310300E1603"
|
||||
"332E310A01040A01020101FFA40F300D16053134302D320A0102010100\"],\"_v"
|
||||
"alues_choice\":\"at-TPMSecurityAssertions\",\"_values\":[{\"_type\":\"TP"
|
||||
"MSecurityAssertions\",\"version\":0,\"fieldUpgradable\":true,\"ekGener"
|
||||
"ationType\":\"ekgt-injected\",\"ekGenerationLocation\":\"tpmManufactur"
|
||||
"er\",\"ekCertificateGenerationLocation\":\"tpmManufacturer\",\"ccInfo\""
|
||||
":{\"_type\":\"CommonCriteriaMeasures\",\"version\":\"3.1\",\"assurancelev"
|
||||
"el\":\"ealevel4\",\"evaluationStatus\":\"evaluationCompleted\",\"plus\":t"
|
||||
"rue,\"strengthOfFunction\":null,\"profileOid\":null,\"profileUri\":nul"
|
||||
"l,\"targetOid\":null,\"targetUri\":null},\"fipsLevel\":{\"_type\":\"FIPSL"
|
||||
"evel\",\"version\":\"140-2\",\"level\":\"sllevel2\",\"plus\":false},\"iso900"
|
||||
"0Certified\":false,\"iso9000Uri\":null}]}]},{\"_type\":\"Extension\",\"e"
|
||||
"xtnID\":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"2.5.29.15\",\"component"
|
||||
"s\":[2,5,29,15],\"name\":\"id-x509-ce-keyUsage\"},\"critical\":true,\"ex"
|
||||
"tnValue\":\"03020520\",\"_extnValue_choice\":\"ext-KeyUsage\",\"_extnVal"
|
||||
"ue\":[\"keyEncipherment\"]},{\"_type\":\"Extension\",\"extnID\":{\"_type\":"
|
||||
"\"OBJECT IDENTIFIER\",\"oid\":\"2.5.29.19\",\"components\":[2,5,29,19],\""
|
||||
"name\":\"id-x509-ce-basicConstraints\"},\"critical\":true,\"extnValue\""
|
||||
":\"3000\",\"_extnValue_choice\":\"ext-BasicConstraints\",\"_extnValue\":"
|
||||
"{\"_type\":\"BasicConstraints\",\"cA\":false,\"pathLenConstraint\":null}"
|
||||
"},{\"_type\":\"Extension\",\"extnID\":{\"_type\":\"OBJECT IDENTIFIER\",\"oi"
|
||||
"d\":\"2.5.29.37\",\"components\":[2,5,29,37],\"name\":\"id-x509-ce-extKe"
|
||||
"yUsage\"},\"critical\":false,\"extnValue\":\"300706056781050801\",\"_ext"
|
||||
"nValue_choice\":\"ext-ExtKeyUsage\",\"_extnValue\":[{\"_type\":\"OBJECT "
|
||||
"IDENTIFIER\",\"oid\":\"2.23.133.8.1\",\"components\":[2,23,133,8,1],\"na"
|
||||
"me\":\"tcg-kp-EKCertificate\"}]},{\"_type\":\"Extension\",\"extnID\":{\"_t"
|
||||
"ype\":\"OBJECT IDENTIFIER\",\"oid\":\"1.3.6.1.5.5.7.1.1\",\"components\":"
|
||||
"[1,3,6,1,5,5,7,1,1],\"name\":\"id-pkix-pe-authorityInfoAccess\"},\"cr"
|
||||
"itical\":false,\"extnValue\":\"303C303A06082B06010505073002862E68747"
|
||||
"4703A2F2F7365637572652E676C6F62616C7369676E2E636F6D2F73746D74706"
|
||||
"D656B696E7430352E637274\",\"_extnValue_choice\":\"ext-AuthorityInfoA"
|
||||
"ccess\",\"_extnValue\":[{\"_type\":\"AccessDescription\",\"accessMethod\""
|
||||
":{\"_type\":\"OBJECT IDENTIFIER\",\"oid\":\"1.3.6.1.5.5.7.48.2\",\"compon"
|
||||
"ents\":[1,3,6,1,5,5,7,48,2],\"name\":\"id-pkix-ad-caIssuers\"},\"acces"
|
||||
"sLocation\":{\"_choice\":\"uniformResourceIdentifier\",\"value\":\"http:"
|
||||
"//secure.globalsign.com/stmtpmekint05.crt\"}}]}]},\"signatureAlgor"
|
||||
"ithm\":{\"_type\":\"AlgorithmIdentifier\",\"algorithm\":{\"_type\":\"OBJEC"
|
||||
"T IDENTIFIER\",\"oid\":\"1.2.840.113549.1.1.11\",\"components\":[1,2,84"
|
||||
"0,113549,1,1,11],\"name\":\"id-pkcs1-sha256WithRSAEncryption\"},\"par"
|
||||
"ameters\":\"0500\"},\"signatureValue\":\"2048:3D4C381E5B4F1BCBE09C63D5"
|
||||
"2F1F04570CAEA142FD9CD942043B11F8E3BDCF50007AE16CF8869013041E92CD"
|
||||
"D3280BA4B51FBBD40582ED750219E261A695095674855AACEB520ADAFF9E7E90"
|
||||
"8480A39CDCF900462D9171960FFE55D3AC49E8C981341BBD2EFBCC252A4C18A4"
|
||||
"F3B7C84CCE42CE70A208C84D2630A7ABFBE72D6271E75B9FF1C971D20EB3DBD7"
|
||||
"63F1E04D834EAA692D2E4001BBF4730A3E3FDA9711AE386524D91C63BE0E516D"
|
||||
"00D5C6141FCCF6C539F3518E180049865BE16B69CAE1F8CB7FDC474B38F7EE56"
|
||||
"CBE7D8A89D9BA99B65D5265AEF32AA62426B10E6D75BB8677EC44F755BBC2806"
|
||||
"FD2B4E04BDF5D44259DBEAA42B6F563DF7AA7506\""
|
||||
"}"
|
||||
};
|
||||
size_t cert_der_sz = 0;
|
||||
size_t cert_json_sz = 0;
|
||||
unsigned char *cert_der = read_file("test_ios_cert.der", &cert_der_sz);
|
||||
char *cert_json = read_file("test_ios_cert.json", &cert_json_sz);
|
||||
heim_octet_string os;
|
||||
Certificate c0, c1;
|
||||
size_t i, nknown, size;
|
||||
@@ -2609,16 +2338,17 @@ test_ios(void)
|
||||
* Decode a value that has plenty of open types with values of known
|
||||
* alternatives in them, then check that we got what we wanted.
|
||||
*/
|
||||
ret = decode_Certificate(encoded_sample, sizeof(encoded_sample),
|
||||
&c0, &size);
|
||||
ret = decode_Certificate(cert_der, cert_der_sz, &c0, &size);
|
||||
if (ret)
|
||||
return 1;
|
||||
if (size != sizeof(encoded_sample))
|
||||
if (size != cert_der_sz)
|
||||
return 1;
|
||||
|
||||
s = print_Certificate(&c0, 0);
|
||||
if (!s)
|
||||
return 1;
|
||||
if (cert_json[cert_json_sz - 1] == '\n')
|
||||
cert_json[--cert_json_sz] = '\0'; /* Trim trailing newline */
|
||||
if (strcmp(s, cert_json) != 0)
|
||||
return 1;
|
||||
free(s);
|
||||
@@ -2657,9 +2387,9 @@ test_ios(void)
|
||||
ASN1_MALLOC_ENCODE(Certificate, os.data, os.length, &c1, &size, ret);
|
||||
if (ret)
|
||||
return 1;
|
||||
if (os.length != size || size != sizeof(encoded_sample))
|
||||
if (os.length != size || size != cert_der_sz)
|
||||
return 1;
|
||||
if (memcmp(os.data, encoded_sample, os.length) != 0)
|
||||
if (memcmp(os.data, cert_der, os.length) != 0)
|
||||
return 1;
|
||||
der_free_octet_string(&os);
|
||||
|
||||
@@ -2674,9 +2404,9 @@ test_ios(void)
|
||||
ASN1_MALLOC_ENCODE(Certificate, os.data, os.length, &c0, &size, ret);
|
||||
if (ret)
|
||||
return 1;
|
||||
if (os.length != size || size != sizeof(encoded_sample))
|
||||
if (os.length != size || size != cert_der_sz)
|
||||
return 1;
|
||||
if (memcmp(os.data, encoded_sample, os.length) != 0)
|
||||
if (memcmp(os.data, cert_der, os.length) != 0)
|
||||
return 1;
|
||||
der_free_octet_string(&os);
|
||||
|
||||
@@ -2690,9 +2420,9 @@ test_ios(void)
|
||||
ASN1_MALLOC_ENCODE(Certificate, os.data, os.length, &c1, &size, ret);
|
||||
if (ret)
|
||||
return 1;
|
||||
if (os.length != size || size != sizeof(encoded_sample))
|
||||
if (os.length != size || size != cert_der_sz)
|
||||
return 1;
|
||||
if (memcmp(os.data, encoded_sample, os.length) != 0)
|
||||
if (memcmp(os.data, cert_der, os.length) != 0)
|
||||
return 1;
|
||||
der_free_octet_string(&os);
|
||||
|
||||
|
||||
+64
-6
@@ -32,17 +32,18 @@ SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
ContentType ::= OBJECT IDENTIFIER
|
||||
MessageDigest ::= OCTET STRING
|
||||
|
||||
ContentInfo ::= SEQUENCE {
|
||||
contentType ContentType,
|
||||
content [0] EXPLICIT HEIM_ANY OPTIONAL -- DEFINED BY contentType
|
||||
}
|
||||
|
||||
EncapsulatedContentInfo ::= SEQUENCE {
|
||||
eContentType ContentType,
|
||||
eContent [0] EXPLICIT OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
CertificateSet ::= SET OF HEIM_ANY
|
||||
CertificateChoices ::= CHOICE {
|
||||
certificate Certificate,
|
||||
any HEIM_ANY
|
||||
}
|
||||
|
||||
-- Really, for us this is strictly a Certificate. See RFC 5911.
|
||||
CertificateSet ::= SET OF CertificateChoices
|
||||
|
||||
CertificateList ::= Certificate
|
||||
|
||||
@@ -146,4 +147,61 @@ CMSRC2CBCParameter ::= SEQUENCE {
|
||||
|
||||
CMSCBCParameter ::= OCTET STRING
|
||||
|
||||
-- We don't have a) a builtin TYPE-IDENTIFIER class, b) class equality
|
||||
-- assignment yet!
|
||||
_CONTENT-TYPE ::= CLASS {
|
||||
&id OBJECT IDENTIFIER UNIQUE,
|
||||
&Type OPTIONAL
|
||||
}
|
||||
|
||||
ContentInfo{_CONTENT-TYPE:ContentSet} ::= SEQUENCE {
|
||||
contentType _CONTENT-TYPE.&id({ContentSet}),
|
||||
content [0] EXPLICIT _CONTENT-TYPE.&Type({ContentSet}{@contentType}) OPTIONAL
|
||||
}
|
||||
|
||||
-- Content Type Object Identifiers and Objects
|
||||
|
||||
id-ct-contentInfo OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
||||
us(840) rsadsi(113549) pkcs(1) pkcs9(9) smime(16) ct(1) 6 }
|
||||
|
||||
id-data OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
||||
us(840) rsadsi(113549) pkcs(1) pkcs7(7) 1 }
|
||||
|
||||
OctetString ::= OCTET STRING -- workaround compiler bug
|
||||
ct-Data _CONTENT-TYPE ::= { &id id-data, &Type OctetString }
|
||||
|
||||
id-signedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
||||
us(840) rsadsi(113549) pkcs(1) pkcs7(7) 2 }
|
||||
|
||||
ct-SignedData _CONTENT-TYPE ::= { &id id-signedData, &Type SignedData }
|
||||
|
||||
id-envelopedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
||||
us(840) rsadsi(113549) pkcs(1) pkcs7(7) 3 }
|
||||
|
||||
ct-EnvelopedData _CONTENT-TYPE ::= { &id id-envelopedData, &Type EnvelopedData }
|
||||
|
||||
id-digestedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
||||
us(840) rsadsi(113549) pkcs(1) pkcs7(7) 5 }
|
||||
-- ct-DigestedData _CONTENT-TYPE ::= { &id id-digestedData, &Type DigestedData }
|
||||
|
||||
id-encryptedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
||||
us(840) rsadsi(113549) pkcs(1) pkcs7(7) 6 }
|
||||
|
||||
-- ct-EncryptedData _CONTENT-TYPE ::= { &id id-encryptedData, &Type EncryptedData }
|
||||
|
||||
id-ct-authData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
||||
us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1) 2 }
|
||||
|
||||
-- ct-AuthenticatedData _CONTENT-TYPE ::=
|
||||
-- { &id id-ct-authData, &Type AuthenticatedData }
|
||||
|
||||
ContentSet _CONTENT-TYPE ::= {
|
||||
-- Define the set of content types to be recognized.
|
||||
ct-Data | ct-SignedData | ct-EnvelopedData
|
||||
-- | ct-EncryptedData
|
||||
-- | ct-AuthenticatedData | ct-DigestedData
|
||||
}
|
||||
|
||||
ContentInfo ::= ContentInfo{ContentSet}
|
||||
|
||||
END
|
||||
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -158,6 +158,14 @@ der_get_length (const unsigned char *p, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ASN1CALL
|
||||
der_get_null(const unsigned char *p, size_t len, int *data, size_t *size)
|
||||
{
|
||||
*data = 0;
|
||||
*size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ASN1CALL
|
||||
der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
|
||||
{
|
||||
|
||||
@@ -294,6 +294,12 @@ der_length_utctime (const time_t *t)
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ASN1CALL
|
||||
der_length_null(const int *k)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t ASN1CALL
|
||||
der_length_boolean (const int *k)
|
||||
{
|
||||
|
||||
@@ -44,6 +44,12 @@ der_print_general_string(const heim_general_string *str, int flags)
|
||||
return strdup(*str);
|
||||
}
|
||||
|
||||
char * ASN1CALL
|
||||
der_print_null(const int *i, int flags)
|
||||
{
|
||||
return strdup("null");
|
||||
}
|
||||
|
||||
char * ASN1CALL
|
||||
der_print_boolean(const int *i, int flags)
|
||||
{
|
||||
|
||||
@@ -227,6 +227,13 @@ der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ASN1CALL
|
||||
der_put_null(unsigned char *p, size_t len, const int *v, size_t *size)
|
||||
{
|
||||
*size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ASN1CALL
|
||||
der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size)
|
||||
{
|
||||
|
||||
@@ -1125,6 +1125,7 @@ define_open_type(int level, const char *newbasename, const char *name, const cha
|
||||
fprintf(jsonfile, "\"objectsetname\":\"%s\",", os->symbol->name);
|
||||
fprintf(jsonfile, "\"typeidmember\":\"%s\",", typeidmember->name);
|
||||
fprintf(jsonfile, "\"opentypemember\":\"%s\",", opentypemember->name);
|
||||
/* XXX We need to include more metadata about the fields */
|
||||
fprintf(jsonfile, "\"typeidfield\":\"%s\",", typeidfield->name);
|
||||
fprintf(jsonfile, "\"opentypefield\":\"%s\",", opentypefield->name);
|
||||
|
||||
|
||||
+33
-9
@@ -714,10 +714,16 @@ sort_object_set(IOSObjectSet *os, /* Object set to sort fields of */
|
||||
{
|
||||
IOSObject **objects;
|
||||
IOSObject *o;
|
||||
Field *f;
|
||||
size_t i, nobjs = 0;
|
||||
int opentypefield_is_optional = 0;
|
||||
|
||||
*objectsp = NULL;
|
||||
|
||||
HEIM_TAILQ_FOREACH(f, os->iosclass->fields, fields) {
|
||||
if (f->opentype && f->optional)
|
||||
opentypefield_is_optional = 1;
|
||||
}
|
||||
HEIM_TAILQ_FOREACH(o, os->objects, objects) {
|
||||
ObjectField *typeidobjf = NULL;
|
||||
ObjectField *of;
|
||||
@@ -726,7 +732,7 @@ sort_object_set(IOSObjectSet *os, /* Object set to sort fields of */
|
||||
if (strcmp(of->name, typeidfield->name) == 0)
|
||||
typeidobjf = of;
|
||||
}
|
||||
if (!typeidobjf) {
|
||||
if (!typeidobjf && !opentypefield_is_optional) {
|
||||
warnx("Ignoring incomplete object specification of %s "
|
||||
"(missing type ID field)",
|
||||
o->symbol ? o->symbol->name : "<unknown>");
|
||||
@@ -764,8 +770,15 @@ template_object_set(IOSObjectSet *os, Field *typeidfield, Field *opentypefield)
|
||||
{
|
||||
IOSObject **objects = NULL;
|
||||
IOSObject *o;
|
||||
Field *f;
|
||||
struct tlist *tl;
|
||||
size_t nobjs, i;
|
||||
int opentypefield_is_optional = 0;
|
||||
|
||||
HEIM_TAILQ_FOREACH(f, os->iosclass->fields, fields) {
|
||||
if (f->opentype && f->optional)
|
||||
opentypefield_is_optional = 1;
|
||||
}
|
||||
|
||||
if (os->symbol->emitted_template)
|
||||
return;
|
||||
@@ -789,7 +802,7 @@ template_object_set(IOSObjectSet *os, Field *typeidfield, Field *opentypefield)
|
||||
}
|
||||
if (!typeidobjf)
|
||||
continue; /* We've warned about this one already when sorting */
|
||||
if (!opentypeobjf) {
|
||||
if (!opentypeobjf && !opentypefield_is_optional) {
|
||||
warnx("Ignoring incomplete object specification of %s "
|
||||
"(missing open type field)",
|
||||
o->symbol ? o->symbol->name : "<unknown>");
|
||||
@@ -820,12 +833,18 @@ template_object_set(IOSObjectSet *os, Field *typeidfield, Field *opentypefield)
|
||||
"for open type type-ID fields");
|
||||
}
|
||||
|
||||
if (asprintf(&s, "sizeof(%s)",
|
||||
opentypeobjf->type->symbol->gen_name) == -1 || !s)
|
||||
err(1, "Out of memory");
|
||||
add_line_pointer_reference(&tl->template,
|
||||
opentypeobjf->type->symbol->gen_name, s,
|
||||
"A1_OP_OPENTYPE");
|
||||
if (!opentypeobjf) {
|
||||
if (asprintf(&s, "0") == -1 || !s)
|
||||
err(1, "Out of memory");
|
||||
add_line(&tl->template, "{ A1_OP_OPENTYPE, 0, 0 }");
|
||||
} else {
|
||||
if (asprintf(&s, "sizeof(%s)",
|
||||
opentypeobjf->type->symbol->gen_name) == -1 || !s)
|
||||
err(1, "Out of memory");
|
||||
add_line_pointer_reference(&tl->template,
|
||||
opentypeobjf->type->symbol->gen_name, s,
|
||||
"A1_OP_OPENTYPE");
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
free(objects);
|
||||
@@ -862,7 +881,8 @@ template_open_type(struct templatehead *temp,
|
||||
* We always sort object sets for now as we can't import
|
||||
* values yet, so they must all be known.
|
||||
*/
|
||||
"A1_OP_OPENTYPE_OBJSET | A1_OS_IS_SORTED |%s | (%llu << 10) | %llu",
|
||||
"A1_OP_OPENTYPE_OBJSET | A1_OS_IS_SORTED | %s | %s | (%llu << 10) | %llu",
|
||||
opentypefield->optional ? "A1_OTF_IS_OPTIONAL" : "0",
|
||||
is_array_of_open_type ? "A1_OS_OT_IS_ARRAY" : "0",
|
||||
(unsigned long long)opentypeidx,
|
||||
(unsigned long long)typeididx);
|
||||
@@ -1022,6 +1042,7 @@ template_members(struct templatehead *temp,
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_OID), %s, NULL }", poffset);
|
||||
break;
|
||||
case TNull:
|
||||
add_line(temp, "{ A1_PARSE_T(A1T_NULL), %s, NULL }", poffset);
|
||||
break;
|
||||
case TBitString: {
|
||||
struct templatehead template;
|
||||
@@ -1176,6 +1197,9 @@ template_members(struct templatehead *temp,
|
||||
if (typeidmember == m) typeididx = i;
|
||||
if (opentypemember == m) opentypeidx = i;
|
||||
|
||||
if (opentypemember && opentypemember == m)
|
||||
m->optional = opentypemember->optional;
|
||||
|
||||
if (name) {
|
||||
if (asprintf(&newbasename, "%s_%s", basetype, name) < 0)
|
||||
errx(1, "malloc");
|
||||
|
||||
@@ -77,6 +77,7 @@ EXPORTS
|
||||
TicketFlags,
|
||||
TransitedEncoding,
|
||||
TypedData,
|
||||
TYPED-DATA,
|
||||
KrbFastResponse,
|
||||
KrbFastFinished,
|
||||
KrbFastReq,
|
||||
|
||||
@@ -5,5 +5,11 @@
|
||||
--sequence=ETYPE-INFO
|
||||
--sequence=ETYPE-INFO2
|
||||
--preserve-binary=KDC-REQ-BODY
|
||||
# We need to preserve KDC-REQ for, e.g., RFC 8636, where the KDF takes the
|
||||
# encoded AS-REQ (which is a KDC-REQ) as an input, so we'll a) use the _save
|
||||
# field of the generated KDC_REQ to store that encoded AS-REQ on the client
|
||||
# side, and b) because we'll be saving it on decode in the _save field we can
|
||||
# also use it on the KDC side.
|
||||
--preserve-binary=KDC-REQ
|
||||
--decorate=PrincipalNameAttrs:void *:pac
|
||||
--decorate=Principal:PrincipalNameAttrs:nameattrs?
|
||||
|
||||
+48
-1
@@ -5,7 +5,7 @@ PKCS12 DEFINITIONS ::=
|
||||
BEGIN
|
||||
|
||||
IMPORTS ContentInfo FROM cms
|
||||
DigestInfo FROM rfc2459
|
||||
DigestInfo, AlgorithmIdentifier FROM rfc2459
|
||||
HEIM_ANY, HEIM_ANY_SET FROM heim;
|
||||
|
||||
-- The PFX PDU
|
||||
@@ -78,4 +78,51 @@ PKCS12-OctetString ::= OCTET STRING
|
||||
-- KeyBag ::= PrivateKeyInfo
|
||||
-- PKCS8ShroudedKeyBag ::= EncryptedPrivateKeyInfo
|
||||
|
||||
-- PKCS#5 v2.0/v2.1 (RFC 8018) definitions for modern PKCS#12 PBE
|
||||
|
||||
id-pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) pkcs-5(5) }
|
||||
|
||||
id-PBES2 OBJECT IDENTIFIER ::= { id-pkcs-5 13 }
|
||||
id-PBKDF2 OBJECT IDENTIFIER ::= { id-pkcs-5 12 }
|
||||
|
||||
-- PBKDF2 PRF algorithm OIDs (from RFC 8018, using RSA DigestAlgorithm arc)
|
||||
-- id-rsadsi OBJECT IDENTIFIER ::= { 1 2 840 113549 }
|
||||
-- id-digestAlgorithm OBJECT IDENTIFIER ::= { id-rsadsi 2 }
|
||||
id-hmacWithSHA1 OBJECT IDENTIFIER ::=
|
||||
{ iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 }
|
||||
id-hmacWithSHA256 OBJECT IDENTIFIER ::=
|
||||
{ iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 9 }
|
||||
id-hmacWithSHA384 OBJECT IDENTIFIER ::=
|
||||
{ iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 10 }
|
||||
id-hmacWithSHA512 OBJECT IDENTIFIER ::=
|
||||
{ iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 11 }
|
||||
|
||||
-- PBES2 encryption scheme OIDs (from RFC 8018 / NIST)
|
||||
id-aes128-CBC OBJECT IDENTIFIER ::=
|
||||
{ joint-iso-itu-t(2) country(16) us(840) organization(1)
|
||||
gov(101) csor(3) nistAlgorithms(4) aes(1) 2 }
|
||||
id-aes192-CBC OBJECT IDENTIFIER ::=
|
||||
{ joint-iso-itu-t(2) country(16) us(840) organization(1)
|
||||
gov(101) csor(3) nistAlgorithms(4) aes(1) 22 }
|
||||
id-aes256-CBC OBJECT IDENTIFIER ::=
|
||||
{ joint-iso-itu-t(2) country(16) us(840) organization(1)
|
||||
gov(101) csor(3) nistAlgorithms(4) aes(1) 42 }
|
||||
|
||||
-- PBKDF2-params (RFC 8018, Section A.2)
|
||||
-- Note: salt can be CHOICE { specified OCTET STRING, otherSource AlgorithmIdentifier }
|
||||
-- but in practice it's always an OCTET STRING, so we simplify
|
||||
PBKDF2-params ::= SEQUENCE {
|
||||
salt OCTET STRING,
|
||||
iterationCount INTEGER (1..4294967295),
|
||||
keyLength INTEGER (1..4294967295) OPTIONAL,
|
||||
prf AlgorithmIdentifier OPTIONAL -- default id-hmacWithSHA1
|
||||
}
|
||||
|
||||
-- PBES2-params (RFC 8018, Section A.4)
|
||||
PBES2-params ::= SEQUENCE {
|
||||
keyDerivationFunc AlgorithmIdentifier, -- id-PBKDF2
|
||||
encryptionScheme AlgorithmIdentifier -- e.g., id-aes256-CBC
|
||||
}
|
||||
|
||||
END
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
PKINIT DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum, Ticket FROM krb5
|
||||
IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum FROM krb5
|
||||
IssuerAndSerialNumber FROM cms
|
||||
SubjectPublicKeyInfo, AlgorithmIdentifier FROM rfc2459
|
||||
HEIM_ANY FROM heim;
|
||||
@@ -26,6 +26,7 @@ id-pkinit-kdf OBJECT IDENTIFIER ::= { id-pkinit 6 }
|
||||
id-pkinit-kdf-ah-sha1 OBJECT IDENTIFIER ::= { id-pkinit-kdf 1 }
|
||||
id-pkinit-kdf-ah-sha256 OBJECT IDENTIFIER ::= { id-pkinit-kdf 2 }
|
||||
id-pkinit-kdf-ah-sha512 OBJECT IDENTIFIER ::= { id-pkinit-kdf 3 }
|
||||
id-pkinit-kdf-ah-sha384 OBJECT IDENTIFIER ::= { id-pkinit-kdf 4 }
|
||||
|
||||
id-pkinit-san OBJECT IDENTIFIER ::=
|
||||
{ iso(1) org(3) dod(6) internet(1) security(5) kerberosv5(2)
|
||||
@@ -86,13 +87,15 @@ PKAuthenticator ::= SEQUENCE {
|
||||
...
|
||||
}
|
||||
|
||||
SupportedKDFs ::= SEQUENCE OF KDFAlgorithmId
|
||||
|
||||
AuthPack ::= SEQUENCE {
|
||||
pkAuthenticator [0] PKAuthenticator,
|
||||
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL,
|
||||
supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL,
|
||||
clientDHNonce [3] DHNonce OPTIONAL,
|
||||
...,
|
||||
supportedKDFs [4] SEQUENCE OF KDFAlgorithmId OPTIONAL,
|
||||
supportedKDFs [4] SupportedKDFs OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
@@ -130,6 +133,9 @@ ReplyKeyPack ::= SEQUENCE {
|
||||
|
||||
TD-DH-PARAMETERS ::= SEQUENCE OF AlgorithmIdentifier
|
||||
|
||||
-- No need for this one since it's the same as TD-DH-PARAMETERS:
|
||||
-- TD-CMS-DIGEST-ALGORITHMS-DATA ::= SEQUENCE OF AlgorithmIdentifier
|
||||
|
||||
|
||||
-- Windows compat glue --
|
||||
|
||||
@@ -193,7 +199,7 @@ PkinitSuppPubInfo ::= SEQUENCE {
|
||||
enctype [0] INTEGER (-2147483648..2147483647),
|
||||
as-REQ [1] OCTET STRING,
|
||||
pk-as-rep [2] OCTET STRING,
|
||||
ticket [3] Ticket,
|
||||
-- ticket [3] Ticket, (removed prior to publication of RFC 8636)
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -1 +1,5 @@
|
||||
--sequence=TD_DH_PARAMETERS
|
||||
--sequence=TD-DH-PARAMETERS
|
||||
--sequence=SupportedKDFs
|
||||
# RFC 8636 takes an encoded PA-PK-AS-REP as an input, so we need to preserve it
|
||||
# on decode on the client side.
|
||||
--preserve-binary=PA-PK-AS-REP
|
||||
|
||||
+110
-34
@@ -29,7 +29,10 @@ id-pkcs1-rsaEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 1 }
|
||||
id-pkcs1-md2WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 2 }
|
||||
id-pkcs1-md5WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 4 }
|
||||
id-pkcs1-sha1WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 5 }
|
||||
-- 1.2.840.113549.1.1.5
|
||||
id-pkcs1-sha256WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 11 }
|
||||
-- 1.2.840.113549.1.1.11
|
||||
-- 1.2.840.10046.4.3
|
||||
id-pkcs1-sha384WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 12 }
|
||||
id-pkcs1-sha512WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 13 }
|
||||
|
||||
@@ -69,7 +72,7 @@ id-secsig-sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { iso(1) identified-organ
|
||||
|
||||
id-nistAlgorithm OBJECT IDENTIFIER ::= {
|
||||
joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) 4 }
|
||||
|
||||
|
||||
id-nist-aes-algs OBJECT IDENTIFIER ::= { id-nistAlgorithm 1 }
|
||||
|
||||
id-aes-128-cbc OBJECT IDENTIFIER ::= { id-nist-aes-algs 2 }
|
||||
@@ -121,6 +124,11 @@ id-ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
|
||||
|
||||
-- some EC group ids
|
||||
|
||||
id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 }
|
||||
id-X448 OBJECT IDENTIFIER ::= { 1 3 101 111 }
|
||||
id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
|
||||
id-Ed448 OBJECT IDENTIFIER ::= { 1 3 101 113 }
|
||||
|
||||
id-ec-group-secp256r1 OBJECT IDENTIFIER ::= {
|
||||
iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
|
||||
prime(1) 7 }
|
||||
@@ -184,11 +192,86 @@ id-at-emailAddress AttributeType ::=
|
||||
|
||||
id-x509-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
|
||||
|
||||
AlgorithmIdentifier ::= SEQUENCE {
|
||||
algorithm OBJECT IDENTIFIER,
|
||||
parameters HEIM_ANY OPTIONAL
|
||||
-- Cryptographic parameter types we might refer to from object sets for
|
||||
-- parameterizing AlgorithmIdentifier.
|
||||
ECParameters ::= CHOICE {
|
||||
namedCurve OBJECT IDENTIFIER
|
||||
-- implicitCurve NULL
|
||||
-- specifiedCurve SpecifiedECDomain
|
||||
}
|
||||
|
||||
DSAParams ::= SEQUENCE {
|
||||
p INTEGER,
|
||||
q INTEGER,
|
||||
g INTEGER
|
||||
}
|
||||
|
||||
ValidationParms ::= SEQUENCE {
|
||||
seed BIT STRING,
|
||||
pgenCounter INTEGER
|
||||
}
|
||||
|
||||
DomainParameters ::= SEQUENCE {
|
||||
p INTEGER, -- odd prime, p=jq +1
|
||||
g INTEGER, -- generator, g
|
||||
q INTEGER OPTIONAL, -- factor of p-1
|
||||
j INTEGER OPTIONAL, -- subgroup factor
|
||||
validationParms ValidationParms OPTIONAL -- ValidationParms
|
||||
}
|
||||
|
||||
-- As defined by PKCS3
|
||||
DHParameter ::= SEQUENCE {
|
||||
prime INTEGER, -- odd prime, p=jq +1
|
||||
base INTEGER, -- generator, g
|
||||
privateValueLength INTEGER OPTIONAL
|
||||
}
|
||||
|
||||
ParamOptions ::= ENUMERATED {
|
||||
-- rfc 5911
|
||||
required (0), -- Parameters MUST be encoded in structure
|
||||
preferredPresent (1), -- Parameters SHOULD be encoded in structure
|
||||
preferredAbsent (2), -- Parameters SHOULD NOT be encoded in structure
|
||||
absent (3), -- Parameters MUST NOT be encoded in structure
|
||||
inheritable (4), -- Parameters are inherited if not present
|
||||
optional (5), -- Parameters MAY be encoded in the structure
|
||||
...
|
||||
}
|
||||
|
||||
-- Our compiler is not yet ready for this because it doesn't yet support
|
||||
-- OPTIONAL (nor DEFAULT) in CLASS definitions, much less WITH SYNTAX:
|
||||
|
||||
_ALGORITHM ::= CLASS { -- rfc 5911
|
||||
&algorithm OBJECT IDENTIFIER UNIQUE,
|
||||
&Params OPTIONAL
|
||||
-- ¶mPresence ParamOptions DEFAULT absent,
|
||||
-- &smimeCaps SMIME-CAPS OPTIONAL
|
||||
} -- WITH SYNTAX {
|
||||
-- IDENTIFIER &id
|
||||
-- [PARAMS [TYPE &Params] ARE ¶mPresence]
|
||||
-- [SMIME-CAPS &smimeCaps]
|
||||
-- }
|
||||
|
||||
AlgorithmIdentifier{_ALGORITHM:AlgorithmSet} ::= SEQUENCE {
|
||||
algorithm _ALGORITHM.&algorithm({AlgorithmSet}),
|
||||
parameters _ALGORITHM.&Params({AlgorithmSet}{@algorithm}) OPTIONAL
|
||||
}
|
||||
|
||||
-- But it would be _really_ nice to be able to support the ALGORITHM class.
|
||||
|
||||
--AlgorithmIdentifier ::= SEQUENCE {
|
||||
-- algorithm OBJECT IDENTIFIER,
|
||||
-- parameters HEIM_ANY OPTIONAL
|
||||
--}
|
||||
|
||||
NullType ::= NULL -- workaround bug in the compiler
|
||||
sa-dsaWithSHA1 _ALGORITHM ::= { &algorithm id-dsa-with-sha1, &Params NullType }
|
||||
sa-rsaWithSHA1 _ALGORITHM ::= { &algorithm id-pkcs1-sha1WithRSAEncryption, &Params NullType }
|
||||
sa-sha256WithRSAEncryption _ALGORITHM ::= {&algorithm id-pkcs1-sha256WithRSAEncryption, &Params NullType }
|
||||
KnownAlgorithms _ALGORITHM ::= {
|
||||
sa-dsaWithSHA1 | sa-rsaWithSHA1 | sa-sha256WithRSAEncryption
|
||||
}
|
||||
AlgorithmIdentifier ::= AlgorithmIdentifier{KnownAlgorithms}
|
||||
|
||||
AttributeType ::= OBJECT IDENTIFIER
|
||||
|
||||
AttributeValue ::= HEIM_ANY
|
||||
@@ -326,26 +409,6 @@ Certificate ::= SEQUENCE {
|
||||
|
||||
Certificates ::= SEQUENCE OF Certificate
|
||||
|
||||
ValidationParms ::= SEQUENCE {
|
||||
seed BIT STRING,
|
||||
pgenCounter INTEGER
|
||||
}
|
||||
|
||||
DomainParameters ::= SEQUENCE {
|
||||
p INTEGER, -- odd prime, p=jq +1
|
||||
g INTEGER, -- generator, g
|
||||
q INTEGER OPTIONAL, -- factor of p-1
|
||||
j INTEGER OPTIONAL, -- subgroup factor
|
||||
validationParms ValidationParms OPTIONAL -- ValidationParms
|
||||
}
|
||||
|
||||
-- As defined by PKCS3
|
||||
DHParameter ::= SEQUENCE {
|
||||
prime INTEGER, -- odd prime, p=jq +1
|
||||
base INTEGER, -- generator, g
|
||||
privateValueLength INTEGER OPTIONAL
|
||||
}
|
||||
|
||||
DHPublicKey ::= INTEGER
|
||||
|
||||
GeneralName ::= CHOICE {
|
||||
@@ -544,22 +607,35 @@ DSASigValue ::= SEQUENCE {
|
||||
|
||||
DSAPublicKey ::= INTEGER
|
||||
|
||||
DSAParams ::= SEQUENCE {
|
||||
p INTEGER,
|
||||
q INTEGER,
|
||||
g INTEGER
|
||||
-- rfc4055
|
||||
|
||||
-- XXX We don't currently support values of SEQUENCE types, so we can't uses
|
||||
-- these in the below DEFAULTs which are therefore commented out.
|
||||
--
|
||||
-- sha1Identifier AlgorithmIdentifier ::= { id-sha1, NULL }
|
||||
-- sha224Identifier AlgorithmIdentifier ::= { id-sha224, NULL }
|
||||
-- sha256Identifier AlgorithmIdentifier ::= { id-sha256, NULL }
|
||||
-- sha384Identifier AlgorithmIdentifier ::= { id-sha384, NULL }
|
||||
-- sha512Identifier AlgorithmIdentifier ::= { id-sha512, NULL }
|
||||
|
||||
RSASSA-PSS-params ::= SEQUENCE {
|
||||
hashAlgorithm [0] AlgorithmIdentifier OPTIONAL -- DEFAULT sha1Identifier -- ,
|
||||
maskGenAlgorithm [1] AlgorithmIdentifier OPTIONAL -- DEFAULT mgf1SHA1Identifier --,
|
||||
saltLength [2] INTEGER (0..4294967295) DEFAULT 20,
|
||||
trailerField [3] INTEGER (0..4294967295) DEFAULT 1
|
||||
}
|
||||
|
||||
RSAES-OAEP-params ::= SEQUENCE {
|
||||
hashFunc [0] AlgorithmIdentifier OPTIONAL -- DEFAULT sha1Identifier -- ,
|
||||
maskGenFunc [1] AlgorithmIdentifier OPTIONAL -- DEFAULT mgf1SHA1Identifier -- ,
|
||||
pSourceFunc [2] AlgorithmIdentifier OPTIONAL -- DEFAULT pSpecifiedEmptyIdentifier
|
||||
}
|
||||
|
||||
|
||||
-- draft-ietf-pkix-ecc-subpubkeyinfo-11
|
||||
|
||||
ECPoint ::= OCTET STRING
|
||||
|
||||
ECParameters ::= CHOICE {
|
||||
namedCurve OBJECT IDENTIFIER
|
||||
-- implicitCurve NULL
|
||||
-- specifiedCurve SpecifiedECDomain
|
||||
}
|
||||
|
||||
ECDSA-Sig-Value ::= SEQUENCE {
|
||||
r INTEGER,
|
||||
s INTEGER
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
--preserve-binary=Name
|
||||
--preserve-binary=TBSCertificate
|
||||
--preserve-binary=TBSCRLCertList
|
||||
--preserve-binary=SubjectPublicKeyInfo
|
||||
--sequence=AttributeValues
|
||||
--sequence=CRLDistributionPoints
|
||||
--sequence=Extensions
|
||||
|
||||
@@ -132,6 +132,7 @@ struct iosclassfield {
|
||||
unsigned long id;
|
||||
unsigned int optional:1;
|
||||
unsigned int unique:1;
|
||||
unsigned int opentype:1;
|
||||
};
|
||||
|
||||
typedef struct iosclassfield Field;
|
||||
|
||||
+36
-6
@@ -88,6 +88,11 @@ struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY] = {
|
||||
},
|
||||
el(oid, heim_oid),
|
||||
el(general_string, heim_general_string),
|
||||
{ (asn1_type_encode)der_put_null, (asn1_type_decode)der_get_null,
|
||||
(asn1_type_length)der_length_null, (asn1_type_copy)der_copy_integer,
|
||||
(asn1_type_release)der_free_integer, (asn1_type_print)der_print_null,
|
||||
sizeof(int)
|
||||
},
|
||||
#undef el
|
||||
#undef elber
|
||||
};
|
||||
@@ -632,10 +637,37 @@ _asn1_decode_open_type(const struct asn1_template *t,
|
||||
* ...
|
||||
* } ...
|
||||
* }
|
||||
*
|
||||
* Of course, the open type member could be OPTIONAL, in which case we
|
||||
* will have:
|
||||
*
|
||||
* typedef struct SingleAttribute {
|
||||
* heim_oid type;
|
||||
* -------->HEIM_ANY *value; // HERE
|
||||
* struct {
|
||||
* ...
|
||||
* } ...
|
||||
* }
|
||||
*
|
||||
* and we'll have to dereference that value pointer if it's not NULL.
|
||||
*/
|
||||
const struct heim_base_data *d = DPOC(data, topentype->offset);
|
||||
const struct heim_base_data *d;
|
||||
void *o;
|
||||
|
||||
if (t->tt & A1_OTF_IS_OPTIONAL) {
|
||||
struct heim_base_data *const *od = DPOC(data, topentype->offset);
|
||||
|
||||
if (*od == NULL)
|
||||
/*
|
||||
* Nothing to do. The user has to check the open type field
|
||||
* before they check the _ios_choice field.
|
||||
*/
|
||||
return 0;
|
||||
d = *od;
|
||||
} else {
|
||||
d = DPOC(data, topentype->offset);
|
||||
}
|
||||
|
||||
if (d->data && d->length) {
|
||||
if ((o = calloc(1, tactual_type->offset)) == NULL)
|
||||
return ENOMEM;
|
||||
@@ -2432,7 +2464,7 @@ _asn1_print_open_type(const struct asn1_template *t, /* object set template */
|
||||
|
||||
/* XXX We assume sizeof(enum) == sizeof(int) */
|
||||
if (!*elementp || *elementp >= A1_HEADER_LEN(tos) + 1) {
|
||||
r = rk_strpoolprintf(r, ",%s\"_%s_choice\":\"_ERROR_DECODING_\"",
|
||||
r = rk_strpoolprintf(r, ",%s\"_%s_choice\":\"<type not recognized or error decoding value of open type>\"",
|
||||
indents ? indents : "", opentype_name);
|
||||
free(indents);
|
||||
return r;
|
||||
@@ -2448,10 +2480,8 @@ _asn1_print_open_type(const struct asn1_template *t, /* object set template */
|
||||
}
|
||||
|
||||
if (!(t->tt & A1_OS_OT_IS_ARRAY)) {
|
||||
dp = DPOC(data, t->offset + sizeof(*elementp));
|
||||
while (sizeof(void *) != sizeof(*elementp) &&
|
||||
((uintptr_t)dp) % sizeof(void *) != 0)
|
||||
dp = (void *)(((char *)dp) + sizeof(*elementp));
|
||||
unsigned align = 8 - ((t->offset + sizeof(*elementp)) & 0x7);
|
||||
dp = DPOC(data, t->offset + sizeof(*elementp) + align);
|
||||
if (*dp) {
|
||||
struct rk_strpool *r2 = NULL;
|
||||
char *s = NULL;
|
||||
|
||||
@@ -36,6 +36,12 @@
|
||||
#ifndef HEIM_BASE_ATOMICS_H
|
||||
#define HEIM_BASE_ATOMICS_H 1
|
||||
|
||||
#if defined(__has_include)
|
||||
# if __has_include(<stdatomic.h>)
|
||||
# define HEIM_HAVE_STDATOMIC 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
@@ -54,15 +60,28 @@
|
||||
|
||||
#define heim_base_atomic(T) _Atomic(T)
|
||||
|
||||
#define heim_base_atomic_inc_32(x) (atomic_fetch_add((x), 1) + 1)
|
||||
#define heim_base_atomic_dec_32(x) (atomic_fetch_sub((x), 1) - 1)
|
||||
#define heim_base_atomic_inc_64(x) (atomic_fetch_add((x), 1) + 1)
|
||||
#define heim_base_atomic_dec_64(x) (atomic_fetch_sub((x), 1) - 1)
|
||||
/*
|
||||
* These have to be inlined functions instead of macros as otherwise we get
|
||||
* errors when the caller ignores the result of these.
|
||||
*/
|
||||
static inline uint32_t heim_base_atomic_inc_32(heim_base_atomic(uint32_t)*x)
|
||||
{ return atomic_fetch_add((x), 1) + 1; }
|
||||
static inline uint32_t heim_base_atomic_dec_32(heim_base_atomic(uint32_t)*x)
|
||||
{ return atomic_fetch_sub((x), 1) - 1; }
|
||||
static inline uint64_t heim_base_atomic_inc_64(heim_base_atomic(uint64_t)*x)
|
||||
{ return atomic_fetch_add((x), 1) + 1; }
|
||||
static inline uint64_t heim_base_atomic_dec_64(heim_base_atomic(uint64_t)*x)
|
||||
{ return atomic_fetch_sub((x), 1) - 1; }
|
||||
|
||||
#define heim_base_exchange_pointer(t,v) atomic_exchange((t), (v))
|
||||
#define heim_base_exchange_32(t,v) atomic_exchange((t), (v))
|
||||
#define heim_base_exchange_64(t,v) atomic_exchange((t), (v))
|
||||
|
||||
#define heim_base_consumer_barrier() atomic_thread_fence(memory_order_acquire)
|
||||
#define heim_base_producer_barrier() atomic_thread_fence(memory_order_release)
|
||||
#define heim_base_full_barrier() atomic_thread_fence(memory_order_seq_cst)
|
||||
#define heim_base_atomic_barrier() atomic_thread_fence(memory_order_seq_cst)
|
||||
|
||||
/*
|
||||
* <stdatomic.h>'s and AIX's CAS functions take a pointer to an expected value
|
||||
* and return a boolean, setting the pointed-to variable to the old value of
|
||||
@@ -98,6 +117,9 @@ heim_base_cas_64_(heim_base_atomic(uint64_t)*t, uint64_t e, uint64_t d)
|
||||
#elif !defined(HEIM_BASE_ATOMICS_FALLBACK) && defined(__GNUC__) && defined(HAVE___SYNC_ADD_AND_FETCH)
|
||||
|
||||
#define heim_base_atomic_barrier() __sync_synchronize()
|
||||
#define heim_base_consumer_barrier() __sync_synchronize()
|
||||
#define heim_base_producer_barrier() __sync_synchronize()
|
||||
#define heim_base_full_barrier() __sync_synchronize()
|
||||
|
||||
#define heim_base_atomic_inc_32(x) __sync_add_and_fetch((x), 1)
|
||||
#define heim_base_atomic_dec_32(x) __sync_sub_and_fetch((x), 1)
|
||||
@@ -129,10 +151,14 @@ heim_base_cas_64_(heim_base_atomic(uint64_t)*t, uint64_t e, uint64_t d)
|
||||
|
||||
static inline void __heim_base_atomic_barrier(void)
|
||||
{
|
||||
__machine_rw_barrier();
|
||||
membar_producer();
|
||||
membar_consumer();
|
||||
}
|
||||
|
||||
#define heim_base_atomic_barrier() __heim_base_atomic_barrier()
|
||||
#define heim_base_atomic_barrier() __heim_base_atomic_barrier()
|
||||
#define heim_base_consumer_barrier() membar_consumer()
|
||||
#define heim_base_producer_barrier() membar_producer()
|
||||
#define heim_base_full_barrier() __heim_base_atomic_barrier()
|
||||
|
||||
#define heim_base_atomic(T) volatile T
|
||||
|
||||
@@ -154,6 +180,9 @@ static inline void __heim_base_atomic_barrier(void)
|
||||
#include <sys/atomic_op.h>
|
||||
|
||||
#define heim_base_atomic_barrier() __isync()
|
||||
#define heim_base_consumer_barrier() __isync()
|
||||
#define heim_base_producer_barrier() __isync()
|
||||
#define heim_base_full_barrier() __isync()
|
||||
|
||||
#define heim_base_atomic_inc_32(x) (fetch_and_add((atomic_p)(x), 1) + 1)
|
||||
#define heim_base_atomic_dec_32(x) (fetch_and_add((atomic_p)(x), -1) - 1)
|
||||
@@ -218,6 +247,9 @@ heim_base_cas_64_(heim_base_atomic(uint64_t)*t, uint64_t e, uint64_t d)
|
||||
#elif !defined(HEIM_BASE_ATOMICS_FALLBACK) && defined(_WIN32)
|
||||
|
||||
#define heim_base_atomic_barrier() MemoryBarrier()
|
||||
#define heim_base_consumer_barrier() _ReadBarrier()
|
||||
#define heim_base_producer_barrier() _WriteBarrier()
|
||||
#define heim_base_full_barrier() MemoryBarrier()
|
||||
|
||||
#define heim_base_atomic_inc_32(x) InterlockedIncrement(x)
|
||||
#define heim_base_atomic_dec_32(x) InterlockedDecrement(x)
|
||||
@@ -236,6 +268,9 @@ heim_base_cas_64_(heim_base_atomic(uint64_t)*t, uint64_t e, uint64_t d)
|
||||
|
||||
#define heim_base_atomic(T) volatile T
|
||||
#define heim_base_atomic_barrier()
|
||||
#define heim_base_consumer_barrier()
|
||||
#define heim_base_producer_barrier()
|
||||
#define heim_base_full_barrier()
|
||||
#define heim_base_atomic_load(x) (*(x))
|
||||
#define heim_base_atomic_init(t, v) do { (*(t) = (v)); } while (0)
|
||||
#define heim_base_atomic_store(t, v) do { (*(t) = (v)); } while (0)
|
||||
@@ -358,6 +393,10 @@ heim_base_cas_64(heim_base_atomic(uint64_t) *target, uint64_t expected,uint64_t
|
||||
|
||||
#ifndef heim_base_atomic_barrier
|
||||
static inline void heim_base_atomic_barrier(void) { return; }
|
||||
#define heim_base_atomic_barrier() heim_base_atomic_barrier()
|
||||
#define heim_base_consumer_barrier() heim_base_atomic_barrier()
|
||||
#define heim_base_producer_barrier() heim_base_atomic_barrier()
|
||||
#define heim_base_full_barrier() heim_base_atomic_barrier()
|
||||
#endif
|
||||
|
||||
#ifndef heim_base_atomic_load
|
||||
|
||||
+2
-50
@@ -12,7 +12,6 @@ AM_CPPFLAGS += \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/gssapi \
|
||||
-I$(srcdir)/mech \
|
||||
-I$(srcdir)/ntlm \
|
||||
-I$(srcdir)/krb5 \
|
||||
-I$(srcdir)/spnego \
|
||||
-I$(srcdir)/sanon \
|
||||
@@ -186,42 +185,6 @@ spnegosrc = \
|
||||
spnego/negoex_locl.h \
|
||||
$(srcdir)/spnego/spnego-private.h
|
||||
|
||||
ntlmsrc = \
|
||||
ntlm/accept_sec_context.c \
|
||||
ntlm/acquire_cred.c \
|
||||
ntlm/add_cred.c \
|
||||
ntlm/canonicalize_name.c \
|
||||
ntlm/compare_name.c \
|
||||
ntlm/context_time.c \
|
||||
ntlm/creds.c \
|
||||
ntlm/crypto.c \
|
||||
ntlm/delete_sec_context.c \
|
||||
ntlm/display_name.c \
|
||||
ntlm/display_status.c \
|
||||
ntlm/duplicate_name.c \
|
||||
ntlm/export_name.c \
|
||||
ntlm/export_sec_context.c \
|
||||
ntlm/external.c \
|
||||
ntlm/ntlm.h \
|
||||
ntlm/import_name.c \
|
||||
ntlm/import_sec_context.c \
|
||||
ntlm/indicate_mechs.c \
|
||||
ntlm/init_sec_context.c \
|
||||
ntlm/inquire_context.c \
|
||||
ntlm/inquire_cred_by_mech.c \
|
||||
ntlm/inquire_mechs_for_name.c \
|
||||
ntlm/inquire_names_for_mech.c \
|
||||
ntlm/inquire_sec_context_by_oid.c \
|
||||
ntlm/iter_cred.c \
|
||||
ntlm/process_context_token.c \
|
||||
ntlm/release_cred.c \
|
||||
ntlm/release_name.c \
|
||||
ntlm/set_sec_context_option.c \
|
||||
ntlm/kdc.c
|
||||
|
||||
$(srcdir)/ntlm/ntlm-private.h: $(ntlmsrc)
|
||||
cd $(srcdir) && perl ../../cf/make-proto.pl -q -P comment -p ntlm/ntlm-private.h $(ntlmsrc) || rm -f ntlm/ntlm-private.h
|
||||
|
||||
sanonsrc = \
|
||||
sanon/accept_sec_context.c \
|
||||
sanon/acquire_cred.c \
|
||||
@@ -259,7 +222,6 @@ sanonsrc = \
|
||||
dist_libgssapi_la_SOURCES = \
|
||||
$(krb5src) \
|
||||
$(mechsrc) \
|
||||
$(ntlmsrc) \
|
||||
$(spnegosrc) \
|
||||
$(sanonsrc)
|
||||
|
||||
@@ -275,7 +237,6 @@ libgssapi_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map
|
||||
endif
|
||||
|
||||
libgssapi_la_LIBADD = \
|
||||
$(top_builddir)/lib/ntlm/libheimntlm.la \
|
||||
$(top_builddir)/lib/krb5/libkrb5.la \
|
||||
$(top_builddir)/lib/asn1/libasn1.la \
|
||||
$(LIB_com_err) \
|
||||
@@ -287,7 +248,6 @@ include_HEADERS = gssapi.h
|
||||
noinst_HEADERS = \
|
||||
gssapi_asn1.h \
|
||||
gssapi_mech.h \
|
||||
$(srcdir)/ntlm/ntlm-private.h \
|
||||
$(srcdir)/spnego/spnego-private.h \
|
||||
$(srcdir)/sanon/sanon-private.h \
|
||||
$(srcdir)/krb5/gsskrb5-private.h
|
||||
@@ -295,7 +255,6 @@ noinst_HEADERS = \
|
||||
nobase_include_HEADERS = \
|
||||
gssapi/gssapi.h \
|
||||
gssapi/gssapi_krb5.h \
|
||||
gssapi/gssapi_ntlm.h \
|
||||
gssapi/gssapi_oid.h \
|
||||
gssapi/gssapi_spnego.h
|
||||
|
||||
@@ -320,8 +279,7 @@ spnego_files = \
|
||||
BUILTHEADERS = \
|
||||
$(srcdir)/krb5/gsskrb5-private.h \
|
||||
$(srcdir)/spnego/spnego-private.h \
|
||||
$(srcdir)/sanon/sanon-private.h \
|
||||
$(srcdir)/ntlm/ntlm-private.h
|
||||
$(srcdir)/sanon/sanon-private.h
|
||||
|
||||
$(libgssapi_la_OBJECTS): $(BUILTHEADERS)
|
||||
$(test_context_OBJECTS): $(BUILTHEADERS)
|
||||
@@ -383,10 +341,9 @@ test_cfx_SOURCES = krb5/test_cfx.c
|
||||
check_PROGRAMS = test_acquire_cred test_acquire_cred_auditdns $(TESTS)
|
||||
|
||||
bin_PROGRAMS = gsstool gss-token
|
||||
noinst_PROGRAMS = test_cred test_kcred test_context test_ntlm test_add_store_cred
|
||||
noinst_PROGRAMS = test_cred test_kcred test_context test_add_store_cred
|
||||
|
||||
test_context_SOURCES = test_context.c test_common.c test_common.h
|
||||
test_ntlm_SOURCES = test_ntlm.c test_common.c test_common.h
|
||||
test_acquire_cred_SOURCES = test_acquire_cred.c test_common.c test_common.h
|
||||
test_acquire_cred_auditdns_SOURCES = \
|
||||
test_acquire_cred.c test_common.c test_common.h \
|
||||
@@ -394,10 +351,6 @@ test_acquire_cred_auditdns_SOURCES = \
|
||||
|
||||
test_add_store_cred_SOURCES = test_add_store_cred.c
|
||||
|
||||
test_ntlm_LDADD = \
|
||||
$(top_builddir)/lib/ntlm/libheimntlm.la \
|
||||
$(LDADD)
|
||||
|
||||
LDADD = libgssapi.la \
|
||||
$(top_builddir)/lib/krb5/libkrb5.la \
|
||||
$(LIB_roken)
|
||||
@@ -433,7 +386,6 @@ EXTRA_DIST = \
|
||||
libgssapi-exports.def \
|
||||
$(man_MANS) \
|
||||
gen-oid.pl \
|
||||
gssapi/gssapi_netlogon.h \
|
||||
krb5/test_acquire_cred.c \
|
||||
krb5/test_cred.c \
|
||||
krb5/test_kcred.c \
|
||||
|
||||
+4
-90
@@ -199,40 +199,6 @@ spnegosrc = \
|
||||
spnego/spnego_locl.h \
|
||||
spnego/negoex_locl.h
|
||||
|
||||
ntlmsrc = \
|
||||
ntlm/accept_sec_context.c \
|
||||
ntlm/acquire_cred.c \
|
||||
ntlm/add_cred.c \
|
||||
ntlm/canonicalize_name.c \
|
||||
ntlm/compare_name.c \
|
||||
ntlm/context_time.c \
|
||||
ntlm/creds.c \
|
||||
ntlm/crypto.c \
|
||||
ntlm/delete_sec_context.c \
|
||||
ntlm/display_name.c \
|
||||
ntlm/display_status.c \
|
||||
ntlm/duplicate_name.c \
|
||||
ntlm/duplicate_cred.c \
|
||||
ntlm/export_name.c \
|
||||
ntlm/export_sec_context.c \
|
||||
ntlm/external.c \
|
||||
ntlm/ntlm.h \
|
||||
ntlm/import_name.c \
|
||||
ntlm/import_sec_context.c \
|
||||
ntlm/indicate_mechs.c \
|
||||
ntlm/init_sec_context.c \
|
||||
ntlm/inquire_context.c \
|
||||
ntlm/inquire_cred_by_mech.c \
|
||||
ntlm/inquire_mechs_for_name.c \
|
||||
ntlm/inquire_names_for_mech.c \
|
||||
ntlm/inquire_sec_context_by_oid.c \
|
||||
ntlm/iter_cred.c \
|
||||
ntlm/process_context_token.c \
|
||||
ntlm/release_cred.c \
|
||||
ntlm/release_name.c \
|
||||
ntlm/set_sec_context_option.c \
|
||||
ntlm/kdc.c
|
||||
|
||||
sanonsrc = \
|
||||
sanon/accept_sec_context.c \
|
||||
sanon/acquire_cred.c \
|
||||
@@ -265,9 +231,6 @@ sanonsrc = \
|
||||
sanon/release_cred.c \
|
||||
sanon/release_name.c
|
||||
|
||||
$(OBJ)\ntlm\ntlm-private.h: $(ntlmsrc)
|
||||
$(PERL) ../../cf/make-proto.pl -q -P remove -p $@ $(ntlmsrc)
|
||||
|
||||
$(OBJ)\krb5\gsskrb5-private.h: $(krb5src)
|
||||
$(PERL) ../../cf/make-proto.pl -q -P remove -p $@ $(krb5src)
|
||||
|
||||
@@ -307,10 +270,8 @@ INCFILES= \
|
||||
$(INCDIR)\gssapi\gssapi.h \
|
||||
$(INCDIR)\gssapi\gssapi_krb5.h \
|
||||
$(INCDIR)\gssapi\gssapi_oid.h \
|
||||
$(INCDIR)\gssapi\gssapi_ntlm.h \
|
||||
$(INCDIR)\gssapi\gssapi_spnego.h \
|
||||
$(INCDIR)\gssapi\gkrb5_err.h \
|
||||
$(OBJ)\ntlm\ntlm-private.h \
|
||||
$(OBJ)\spnego\spnego-private.h \
|
||||
$(OBJ)\sanon\sanon-private.h \
|
||||
$(OBJ)\krb5\gsskrb5-private.h \
|
||||
@@ -470,37 +431,6 @@ libgssapi_OBJs = \
|
||||
$(OBJ)\spnego/init_sec_context.obj \
|
||||
$(OBJ)\spnego/negoex_ctx.obj \
|
||||
$(OBJ)\spnego/negoex_util.obj \
|
||||
$(OBJ)\ntlm/accept_sec_context.obj \
|
||||
$(OBJ)\ntlm/acquire_cred.obj \
|
||||
$(OBJ)\ntlm/add_cred.obj \
|
||||
$(OBJ)\ntlm/canonicalize_name.obj \
|
||||
$(OBJ)\ntlm/compare_name.obj \
|
||||
$(OBJ)\ntlm/context_time.obj \
|
||||
$(OBJ)\ntlm/creds.obj \
|
||||
$(OBJ)\ntlm/crypto.obj \
|
||||
$(OBJ)\ntlm/delete_sec_context.obj \
|
||||
$(OBJ)\ntlm/display_name.obj \
|
||||
$(OBJ)\ntlm/display_status.obj \
|
||||
$(OBJ)\ntlm/duplicate_cred.obj \
|
||||
$(OBJ)\ntlm/duplicate_name.obj \
|
||||
$(OBJ)\ntlm/export_name.obj \
|
||||
$(OBJ)\ntlm/export_sec_context.obj \
|
||||
$(OBJ)\ntlm/external.obj \
|
||||
$(OBJ)\ntlm/import_name.obj \
|
||||
$(OBJ)\ntlm/import_sec_context.obj \
|
||||
$(OBJ)\ntlm/indicate_mechs.obj \
|
||||
$(OBJ)\ntlm/init_sec_context.obj \
|
||||
$(OBJ)\ntlm/inquire_context.obj \
|
||||
$(OBJ)\ntlm/inquire_cred_by_mech.obj \
|
||||
$(OBJ)\ntlm/inquire_mechs_for_name.obj \
|
||||
$(OBJ)\ntlm/inquire_names_for_mech.obj \
|
||||
$(OBJ)\ntlm/inquire_sec_context_by_oid.obj \
|
||||
$(OBJ)\ntlm/iter_cred.obj \
|
||||
$(OBJ)\ntlm/process_context_token.obj \
|
||||
$(OBJ)\ntlm/release_cred.obj \
|
||||
$(OBJ)\ntlm/release_name.obj \
|
||||
$(OBJ)\ntlm/set_sec_context_option.obj \
|
||||
$(OBJ)\ntlm/kdc.obj \
|
||||
$(OBJ)\sanon/accept_sec_context.obj \
|
||||
$(OBJ)\sanon/acquire_cred.obj \
|
||||
$(OBJ)\sanon/add_cred.obj \
|
||||
@@ -550,12 +480,6 @@ GCOPTS=-I$(SRCDIR) -I$(OBJ) -Igssapi -DBUILD_GSSAPI_LIB
|
||||
{mech}.c{$(OBJ)\mech}.obj::
|
||||
$(C2OBJ_NP) -Fo$(OBJ)\mech\ -Fd$(OBJ)\mech\ -I$(OBJ)\mech -I$(OBJ)\gssapi $(GCOPTS) -DASN1_LIB
|
||||
|
||||
{$(OBJ)\ntlm}.c{$(OBJ)\ntlm}.obj::
|
||||
$(C2OBJ_NP) -Fo$(OBJ)\ntlm\ -Fd$(OBJ)\ntlm\ -I$(OBJ)\ntlm $(GCOPTS)
|
||||
|
||||
{ntlm}.c{$(OBJ)\ntlm}.obj::
|
||||
$(C2OBJ_NP) -Fo$(OBJ)\ntlm\ -Fd$(OBJ)\ntlm\ -I$(OBJ)\ntlm $(GCOPTS) -DASN1_LIB
|
||||
|
||||
{$(OBJ)\spnego}.c{$(OBJ)\spnego}.obj::
|
||||
$(C2OBJ_NP) -Fo$(OBJ)\spnego\ -Fd$(OBJ)\spnego\ -I$(OBJ)\spnego $(GCOPTS)
|
||||
|
||||
@@ -584,8 +508,8 @@ LIBGSSAPI_LIBS=\
|
||||
$(LIBHEIMBASE) \
|
||||
$(LIBROKEN) \
|
||||
$(LIBHEIMDAL) \
|
||||
$(LIBHEIMNTLM) \
|
||||
$(LIBCOMERR)
|
||||
$(LIBCOMERR) \
|
||||
$(LIB_openssl_crypto)
|
||||
|
||||
LIBGSSAPI_SDKLIBS=\
|
||||
$(PTHREAD_LIB) \
|
||||
@@ -628,9 +552,6 @@ clean::
|
||||
prep:: mkdirs-gss
|
||||
|
||||
mkdirs-gss:
|
||||
!if !exist($(OBJ)\ntlm)
|
||||
$(MKDIR) $(OBJ)\ntlm
|
||||
!endif
|
||||
!if !exist($(OBJ)\krb5)
|
||||
$(MKDIR) $(OBJ)\krb5
|
||||
!endif
|
||||
@@ -648,7 +569,6 @@ mkdirs-gss:
|
||||
!endif
|
||||
|
||||
clean::
|
||||
-$(RM) $(OBJ)\ntlm\*.*
|
||||
-$(RM) $(OBJ)\krb5\*.*
|
||||
-$(RM) $(OBJ)\spnego\*.*
|
||||
-$(RM) $(OBJ)\mech\*.*
|
||||
@@ -676,7 +596,7 @@ $(OBJ)\gss-commands.c $(OBJ)\gss-commands.h: gss-commands.in
|
||||
"\t$(OBJ)\\negoex_err.obj \\\n"
|
||||
"\t$(OBJ)\\spnego\\asn1_spnego_asn1.obj \\\n"
|
||||
"\t$(OBJ)\\gssapi\\asn1_gssapi_asn1.obj")
|
||||
"krb5src" "mechsrc" "spnegosrc" "ntlmsrc")
|
||||
"krb5src" "mechsrc" "spnegosrc")
|
||||
!endif
|
||||
|
||||
test-exports:
|
||||
@@ -692,8 +612,7 @@ TEST_BINARIES=\
|
||||
$(OBJ)\test_acquire_cred.exe \
|
||||
$(OBJ)\test_cred.exe \
|
||||
$(OBJ)\test_kcred.exe \
|
||||
$(OBJ)\test_context.exe \
|
||||
$(OBJ)\test_ntlm.exe
|
||||
$(OBJ)\test_context.exe
|
||||
|
||||
$(OBJ)\test_oid.exe: $(OBJ)\test_oid.obj $(LIBGSSAPI) $(LIBROKEN)
|
||||
$(EXECONLINK)
|
||||
@@ -726,11 +645,6 @@ $(OBJ)\test_context.exe: $(OBJ)\test_context.obj $(OBJ)\test_common.obj \
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
$(OBJ)\test_ntlm.exe: $(OBJ)\test_ntlm.obj $(OBJ)\test_common.obj \
|
||||
$(LIBGSSAPI) $(LIBHEIMNTLM) $(LIBROKEN) $(LIBVERS)
|
||||
$(EXECONLINK)
|
||||
$(EXEPREP_NODIST)
|
||||
|
||||
{}.c{$(OBJ)}.obj::
|
||||
$(C2OBJ_P) -I$(OBJ)\krb5 -I$(OBJ) -I$(SRCDIR) -I$(SRCDIR)\gssapi
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006 - 2009 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef GSSAPI_NTLM_H_
|
||||
#define GSSAPI_NTLM_H_
|
||||
|
||||
#include <gssapi.h>
|
||||
|
||||
#endif /* GSSAPI_NTLM_H_ */
|
||||
@@ -647,7 +647,6 @@ _gss_mg_support_mechanism(gss_const_OID mech);
|
||||
|
||||
gssapi_mech_interface __gss_spnego_initialize(void);
|
||||
gssapi_mech_interface __gss_krb5_initialize(void);
|
||||
gssapi_mech_interface __gss_ntlm_initialize(void);
|
||||
gssapi_mech_interface __gss_sanon_initialize(void);
|
||||
|
||||
void gss_mg_collect_error(gss_OID, OM_uint32, OM_uint32);
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <gssapi.h>
|
||||
#include <gssapi_krb5.h>
|
||||
#include <gssapi_spnego.h>
|
||||
#include <gssapi_ntlm.h>
|
||||
#include <err.h>
|
||||
#include <getarg.h>
|
||||
#include <rtbl.h>
|
||||
|
||||
+179
-73
@@ -240,7 +240,7 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
|
||||
int32_t seq_number;
|
||||
size_t len, total_len;
|
||||
u_char k6_data[16], *p0, *p;
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
_gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
|
||||
@@ -302,10 +302,19 @@ _gssapi_get_mic_arcfour(OM_uint32 * minor_status,
|
||||
|
||||
memset (p + 4, (context_handle->more_flags & LOCAL) ? 0 : 0xff, 4);
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, p, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
if ((rc4_key = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||
EVP_Cipher(rc4_key, p, p, 8) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
|
||||
memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data));
|
||||
|
||||
@@ -375,14 +384,22 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
|
||||
}
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, (void *)k6_data, NULL, 0);
|
||||
EVP_Cipher(&rc4_key, SND_SEQ, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
if ((rc4_key = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, (void *)k6_data, NULL, 0) != 1 ||
|
||||
EVP_Cipher(rc4_key, SND_SEQ, p, 8) != 1) {
|
||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data));
|
||||
}
|
||||
|
||||
_gss_mg_decode_be_uint32(SND_SEQ, &seq_number);
|
||||
@@ -528,14 +545,23 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
|
||||
|
||||
|
||||
if(conf_req_flag) {
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8 + datalen);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
if ((rc4_key = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8 + datalen) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
}
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data));
|
||||
|
||||
ret = arcfour_mic_key(context, key,
|
||||
p0 + 16, 8, /* SGN_CKSUM */
|
||||
@@ -547,12 +573,21 @@ _gssapi_wrap_arcfour(OM_uint32 * minor_status,
|
||||
}
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
if ((rc4_key = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||
EVP_Cipher(rc4_key, p0 + 8, p0 + 8 /* SND_SEQ */, 8) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data));
|
||||
}
|
||||
|
||||
@@ -647,12 +682,21 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
|
||||
}
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, SND_SEQ, p0 + 8, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
if ((rc4_key = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||
EVP_Cipher(rc4_key, SND_SEQ, p0 + 8, 8) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data));
|
||||
}
|
||||
|
||||
@@ -695,20 +739,29 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
|
||||
output_message_buffer->length = datalen;
|
||||
|
||||
if(conf_flag) {
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8);
|
||||
EVP_Cipher(&rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen);
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
if ((rc4_key = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 1 ||
|
||||
EVP_Cipher(rc4_key, output_message_buffer->value, p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE, datalen) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
} else {
|
||||
memcpy(Confounder, p0 + 24, 8); /* Confounder */
|
||||
memcpy(output_message_buffer->value,
|
||||
p0 + GSS_ARCFOUR_WRAP_TOKEN_SIZE,
|
||||
datalen);
|
||||
}
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data));
|
||||
|
||||
if (!IS_DCE_STYLE(context_handle)) {
|
||||
ret = _gssapi_verify_pad(output_message_buffer, datalen, &padlen);
|
||||
@@ -1087,13 +1140,21 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
||||
}
|
||||
|
||||
if (conf_req_flag) {
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
|
||||
/* Confounder */
|
||||
EVP_Cipher(&rc4_key, p0 + 24, p0 + 24, 8);
|
||||
if ((rc4_key = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||
/* Confounder */
|
||||
EVP_Cipher(rc4_key, p0 + 24, p0 + 24, 8) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/* Seal Data */
|
||||
for (i=0; i < iov_count; i++) {
|
||||
@@ -1104,19 +1165,28 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
||||
continue;
|
||||
}
|
||||
|
||||
EVP_Cipher(&rc4_key, iov[i].buffer.value,
|
||||
iov[i].buffer.value, iov[i].buffer.length);
|
||||
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
|
||||
iov[i].buffer.value, iov[i].buffer.length) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Padding */
|
||||
if (padding) {
|
||||
EVP_Cipher(&rc4_key, padding->buffer.value,
|
||||
padding->buffer.value, padding->buffer.length);
|
||||
if (padding &&
|
||||
EVP_Cipher(rc4_key, padding->buffer.value,
|
||||
padding->buffer.value, padding->buffer.length) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
}
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data));
|
||||
|
||||
kret = arcfour_mic_key(context, key,
|
||||
p0 + 16, 8, /* SGN_CKSUM */
|
||||
@@ -1128,14 +1198,23 @@ _gssapi_wrap_iov_arcfour(OM_uint32 *minor_status,
|
||||
}
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, p0 + 8, p0 + 8, 8); /* SND_SEQ */
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
if ((rc4_key = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||
EVP_Cipher(rc4_key, p0 + 8, p0 + 8, 8) != 1 /* SND_SEQ */) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data));
|
||||
}
|
||||
|
||||
if (conf_state)
|
||||
@@ -1201,7 +1280,8 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
||||
}
|
||||
|
||||
if (padding != NULL && padding->buffer.length != 1) {
|
||||
*minor_status = EINVAL;
|
||||
_krb5_debug(context, 4, "Padding does not match");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
@@ -1269,14 +1349,23 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
||||
}
|
||||
|
||||
{
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
EVP_Cipher(&rc4_key, snd_seq, p0 + 8, 8); /* SND_SEQ */
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
if ((rc4_key = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||
EVP_Cipher(rc4_key, snd_seq, p0 + 8, 8) != 1 /* SND_SEQ */) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data));
|
||||
}
|
||||
|
||||
_gss_mg_decode_be_uint32(snd_seq, &seq_number);
|
||||
@@ -1312,13 +1401,21 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
||||
}
|
||||
|
||||
if (conf_state == 1) {
|
||||
EVP_CIPHER_CTX rc4_key;
|
||||
EVP_CIPHER_CTX *rc4_key;
|
||||
|
||||
EVP_CIPHER_CTX_init(&rc4_key);
|
||||
EVP_CipherInit_ex(&rc4_key, EVP_rc4(), NULL, k6_data, NULL, 1);
|
||||
|
||||
/* Confounder */
|
||||
EVP_Cipher(&rc4_key, Confounder, p0 + 24, 8);
|
||||
if ((rc4_key = EVP_CIPHER_CTX_new()) == NULL) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (EVP_CIPHER_CTX_init(rc4_key) != 1 ||
|
||||
EVP_CipherInit_ex(rc4_key, context->ossl->rc4, NULL, k6_data, NULL, 1) != 1 ||
|
||||
/* Confounder */
|
||||
EVP_Cipher(rc4_key, Confounder, p0 + 24, 8) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/* Data */
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
@@ -1329,22 +1426,31 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
|
||||
continue;
|
||||
}
|
||||
|
||||
EVP_Cipher(&rc4_key, iov[i].buffer.value,
|
||||
iov[i].buffer.value, iov[i].buffer.length);
|
||||
if (EVP_Cipher(rc4_key, iov[i].buffer.value,
|
||||
iov[i].buffer.value, iov[i].buffer.length) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not decrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Padding */
|
||||
if (padding) {
|
||||
EVP_Cipher(&rc4_key, padding->buffer.value,
|
||||
padding->buffer.value, padding->buffer.length);
|
||||
if (padding &&
|
||||
EVP_Cipher(rc4_key, padding->buffer.value,
|
||||
padding->buffer.value, padding->buffer.length) != 1) {
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
_krb5_debug_openssl(context, 4, "Could not encrypt with RC4 with OpenSSL");
|
||||
*minor_status = KRB5_CRYPTO_INTERNAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&rc4_key);
|
||||
EVP_CIPHER_CTX_free(rc4_key);
|
||||
} else {
|
||||
/* Confounder */
|
||||
memcpy(Confounder, p0 + 24, 8);
|
||||
}
|
||||
memset(k6_data, 0, sizeof(k6_data));
|
||||
memset_s(k6_data, sizeof(k6_data), 0, sizeof(k6_data));
|
||||
|
||||
/* Prepare the buffer for signing */
|
||||
kret = arcfour_mic_cksum_iov(context,
|
||||
|
||||
+1
-247
@@ -33,246 +33,6 @@
|
||||
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
#ifdef HEIM_WEAK_CRYPTO
|
||||
|
||||
static OM_uint32
|
||||
mic_des
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx ctx,
|
||||
krb5_context context,
|
||||
gss_qop_t qop_req,
|
||||
const gss_buffer_t message_buffer,
|
||||
gss_buffer_t message_token,
|
||||
krb5_keyblock *key
|
||||
)
|
||||
{
|
||||
u_char *p;
|
||||
EVP_MD_CTX *md5;
|
||||
u_char hash[16];
|
||||
DES_key_schedule schedule;
|
||||
EVP_CIPHER_CTX des_ctx;
|
||||
DES_cblock deskey;
|
||||
DES_cblock zero;
|
||||
int32_t seq_number;
|
||||
size_t len, total_len;
|
||||
|
||||
_gsskrb5_encap_length (22, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
|
||||
message_token->length = total_len;
|
||||
message_token->value = malloc (total_len);
|
||||
if (message_token->value == NULL) {
|
||||
message_token->length = 0;
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
p = _gsskrb5_make_header(message_token->value,
|
||||
len,
|
||||
"\x01\x01", /* TOK_ID */
|
||||
GSS_KRB5_MECHANISM);
|
||||
|
||||
memcpy (p, "\x00\x00", 2); /* SGN_ALG = DES MAC MD5 */
|
||||
p += 2;
|
||||
|
||||
memcpy (p, "\xff\xff\xff\xff", 4); /* Filler */
|
||||
p += 4;
|
||||
|
||||
/* Fill in later (SND-SEQ) */
|
||||
memset (p, 0, 16);
|
||||
p += 16;
|
||||
|
||||
/* checksum */
|
||||
md5 = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(md5, EVP_md5(), NULL);
|
||||
EVP_DigestUpdate(md5, p - 24, 8);
|
||||
EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
|
||||
EVP_DigestFinal_ex(md5, hash, NULL);
|
||||
EVP_MD_CTX_destroy(md5);
|
||||
|
||||
memset (&zero, 0, sizeof(zero));
|
||||
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
|
||||
DES_set_key_unchecked (&deskey, &schedule);
|
||||
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
|
||||
&schedule, &zero);
|
||||
memcpy (p - 8, hash, 8); /* SGN_CKSUM */
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
/* sequence number */
|
||||
krb5_auth_con_getlocalseqnumber (context,
|
||||
ctx->auth_context,
|
||||
&seq_number);
|
||||
|
||||
p -= 16; /* SND_SEQ */
|
||||
p[0] = (seq_number >> 0) & 0xFF;
|
||||
p[1] = (seq_number >> 8) & 0xFF;
|
||||
p[2] = (seq_number >> 16) & 0xFF;
|
||||
p[3] = (seq_number >> 24) & 0xFF;
|
||||
memset (p + 4,
|
||||
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
|
||||
4);
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
|
||||
EVP_Cipher(&des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
|
||||
krb5_auth_con_setlocalseqnumber (context,
|
||||
ctx->auth_context,
|
||||
++seq_number);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
memset_s(deskey, sizeof(deskey), 0, sizeof(deskey));
|
||||
memset_s(&schedule, sizeof(schedule), 0, sizeof(schedule));
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static OM_uint32
|
||||
mic_des3
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx ctx,
|
||||
krb5_context context,
|
||||
gss_qop_t qop_req,
|
||||
const gss_buffer_t message_buffer,
|
||||
gss_buffer_t message_token,
|
||||
krb5_keyblock *key
|
||||
)
|
||||
{
|
||||
u_char *p;
|
||||
Checksum cksum;
|
||||
u_char seq[8];
|
||||
|
||||
int32_t seq_number;
|
||||
size_t len, total_len;
|
||||
|
||||
krb5_crypto crypto;
|
||||
krb5_error_code kret;
|
||||
krb5_data encdata;
|
||||
char *tmp;
|
||||
char ivec[8];
|
||||
|
||||
_gsskrb5_encap_length (36, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
|
||||
message_token->length = total_len;
|
||||
message_token->value = malloc (total_len);
|
||||
if (message_token->value == NULL) {
|
||||
message_token->length = 0;
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
p = _gsskrb5_make_header(message_token->value,
|
||||
len,
|
||||
"\x01\x01", /* TOK-ID */
|
||||
GSS_KRB5_MECHANISM);
|
||||
|
||||
memcpy (p, "\x04\x00", 2); /* SGN_ALG = HMAC SHA1 DES3-KD */
|
||||
p += 2;
|
||||
|
||||
memcpy (p, "\xff\xff\xff\xff", 4); /* filler */
|
||||
p += 4;
|
||||
|
||||
/* this should be done in parts */
|
||||
|
||||
tmp = malloc (message_buffer->length + 8);
|
||||
if (tmp == NULL) {
|
||||
free (message_token->value);
|
||||
message_token->value = NULL;
|
||||
message_token->length = 0;
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
memcpy (tmp, p - 8, 8);
|
||||
memcpy (tmp + 8, message_buffer->value, message_buffer->length);
|
||||
|
||||
kret = krb5_crypto_init(context, key, 0, &crypto);
|
||||
if (kret) {
|
||||
free (message_token->value);
|
||||
message_token->value = NULL;
|
||||
message_token->length = 0;
|
||||
free (tmp);
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
kret = krb5_create_checksum (context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SIGN,
|
||||
0,
|
||||
tmp,
|
||||
message_buffer->length + 8,
|
||||
&cksum);
|
||||
free (tmp);
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
if (kret) {
|
||||
free (message_token->value);
|
||||
message_token->value = NULL;
|
||||
message_token->length = 0;
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
memcpy (p + 8, cksum.checksum.data, cksum.checksum.length);
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
/* sequence number */
|
||||
krb5_auth_con_getlocalseqnumber (context,
|
||||
ctx->auth_context,
|
||||
&seq_number);
|
||||
|
||||
seq[0] = (seq_number >> 0) & 0xFF;
|
||||
seq[1] = (seq_number >> 8) & 0xFF;
|
||||
seq[2] = (seq_number >> 16) & 0xFF;
|
||||
seq[3] = (seq_number >> 24) & 0xFF;
|
||||
memset (seq + 4,
|
||||
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
|
||||
4);
|
||||
|
||||
kret = krb5_crypto_init(context, key,
|
||||
ETYPE_DES3_CBC_NONE, &crypto);
|
||||
if (kret) {
|
||||
free (message_token->value);
|
||||
message_token->value = NULL;
|
||||
message_token->length = 0;
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (ctx->more_flags & COMPAT_OLD_DES3)
|
||||
memset(ivec, 0, 8);
|
||||
else
|
||||
memcpy(ivec, p + 8, 8);
|
||||
|
||||
kret = krb5_encrypt_ivec (context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SEQ,
|
||||
seq, 8, &encdata, ivec);
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
if (kret) {
|
||||
free (message_token->value);
|
||||
message_token->value = NULL;
|
||||
message_token->length = 0;
|
||||
*minor_status = kret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
assert (encdata.length == 8);
|
||||
|
||||
memcpy (p, encdata.data, encdata.length);
|
||||
krb5_data_free (&encdata);
|
||||
|
||||
krb5_auth_con_setlocalseqnumber (context,
|
||||
ctx->auth_context,
|
||||
++seq_number);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
free_Checksum (&cksum);
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
|
||||
(OM_uint32 * minor_status,
|
||||
gss_const_ctx_id_t context_handle,
|
||||
@@ -304,17 +64,11 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_get_mic
|
||||
case KRB5_ENCTYPE_DES_CBC_CRC :
|
||||
case KRB5_ENCTYPE_DES_CBC_MD4 :
|
||||
case KRB5_ENCTYPE_DES_CBC_MD5 :
|
||||
#ifdef HEIM_WEAK_CRYPTO
|
||||
ret = mic_des (minor_status, ctx, context, qop_req,
|
||||
message_buffer, message_token, key);
|
||||
#else
|
||||
ret = GSS_S_FAILURE;
|
||||
#endif
|
||||
break;
|
||||
case KRB5_ENCTYPE_DES3_CBC_MD5 :
|
||||
case KRB5_ENCTYPE_DES3_CBC_SHA1 :
|
||||
ret = mic_des3 (minor_status, ctx, context, qop_req,
|
||||
message_buffer, message_token, key);
|
||||
ret = GSS_S_FAILURE;
|
||||
break;
|
||||
case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
|
||||
case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
|
||||
|
||||
+1
-375
@@ -33,372 +33,6 @@
|
||||
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
#ifdef HEIM_WEAK_CRYPTO
|
||||
|
||||
static OM_uint32
|
||||
unwrap_des
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx context_handle,
|
||||
const gss_buffer_t input_message_buffer,
|
||||
gss_buffer_t output_message_buffer,
|
||||
int * conf_state,
|
||||
gss_qop_t * qop_state,
|
||||
krb5_keyblock *key
|
||||
)
|
||||
{
|
||||
u_char *p, *seq;
|
||||
size_t len;
|
||||
EVP_MD_CTX *md5;
|
||||
u_char hash[16];
|
||||
EVP_CIPHER_CTX des_ctx;
|
||||
DES_key_schedule schedule;
|
||||
DES_cblock deskey;
|
||||
DES_cblock zero;
|
||||
size_t i;
|
||||
uint32_t seq_number;
|
||||
size_t padlength;
|
||||
OM_uint32 ret, seq_err;
|
||||
int cstate;
|
||||
int cmp;
|
||||
int token_len;
|
||||
|
||||
if (IS_DCE_STYLE(context_handle)) {
|
||||
token_len = 22 + 8 + 15; /* 45 */
|
||||
if (input_message_buffer->length < token_len)
|
||||
return GSS_S_BAD_MECH;
|
||||
} else {
|
||||
token_len = input_message_buffer->length;
|
||||
}
|
||||
|
||||
p = input_message_buffer->value;
|
||||
ret = _gsskrb5_verify_header (&p,
|
||||
token_len,
|
||||
"\x02\x01",
|
||||
GSS_KRB5_MECHANISM);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
len = (p - (u_char *)input_message_buffer->value)
|
||||
+ 22 + 8;
|
||||
if (input_message_buffer->length < len)
|
||||
return GSS_S_BAD_MECH;
|
||||
|
||||
if (memcmp (p, "\x00\x00", 2) != 0)
|
||||
return GSS_S_BAD_SIG;
|
||||
p += 2;
|
||||
if (memcmp (p, "\x00\x00", 2) == 0) {
|
||||
cstate = 1;
|
||||
} else if (memcmp (p, "\xFF\xFF", 2) == 0) {
|
||||
cstate = 0;
|
||||
} else
|
||||
return GSS_S_BAD_MIC;
|
||||
p += 2;
|
||||
if(conf_state != NULL)
|
||||
*conf_state = cstate;
|
||||
if (memcmp (p, "\xff\xff", 2) != 0)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
p += 2;
|
||||
p += 16;
|
||||
|
||||
len = p - (u_char *)input_message_buffer->value;
|
||||
|
||||
if(cstate) {
|
||||
/* decrypt data */
|
||||
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
|
||||
memset (&zero, 0, sizeof(zero));
|
||||
|
||||
for (i = 0; i < sizeof(deskey); ++i)
|
||||
deskey[i] ^= 0xf0;
|
||||
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 0);
|
||||
EVP_Cipher(&des_ctx, p, p, input_message_buffer->length - len);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
|
||||
memset (&deskey, 0, sizeof(deskey));
|
||||
}
|
||||
|
||||
if (IS_DCE_STYLE(context_handle)) {
|
||||
padlength = 0;
|
||||
} else {
|
||||
/* check pad */
|
||||
ret = _gssapi_verify_pad(input_message_buffer,
|
||||
input_message_buffer->length - len - 8,
|
||||
&padlength);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
md5 = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(md5, EVP_md5(), NULL);
|
||||
EVP_DigestUpdate(md5, p - 24, 8);
|
||||
EVP_DigestUpdate(md5, p, input_message_buffer->length - len);
|
||||
EVP_DigestFinal_ex(md5, hash, NULL);
|
||||
EVP_MD_CTX_destroy(md5);
|
||||
|
||||
memset (&zero, 0, sizeof(zero));
|
||||
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
|
||||
DES_set_key_unchecked (&deskey, &schedule);
|
||||
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
|
||||
&schedule, &zero);
|
||||
if (ct_memcmp (p - 8, hash, 8) != 0) {
|
||||
memset_s(&deskey, sizeof(deskey), 0, sizeof(deskey));
|
||||
memset_s(&schedule, sizeof(schedule), 0, sizeof(schedule));
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
/* verify sequence number */
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
|
||||
p -= 16;
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
|
||||
EVP_Cipher(&des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
|
||||
seq = p;
|
||||
_gss_mg_decode_be_uint32(seq, &seq_number);
|
||||
|
||||
if (context_handle->more_flags & LOCAL)
|
||||
cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
|
||||
else
|
||||
cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
|
||||
|
||||
if (cmp != 0) {
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
seq_err = _gssapi_msg_order_check(context_handle->order, seq_number);
|
||||
if (seq_err == GSS_S_FAILURE) {
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return seq_err;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
|
||||
/* copy out data */
|
||||
|
||||
output_message_buffer->length = input_message_buffer->length
|
||||
- len - padlength - 8;
|
||||
output_message_buffer->value = malloc(output_message_buffer->length);
|
||||
if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
|
||||
return GSS_S_FAILURE;
|
||||
if (output_message_buffer->value != NULL)
|
||||
memcpy (output_message_buffer->value,
|
||||
p + 24,
|
||||
output_message_buffer->length);
|
||||
return GSS_S_COMPLETE | seq_err;
|
||||
}
|
||||
#endif
|
||||
|
||||
static OM_uint32
|
||||
unwrap_des3
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx context_handle,
|
||||
krb5_context context,
|
||||
const gss_buffer_t input_message_buffer,
|
||||
gss_buffer_t output_message_buffer,
|
||||
int * conf_state,
|
||||
gss_qop_t * qop_state,
|
||||
krb5_keyblock *key
|
||||
)
|
||||
{
|
||||
u_char *p;
|
||||
size_t len;
|
||||
u_char *seq;
|
||||
krb5_data seq_data;
|
||||
u_char cksum[20];
|
||||
uint32_t seq_number;
|
||||
size_t padlength;
|
||||
OM_uint32 ret, seq_err;
|
||||
int cstate;
|
||||
krb5_crypto crypto;
|
||||
Checksum csum;
|
||||
int cmp;
|
||||
int token_len;
|
||||
|
||||
if (IS_DCE_STYLE(context_handle)) {
|
||||
token_len = 34 + 8 + 15; /* 57 */
|
||||
if (input_message_buffer->length < token_len)
|
||||
return GSS_S_BAD_MECH;
|
||||
} else {
|
||||
token_len = input_message_buffer->length;
|
||||
}
|
||||
|
||||
p = input_message_buffer->value;
|
||||
ret = _gsskrb5_verify_header (&p,
|
||||
token_len,
|
||||
"\x02\x01",
|
||||
GSS_KRB5_MECHANISM);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
len = (p - (u_char *)input_message_buffer->value)
|
||||
+ 34 + 8;
|
||||
if (input_message_buffer->length < len)
|
||||
return GSS_S_BAD_MECH;
|
||||
|
||||
if (ct_memcmp (p, "\x04\x00", 2) != 0) /* HMAC SHA1 DES3_KD */
|
||||
return GSS_S_BAD_SIG;
|
||||
p += 2;
|
||||
if (ct_memcmp (p, "\x02\x00", 2) == 0) {
|
||||
cstate = 1;
|
||||
} else if (ct_memcmp (p, "\xff\xff", 2) == 0) {
|
||||
cstate = 0;
|
||||
} else
|
||||
return GSS_S_BAD_MIC;
|
||||
p += 2;
|
||||
if(conf_state != NULL)
|
||||
*conf_state = cstate;
|
||||
if (ct_memcmp (p, "\xff\xff", 2) != 0)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
p += 2;
|
||||
p += 28;
|
||||
|
||||
len = p - (u_char *)input_message_buffer->value;
|
||||
|
||||
if(cstate) {
|
||||
/* decrypt data */
|
||||
krb5_data tmp;
|
||||
|
||||
ret = krb5_crypto_init(context, key,
|
||||
ETYPE_DES3_CBC_NONE, &crypto);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
ret = krb5_decrypt(context, crypto, KRB5_KU_USAGE_SEAL,
|
||||
p, input_message_buffer->length - len, &tmp);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
assert (tmp.length == input_message_buffer->length - len);
|
||||
|
||||
memcpy (p, tmp.data, tmp.length);
|
||||
krb5_data_free(&tmp);
|
||||
}
|
||||
|
||||
if (IS_DCE_STYLE(context_handle)) {
|
||||
padlength = 0;
|
||||
} else {
|
||||
/* check pad */
|
||||
ret = _gssapi_verify_pad(input_message_buffer,
|
||||
input_message_buffer->length - len - 8,
|
||||
&padlength);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* verify sequence number */
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
|
||||
p -= 28;
|
||||
|
||||
ret = krb5_crypto_init(context, key,
|
||||
ETYPE_DES3_CBC_NONE, &crypto);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
{
|
||||
DES_cblock ivec;
|
||||
|
||||
memcpy(&ivec, p + 8, 8);
|
||||
ret = krb5_decrypt_ivec (context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SEQ,
|
||||
p, 8, &seq_data,
|
||||
&ivec);
|
||||
}
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
if (seq_data.length != 8) {
|
||||
krb5_data_free (&seq_data);
|
||||
*minor_status = 0;
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
seq = seq_data.data;
|
||||
_gss_mg_decode_be_uint32(seq, &seq_number);
|
||||
|
||||
if (context_handle->more_flags & LOCAL)
|
||||
cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
|
||||
else
|
||||
cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
|
||||
|
||||
krb5_data_free (&seq_data);
|
||||
if (cmp != 0) {
|
||||
*minor_status = 0;
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
seq_err = _gssapi_msg_order_check(context_handle->order, seq_number);
|
||||
if (seq_err == GSS_S_FAILURE) {
|
||||
*minor_status = 0;
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return seq_err;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
|
||||
/* verify checksum */
|
||||
|
||||
memcpy (cksum, p + 8, 20);
|
||||
|
||||
memcpy (p + 20, p - 8, 8);
|
||||
|
||||
csum.cksumtype = CKSUMTYPE_HMAC_SHA1_DES3;
|
||||
csum.checksum.length = 20;
|
||||
csum.checksum.data = cksum;
|
||||
|
||||
ret = krb5_crypto_init(context, key, 0, &crypto);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = krb5_verify_checksum (context, crypto,
|
||||
KRB5_KU_USAGE_SIGN,
|
||||
p + 20,
|
||||
input_message_buffer->length - len + 8,
|
||||
&csum);
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
if (ret) {
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/* copy out data */
|
||||
|
||||
output_message_buffer->length = input_message_buffer->length
|
||||
- len - padlength - 8;
|
||||
output_message_buffer->value = malloc(output_message_buffer->length);
|
||||
if(output_message_buffer->length != 0 && output_message_buffer->value == NULL)
|
||||
return GSS_S_FAILURE;
|
||||
if (output_message_buffer->value != NULL)
|
||||
memcpy (output_message_buffer->value,
|
||||
p + 36,
|
||||
output_message_buffer->length);
|
||||
return GSS_S_COMPLETE | seq_err;
|
||||
}
|
||||
|
||||
OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
|
||||
(OM_uint32 * minor_status,
|
||||
gss_const_ctx_id_t context_handle,
|
||||
@@ -439,19 +73,11 @@ OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
|
||||
case KRB5_ENCTYPE_DES_CBC_CRC :
|
||||
case KRB5_ENCTYPE_DES_CBC_MD4 :
|
||||
case KRB5_ENCTYPE_DES_CBC_MD5 :
|
||||
#ifdef HEIM_WEAK_CRYPTO
|
||||
ret = unwrap_des (minor_status, ctx,
|
||||
input_message_buffer, output_message_buffer,
|
||||
conf_state, qop_state, key);
|
||||
#else
|
||||
ret = GSS_S_FAILURE;
|
||||
#endif
|
||||
break;
|
||||
case KRB5_ENCTYPE_DES3_CBC_MD5 :
|
||||
case KRB5_ENCTYPE_DES3_CBC_SHA1 :
|
||||
ret = unwrap_des3 (minor_status, ctx, context,
|
||||
input_message_buffer, output_message_buffer,
|
||||
conf_state, qop_state, key);
|
||||
ret = GSS_S_FAILURE;
|
||||
break;
|
||||
case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
|
||||
case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
|
||||
|
||||
@@ -33,245 +33,6 @@
|
||||
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
#ifdef HEIM_WEAK_CRYPTO
|
||||
|
||||
static OM_uint32
|
||||
verify_mic_des
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx context_handle,
|
||||
krb5_context context,
|
||||
const gss_buffer_t message_buffer,
|
||||
const gss_buffer_t token_buffer,
|
||||
gss_qop_t * qop_state,
|
||||
krb5_keyblock *key,
|
||||
const char *type
|
||||
)
|
||||
{
|
||||
u_char *p;
|
||||
EVP_MD_CTX *md5;
|
||||
u_char hash[16], *seq;
|
||||
DES_key_schedule schedule;
|
||||
EVP_CIPHER_CTX des_ctx;
|
||||
DES_cblock zero;
|
||||
DES_cblock deskey;
|
||||
uint32_t seq_number;
|
||||
OM_uint32 ret;
|
||||
int cmp;
|
||||
|
||||
p = token_buffer->value;
|
||||
ret = _gsskrb5_verify_header (&p,
|
||||
token_buffer->length,
|
||||
type,
|
||||
GSS_KRB5_MECHANISM);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (memcmp(p, "\x00\x00", 2) != 0)
|
||||
return GSS_S_BAD_SIG;
|
||||
p += 2;
|
||||
if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
|
||||
return GSS_S_BAD_MIC;
|
||||
p += 4;
|
||||
p += 16;
|
||||
|
||||
/* verify checksum */
|
||||
md5 = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(md5, EVP_md5(), NULL);
|
||||
EVP_DigestUpdate(md5, p - 24, 8);
|
||||
EVP_DigestUpdate(md5, message_buffer->value, message_buffer->length);
|
||||
EVP_DigestFinal_ex(md5, hash, NULL);
|
||||
EVP_MD_CTX_destroy(md5);
|
||||
|
||||
memset (&zero, 0, sizeof(zero));
|
||||
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
|
||||
|
||||
DES_set_key_unchecked (&deskey, &schedule);
|
||||
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
|
||||
&schedule, &zero);
|
||||
if (ct_memcmp (p - 8, hash, 8) != 0) {
|
||||
memset_s(deskey, sizeof(deskey), 0, sizeof(deskey));
|
||||
memset_s(&schedule, sizeof(schedule), 0, sizeof(schedule));
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
/* verify sequence number */
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
|
||||
p -= 16;
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, hash, 0);
|
||||
EVP_Cipher(&des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
|
||||
memset_s(deskey, sizeof(deskey), 0, sizeof(deskey));
|
||||
memset_s(&schedule, sizeof(schedule), 0, sizeof(schedule));
|
||||
|
||||
seq = p;
|
||||
_gss_mg_decode_be_uint32(seq, &seq_number);
|
||||
|
||||
if (context_handle->more_flags & LOCAL)
|
||||
cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
|
||||
else
|
||||
cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
|
||||
|
||||
if (cmp != 0) {
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
ret = _gssapi_msg_order_check(context_handle->order, seq_number);
|
||||
if (ret) {
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static OM_uint32
|
||||
verify_mic_des3
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx context_handle,
|
||||
krb5_context context,
|
||||
const gss_buffer_t message_buffer,
|
||||
const gss_buffer_t token_buffer,
|
||||
gss_qop_t * qop_state,
|
||||
krb5_keyblock *key,
|
||||
const char *type
|
||||
)
|
||||
{
|
||||
u_char *p;
|
||||
u_char *seq;
|
||||
uint32_t seq_number;
|
||||
OM_uint32 ret, seq_err;
|
||||
krb5_crypto crypto;
|
||||
krb5_data seq_data;
|
||||
int cmp, docompat;
|
||||
Checksum csum;
|
||||
char *tmp;
|
||||
char ivec[8];
|
||||
|
||||
p = token_buffer->value;
|
||||
ret = _gsskrb5_verify_header (&p,
|
||||
token_buffer->length,
|
||||
type,
|
||||
GSS_KRB5_MECHANISM);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (memcmp(p, "\x04\x00", 2) != 0) /* SGN_ALG = HMAC SHA1 DES3-KD */
|
||||
return GSS_S_BAD_SIG;
|
||||
p += 2;
|
||||
if (memcmp (p, "\xff\xff\xff\xff", 4) != 0)
|
||||
return GSS_S_BAD_MIC;
|
||||
p += 4;
|
||||
|
||||
ret = krb5_crypto_init(context, key,
|
||||
ETYPE_DES3_CBC_NONE, &crypto);
|
||||
if (ret){
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/* verify sequence number */
|
||||
docompat = 0;
|
||||
retry:
|
||||
if (docompat)
|
||||
memset(ivec, 0, 8);
|
||||
else
|
||||
memcpy(ivec, p + 8, 8);
|
||||
|
||||
ret = krb5_decrypt_ivec (context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SEQ,
|
||||
p, 8, &seq_data, ivec);
|
||||
if (ret) {
|
||||
if (docompat++) {
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
} else
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (seq_data.length != 8) {
|
||||
krb5_data_free (&seq_data);
|
||||
if (docompat++) {
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
return GSS_S_BAD_MIC;
|
||||
} else
|
||||
goto retry;
|
||||
}
|
||||
|
||||
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
|
||||
|
||||
seq = seq_data.data;
|
||||
_gss_mg_decode_be_uint32(seq, &seq_number);
|
||||
|
||||
if (context_handle->more_flags & LOCAL)
|
||||
cmp = ct_memcmp(&seq[4], "\xff\xff\xff\xff", 4);
|
||||
else
|
||||
cmp = ct_memcmp(&seq[4], "\x00\x00\x00\x00", 4);
|
||||
|
||||
krb5_data_free (&seq_data);
|
||||
if (cmp != 0) {
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
*minor_status = 0;
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
|
||||
seq_err = _gssapi_msg_order_check(context_handle->order, seq_number);
|
||||
if (seq_err == GSS_S_FAILURE) {
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
*minor_status = 0;
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* verify checksum */
|
||||
|
||||
tmp = malloc (message_buffer->length + 8);
|
||||
if (tmp == NULL) {
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
memcpy (tmp, p - 8, 8);
|
||||
memcpy (tmp + 8, message_buffer->value, message_buffer->length);
|
||||
|
||||
csum.cksumtype = CKSUMTYPE_HMAC_SHA1_DES3;
|
||||
csum.checksum.length = 20;
|
||||
csum.checksum.data = p + 8;
|
||||
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
ret = krb5_crypto_init(context, key,
|
||||
ETYPE_DES3_CBC_SHA1, &crypto);
|
||||
if (ret == 0)
|
||||
ret = krb5_verify_checksum(context, crypto,
|
||||
KRB5_KU_USAGE_SIGN,
|
||||
tmp, message_buffer->length + 8,
|
||||
&csum);
|
||||
free (tmp);
|
||||
if (ret) {
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
*minor_status = ret;
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
return GSS_S_BAD_MIC;
|
||||
}
|
||||
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
|
||||
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
return GSS_S_COMPLETE | seq_err;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_gsskrb5_verify_mic_internal
|
||||
(OM_uint32 * minor_status,
|
||||
@@ -304,19 +65,11 @@ _gsskrb5_verify_mic_internal
|
||||
case KRB5_ENCTYPE_DES_CBC_CRC :
|
||||
case KRB5_ENCTYPE_DES_CBC_MD4 :
|
||||
case KRB5_ENCTYPE_DES_CBC_MD5 :
|
||||
#ifdef HEIM_WEAK_CRYPTO
|
||||
ret = verify_mic_des (minor_status, ctx, context,
|
||||
message_buffer, token_buffer, qop_state, key,
|
||||
type);
|
||||
#else
|
||||
ret = GSS_S_FAILURE;
|
||||
#endif
|
||||
ret = GSS_S_FAILURE;
|
||||
break;
|
||||
case KRB5_ENCTYPE_DES3_CBC_MD5 :
|
||||
case KRB5_ENCTYPE_DES3_CBC_SHA1 :
|
||||
ret = verify_mic_des3 (minor_status, ctx, context,
|
||||
message_buffer, token_buffer, qop_state, key,
|
||||
type);
|
||||
ret = GSS_S_FAILURE;
|
||||
break;
|
||||
case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
|
||||
case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
|
||||
|
||||
+1
-341
@@ -193,338 +193,6 @@ _gsskrb5_wrap_size_limit (
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HEIM_WEAK_CRYPTO
|
||||
|
||||
static OM_uint32
|
||||
wrap_des
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx ctx,
|
||||
krb5_context context,
|
||||
int conf_req_flag,
|
||||
gss_qop_t qop_req,
|
||||
const gss_buffer_t input_message_buffer,
|
||||
int * conf_state,
|
||||
gss_buffer_t output_message_buffer,
|
||||
krb5_keyblock *key
|
||||
)
|
||||
{
|
||||
u_char *p;
|
||||
EVP_MD_CTX *md5;
|
||||
u_char hash[16];
|
||||
DES_key_schedule schedule;
|
||||
EVP_CIPHER_CTX des_ctx;
|
||||
DES_cblock deskey;
|
||||
DES_cblock zero;
|
||||
size_t i;
|
||||
int32_t seq_number;
|
||||
size_t len, total_len, padlength, datalen;
|
||||
|
||||
if (IS_DCE_STYLE(ctx)) {
|
||||
padlength = 0;
|
||||
datalen = input_message_buffer->length;
|
||||
len = 22 + 8;
|
||||
_gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
total_len += datalen;
|
||||
datalen += 8;
|
||||
} else {
|
||||
padlength = 8 - (input_message_buffer->length % 8);
|
||||
datalen = input_message_buffer->length + padlength + 8;
|
||||
len = datalen + 22;
|
||||
_gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
}
|
||||
|
||||
output_message_buffer->length = total_len;
|
||||
output_message_buffer->value = malloc (total_len);
|
||||
if (output_message_buffer->value == NULL) {
|
||||
output_message_buffer->length = 0;
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
p = _gsskrb5_make_header(output_message_buffer->value,
|
||||
len,
|
||||
"\x02\x01", /* TOK_ID */
|
||||
GSS_KRB5_MECHANISM);
|
||||
|
||||
/* SGN_ALG */
|
||||
memcpy (p, "\x00\x00", 2);
|
||||
p += 2;
|
||||
/* SEAL_ALG */
|
||||
if(conf_req_flag)
|
||||
memcpy (p, "\x00\x00", 2);
|
||||
else
|
||||
memcpy (p, "\xff\xff", 2);
|
||||
p += 2;
|
||||
/* Filler */
|
||||
memcpy (p, "\xff\xff", 2);
|
||||
p += 2;
|
||||
|
||||
/* fill in later */
|
||||
memset (p, 0, 16);
|
||||
p += 16;
|
||||
|
||||
/* confounder + data + pad */
|
||||
krb5_generate_random_block(p, 8);
|
||||
memcpy (p + 8, input_message_buffer->value,
|
||||
input_message_buffer->length);
|
||||
memset (p + 8 + input_message_buffer->length, padlength, padlength);
|
||||
|
||||
/* checksum */
|
||||
md5 = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(md5, EVP_md5(), NULL);
|
||||
EVP_DigestUpdate(md5, p - 24, 8);
|
||||
EVP_DigestUpdate(md5, p, datalen);
|
||||
EVP_DigestFinal_ex(md5, hash, NULL);
|
||||
EVP_MD_CTX_destroy(md5);
|
||||
|
||||
memset (&zero, 0, sizeof(zero));
|
||||
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
|
||||
DES_set_key_unchecked (&deskey, &schedule);
|
||||
DES_cbc_cksum ((void *)hash, (void *)hash, sizeof(hash),
|
||||
&schedule, &zero);
|
||||
memcpy (p - 8, hash, 8);
|
||||
|
||||
/* sequence number */
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
krb5_auth_con_getlocalseqnumber (context,
|
||||
ctx->auth_context,
|
||||
&seq_number);
|
||||
|
||||
p -= 16;
|
||||
p[0] = (seq_number >> 0) & 0xFF;
|
||||
p[1] = (seq_number >> 8) & 0xFF;
|
||||
p[2] = (seq_number >> 16) & 0xFF;
|
||||
p[3] = (seq_number >> 24) & 0xFF;
|
||||
memset (p + 4,
|
||||
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
|
||||
4);
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, key->keyvalue.data, p + 8, 1);
|
||||
EVP_Cipher(&des_ctx, p, p, 8);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
|
||||
krb5_auth_con_setlocalseqnumber (context,
|
||||
ctx->auth_context,
|
||||
++seq_number);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
/* encrypt the data */
|
||||
p += 16;
|
||||
|
||||
if(conf_req_flag) {
|
||||
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
|
||||
|
||||
for (i = 0; i < sizeof(deskey); ++i)
|
||||
deskey[i] ^= 0xf0;
|
||||
|
||||
EVP_CIPHER_CTX_init(&des_ctx);
|
||||
EVP_CipherInit_ex(&des_ctx, EVP_des_cbc(), NULL, deskey, zero, 1);
|
||||
EVP_Cipher(&des_ctx, p, p, datalen);
|
||||
EVP_CIPHER_CTX_cleanup(&des_ctx);
|
||||
}
|
||||
memset (deskey, 0, sizeof(deskey));
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
|
||||
if(conf_state != NULL)
|
||||
*conf_state = conf_req_flag;
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static OM_uint32
|
||||
wrap_des3
|
||||
(OM_uint32 * minor_status,
|
||||
const gsskrb5_ctx ctx,
|
||||
krb5_context context,
|
||||
int conf_req_flag,
|
||||
gss_qop_t qop_req,
|
||||
const gss_buffer_t input_message_buffer,
|
||||
int * conf_state,
|
||||
gss_buffer_t output_message_buffer,
|
||||
krb5_keyblock *key
|
||||
)
|
||||
{
|
||||
u_char *p;
|
||||
u_char seq[8];
|
||||
int32_t seq_number;
|
||||
size_t len, total_len, padlength, datalen;
|
||||
uint32_t ret;
|
||||
krb5_crypto crypto;
|
||||
Checksum cksum;
|
||||
krb5_data encdata;
|
||||
|
||||
if (IS_DCE_STYLE(ctx)) {
|
||||
padlength = 0;
|
||||
datalen = input_message_buffer->length;
|
||||
len = 34 + 8;
|
||||
_gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
total_len += datalen;
|
||||
datalen += 8;
|
||||
} else {
|
||||
padlength = 8 - (input_message_buffer->length % 8);
|
||||
datalen = input_message_buffer->length + padlength + 8;
|
||||
len = datalen + 34;
|
||||
_gsskrb5_encap_length (len, &len, &total_len, GSS_KRB5_MECHANISM);
|
||||
}
|
||||
|
||||
output_message_buffer->length = total_len;
|
||||
output_message_buffer->value = malloc (total_len);
|
||||
if (output_message_buffer->value == NULL) {
|
||||
output_message_buffer->length = 0;
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
p = _gsskrb5_make_header(output_message_buffer->value,
|
||||
len,
|
||||
"\x02\x01", /* TOK_ID */
|
||||
GSS_KRB5_MECHANISM);
|
||||
|
||||
/* SGN_ALG */
|
||||
memcpy (p, "\x04\x00", 2); /* HMAC SHA1 DES3-KD */
|
||||
p += 2;
|
||||
/* SEAL_ALG */
|
||||
if(conf_req_flag)
|
||||
memcpy (p, "\x02\x00", 2); /* DES3-KD */
|
||||
else
|
||||
memcpy (p, "\xff\xff", 2);
|
||||
p += 2;
|
||||
/* Filler */
|
||||
memcpy (p, "\xff\xff", 2);
|
||||
p += 2;
|
||||
|
||||
/* calculate checksum (the above + confounder + data + pad) */
|
||||
|
||||
memcpy (p + 20, p - 8, 8);
|
||||
krb5_generate_random_block(p + 28, 8);
|
||||
memcpy (p + 28 + 8, input_message_buffer->value,
|
||||
input_message_buffer->length);
|
||||
memset (p + 28 + 8 + input_message_buffer->length, padlength, padlength);
|
||||
|
||||
ret = krb5_crypto_init(context, key, 0, &crypto);
|
||||
if (ret) {
|
||||
free (output_message_buffer->value);
|
||||
output_message_buffer->length = 0;
|
||||
output_message_buffer->value = NULL;
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = krb5_create_checksum (context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SIGN,
|
||||
0,
|
||||
p + 20,
|
||||
datalen + 8,
|
||||
&cksum);
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
if (ret) {
|
||||
free (output_message_buffer->value);
|
||||
output_message_buffer->length = 0;
|
||||
output_message_buffer->value = NULL;
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/* zero out SND_SEQ + SGN_CKSUM in case */
|
||||
memset (p, 0, 28);
|
||||
|
||||
memcpy (p + 8, cksum.checksum.data, cksum.checksum.length);
|
||||
free_Checksum (&cksum);
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
|
||||
/* sequence number */
|
||||
krb5_auth_con_getlocalseqnumber (context,
|
||||
ctx->auth_context,
|
||||
&seq_number);
|
||||
|
||||
seq[0] = (seq_number >> 0) & 0xFF;
|
||||
seq[1] = (seq_number >> 8) & 0xFF;
|
||||
seq[2] = (seq_number >> 16) & 0xFF;
|
||||
seq[3] = (seq_number >> 24) & 0xFF;
|
||||
memset (seq + 4,
|
||||
(ctx->more_flags & LOCAL) ? 0 : 0xFF,
|
||||
4);
|
||||
|
||||
|
||||
ret = krb5_crypto_init(context, key, ETYPE_DES3_CBC_NONE,
|
||||
&crypto);
|
||||
if (ret) {
|
||||
free (output_message_buffer->value);
|
||||
output_message_buffer->length = 0;
|
||||
output_message_buffer->value = NULL;
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
{
|
||||
DES_cblock ivec;
|
||||
|
||||
memcpy (&ivec, p + 8, 8);
|
||||
ret = krb5_encrypt_ivec (context,
|
||||
crypto,
|
||||
KRB5_KU_USAGE_SEQ,
|
||||
seq, 8, &encdata,
|
||||
&ivec);
|
||||
}
|
||||
krb5_crypto_destroy (context, crypto);
|
||||
if (ret) {
|
||||
free (output_message_buffer->value);
|
||||
output_message_buffer->length = 0;
|
||||
output_message_buffer->value = NULL;
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
assert (encdata.length == 8);
|
||||
|
||||
memcpy (p, encdata.data, encdata.length);
|
||||
krb5_data_free (&encdata);
|
||||
|
||||
krb5_auth_con_setlocalseqnumber (context,
|
||||
ctx->auth_context,
|
||||
++seq_number);
|
||||
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
|
||||
|
||||
/* encrypt the data */
|
||||
p += 28;
|
||||
|
||||
if(conf_req_flag) {
|
||||
krb5_data tmp;
|
||||
|
||||
ret = krb5_crypto_init(context, key,
|
||||
ETYPE_DES3_CBC_NONE, &crypto);
|
||||
if (ret) {
|
||||
free (output_message_buffer->value);
|
||||
output_message_buffer->length = 0;
|
||||
output_message_buffer->value = NULL;
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
ret = krb5_encrypt(context, crypto, KRB5_KU_USAGE_SEAL,
|
||||
p, datalen, &tmp);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (ret) {
|
||||
free (output_message_buffer->value);
|
||||
output_message_buffer->length = 0;
|
||||
output_message_buffer->value = NULL;
|
||||
*minor_status = ret;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
assert (tmp.length == datalen);
|
||||
|
||||
memcpy (p, tmp.data, datalen);
|
||||
krb5_data_free(&tmp);
|
||||
}
|
||||
if(conf_state != NULL)
|
||||
*conf_state = conf_req_flag;
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32 GSSAPI_CALLCONV
|
||||
_gsskrb5_wrap
|
||||
(OM_uint32 * minor_status,
|
||||
@@ -563,19 +231,11 @@ _gsskrb5_wrap
|
||||
case KRB5_ENCTYPE_DES_CBC_CRC :
|
||||
case KRB5_ENCTYPE_DES_CBC_MD4 :
|
||||
case KRB5_ENCTYPE_DES_CBC_MD5 :
|
||||
#ifdef HEIM_WEAK_CRYPTO
|
||||
ret = wrap_des (minor_status, ctx, context, conf_req_flag,
|
||||
qop_req, input_message_buffer, conf_state,
|
||||
output_message_buffer, key);
|
||||
#else
|
||||
ret = GSS_S_FAILURE;
|
||||
#endif
|
||||
break;
|
||||
case KRB5_ENCTYPE_DES3_CBC_MD5 :
|
||||
case KRB5_ENCTYPE_DES3_CBC_SHA1 :
|
||||
ret = wrap_des3 (minor_status, ctx, context, conf_req_flag,
|
||||
qop_req, input_message_buffer, conf_state,
|
||||
output_message_buffer, key);
|
||||
ret = GSS_S_FAILURE;
|
||||
break;
|
||||
case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5:
|
||||
case KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56:
|
||||
|
||||
@@ -304,9 +304,6 @@ _gss_load_mech(void)
|
||||
if (add_builtin(__gss_spnego_initialize()))
|
||||
_gss_mg_log(1, "Out of memory while adding builtin SPNEGO "
|
||||
"mechanism to the GSS mechanism switch");
|
||||
if (add_builtin(__gss_ntlm_initialize()))
|
||||
_gss_mg_log(1, "Out of memory while adding builtin NTLM "
|
||||
"mechanism to the GSS mechanism switch");
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
fp = fopen(conf ? conf : _PATH_GSS_MECH, "r");
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. 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 "netlogon.h"
|
||||
|
||||
/*
|
||||
* Not implemented: this is needed only by domain controllers.
|
||||
*/
|
||||
|
||||
OM_uint32
|
||||
_netlogon_accept_sec_context
|
||||
(OM_uint32 * minor_status,
|
||||
gss_ctx_id_t * context_handle,
|
||||
gss_const_cred_id_t acceptor_cred_handle,
|
||||
const gss_buffer_t input_token_buffer,
|
||||
const gss_channel_bindings_t input_chan_bindings,
|
||||
gss_name_t * src_name,
|
||||
gss_OID * mech_type,
|
||||
gss_buffer_t output_token,
|
||||
OM_uint32 * ret_flags,
|
||||
OM_uint32 * time_rec,
|
||||
gss_cred_id_t * delegated_cred_handle
|
||||
)
|
||||
{
|
||||
|
||||
output_token->value = NULL;
|
||||
output_token->length = 0;
|
||||
|
||||
*minor_status = 0;
|
||||
|
||||
if (context_handle == NULL)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
if (input_token_buffer == GSS_C_NO_BUFFER)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
if (src_name)
|
||||
*src_name = GSS_C_NO_NAME;
|
||||
if (mech_type)
|
||||
*mech_type = GSS_C_NO_OID;
|
||||
if (ret_flags)
|
||||
*ret_flags = 0;
|
||||
if (time_rec)
|
||||
*time_rec = 0;
|
||||
if (delegated_cred_handle)
|
||||
*delegated_cred_handle = GSS_C_NO_CREDENTIAL;
|
||||
|
||||
if (*context_handle == GSS_C_NO_CONTEXT) {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
} else {
|
||||
*minor_status = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
return GSS_S_UNAVAILABLE;
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2010 Apple Inc. 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 "netlogon.h"
|
||||
#include <gssapi_spi.h>
|
||||
|
||||
OM_uint32
|
||||
_netlogon_acquire_cred(OM_uint32 * min_stat,
|
||||
gss_const_name_t desired_name,
|
||||
OM_uint32 time_req,
|
||||
const gss_OID_set desired_mechs,
|
||||
gss_cred_usage_t cred_usage,
|
||||
gss_cred_id_t * output_cred_handle,
|
||||
gss_OID_set * actual_mechs,
|
||||
OM_uint32 * time_rec)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
gssnetlogon_cred cred;
|
||||
|
||||
/* only initiator support so far */
|
||||
if (cred_usage != GSS_C_INITIATE)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
if (desired_name == GSS_C_NO_NAME)
|
||||
return GSS_S_BAD_NAME;
|
||||
|
||||
cred = (gssnetlogon_cred)calloc(1, sizeof(*cred));
|
||||
if (cred == NULL) {
|
||||
*min_stat = ENOMEM;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
cred->SignatureAlgorithm = NL_SIGN_ALG_HMAC_MD5;
|
||||
cred->SealAlgorithm = NL_SEAL_ALG_RC4;
|
||||
|
||||
ret = _netlogon_duplicate_name(min_stat, desired_name,
|
||||
(gss_name_t *)&cred->Name);
|
||||
if (GSS_ERROR(ret)) {
|
||||
free(cred);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*output_cred_handle = (gss_cred_id_t)cred;
|
||||
if (actual_mechs != NULL)
|
||||
*actual_mechs = GSS_C_NO_OID_SET;
|
||||
if (time_rec != NULL)
|
||||
*time_rec = GSS_C_INDEFINITE;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_netlogon_acquire_cred_ex(gss_status_id_t status,
|
||||
gss_const_name_t desired_name,
|
||||
OM_uint32 flags,
|
||||
OM_uint32 time_req,
|
||||
gss_cred_usage_t cred_usage,
|
||||
gss_auth_identity_t identity,
|
||||
void *ctx,
|
||||
void (*complete)(void *, OM_uint32, gss_status_id_t, gss_cred_id_t, OM_uint32))
|
||||
{
|
||||
return GSS_S_UNAVAILABLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* value contains 16 byte session key
|
||||
*/
|
||||
static OM_uint32
|
||||
_netlogon_set_session_key(OM_uint32 *minor_status,
|
||||
gss_cred_id_t *cred_handle,
|
||||
const gss_buffer_t value)
|
||||
{
|
||||
gssnetlogon_cred cred;
|
||||
|
||||
if (*cred_handle == GSS_C_NO_CREDENTIAL) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
cred = (gssnetlogon_cred)*cred_handle;
|
||||
|
||||
if (value->length != sizeof(cred->SessionKey)) {
|
||||
*minor_status = ERANGE;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(cred->SessionKey, value->value, value->length);
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
/*
|
||||
* value contains 16 bit little endian encoded seal algorithm
|
||||
*/
|
||||
static OM_uint32
|
||||
_netlogon_set_sign_algorithm(OM_uint32 *minor_status,
|
||||
gss_cred_id_t *cred_handle,
|
||||
const gss_buffer_t value)
|
||||
{
|
||||
gssnetlogon_cred cred;
|
||||
uint16_t alg;
|
||||
const uint8_t *p;
|
||||
|
||||
if (*cred_handle == GSS_C_NO_CREDENTIAL) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
cred = (gssnetlogon_cred)*cred_handle;
|
||||
|
||||
if (value->length != 2) {
|
||||
*minor_status = ERANGE;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
p = (const uint8_t *)value->value;
|
||||
alg = (p[0] << 0) | (p[1] << 8);
|
||||
|
||||
if (alg != NL_SIGN_ALG_HMAC_MD5 && alg != NL_SIGN_ALG_SHA256) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
cred->SignatureAlgorithm = alg;
|
||||
if (alg == NL_SIGN_ALG_SHA256)
|
||||
cred->SealAlgorithm = NL_SEAL_ALG_AES128;
|
||||
else
|
||||
cred->SealAlgorithm = NL_SEAL_ALG_RC4;
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_netlogon_set_cred_option
|
||||
(OM_uint32 *minor_status,
|
||||
gss_cred_id_t *cred_handle,
|
||||
const gss_OID desired_object,
|
||||
const gss_buffer_t value)
|
||||
{
|
||||
if (value == GSS_C_NO_BUFFER) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
if (gss_oid_equal(desired_object, GSS_NETLOGON_SET_SESSION_KEY_X))
|
||||
return _netlogon_set_session_key(minor_status, cred_handle, value);
|
||||
else if (gss_oid_equal(desired_object, GSS_NETLOGON_SET_SIGN_ALGORITHM_X))
|
||||
return _netlogon_set_sign_algorithm(minor_status, cred_handle, value);
|
||||
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2010 Apple Inc. 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 "netlogon.h"
|
||||
|
||||
OM_uint32 _netlogon_add_cred (
|
||||
OM_uint32 *minor_status,
|
||||
gss_const_cred_id_t input_cred_handle,
|
||||
gss_const_name_t desired_name,
|
||||
const gss_OID desired_mech,
|
||||
gss_cred_usage_t cred_usage,
|
||||
OM_uint32 initiator_time_req,
|
||||
OM_uint32 acceptor_time_req,
|
||||
gss_cred_id_t *output_cred_handle,
|
||||
gss_OID_set *actual_mechs,
|
||||
OM_uint32 *initiator_time_rec,
|
||||
OM_uint32 *acceptor_time_rec)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
int equal;
|
||||
const gssnetlogon_cred src = (const gssnetlogon_cred)input_cred_handle;
|
||||
gssnetlogon_cred dst;
|
||||
|
||||
if (desired_name != GSS_C_NO_NAME) {
|
||||
if (input_cred_handle != GSS_C_NO_CREDENTIAL) {
|
||||
ret = _netlogon_compare_name(minor_status, desired_name,
|
||||
(gss_name_t)src->Name, &equal);
|
||||
if (GSS_ERROR(ret))
|
||||
return ret;
|
||||
|
||||
if (!equal)
|
||||
return GSS_S_BAD_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
ret = _netlogon_acquire_cred(minor_status,
|
||||
input_cred_handle ? (gss_name_t)src->Name : desired_name,
|
||||
initiator_time_req, GSS_C_NO_OID_SET, cred_usage,
|
||||
output_cred_handle, actual_mechs, initiator_time_rec);
|
||||
if (GSS_ERROR(ret))
|
||||
return ret;
|
||||
|
||||
dst = (gssnetlogon_cred)*output_cred_handle;
|
||||
|
||||
if (src != NULL) {
|
||||
dst->SignatureAlgorithm = src->SignatureAlgorithm;
|
||||
dst->SealAlgorithm = src->SealAlgorithm;
|
||||
|
||||
memcpy(dst->SessionKey, src->SessionKey, sizeof(src->SessionKey));
|
||||
}
|
||||
|
||||
if (acceptor_time_rec != NULL)
|
||||
*acceptor_time_rec = 0;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. 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 "netlogon.h"
|
||||
|
||||
OM_uint32 _netlogon_canonicalize_name (
|
||||
OM_uint32 * minor_status,
|
||||
gss_const_name_t input_name,
|
||||
const gss_OID mech_type,
|
||||
gss_name_t * output_name
|
||||
)
|
||||
{
|
||||
return _netlogon_duplicate_name(minor_status, input_name, output_name);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2010 Apple Inc. 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 "netlogon.h"
|
||||
|
||||
OM_uint32 _netlogon_compare_name
|
||||
(OM_uint32 * minor_status,
|
||||
gss_const_name_t name1,
|
||||
gss_const_name_t name2,
|
||||
int * name_equal
|
||||
)
|
||||
{
|
||||
const gssnetlogon_name n1 = (const gssnetlogon_name)name1;
|
||||
const gssnetlogon_name n2 = (const gssnetlogon_name)name2;
|
||||
|
||||
*name_equal = 0;
|
||||
|
||||
if (n1->NetbiosName.value != NULL && n2->NetbiosName.value != NULL)
|
||||
*name_equal = (strcasecmp((char *)n1->NetbiosName.value,
|
||||
(char *)n2->NetbiosName.value) == 0);
|
||||
|
||||
if (n1->DnsName.value != NULL && n2->DnsName.value != NULL)
|
||||
*name_equal = (strcasecmp((char *)n1->DnsName.value,
|
||||
(char *)n2->DnsName.value) == 0);
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2009 Apple Inc. 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 "netlogon.h"
|
||||
|
||||
OM_uint32 _netlogon_context_time
|
||||
(OM_uint32 * minor_status,
|
||||
gss_const_ctx_id_t context_handle,
|
||||
OM_uint32 * time_rec
|
||||
)
|
||||
{
|
||||
if (time_rec != NULL)
|
||||
*time_rec = GSS_C_INDEFINITE;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
@@ -1,733 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions Copyright (c) 2010 Apple Inc. 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 "netlogon.h"
|
||||
|
||||
static uint8_t zeros[4];
|
||||
|
||||
static void
|
||||
_netlogon_encode_sequence_number(uint64_t SequenceNumber, uint8_t *p,
|
||||
int initiatorFlag)
|
||||
{
|
||||
uint32_t LowPart, HighPart;
|
||||
|
||||
LowPart = (SequenceNumber >> 0 ) & 0xFFFFFFFF;
|
||||
HighPart = (SequenceNumber >> 32) & 0xFFFFFFFF;
|
||||
|
||||
_gss_mg_encode_be_uint32(LowPart, &p[0]);
|
||||
_gss_mg_encode_be_uint32(HighPart, &p[4]);
|
||||
|
||||
if (initiatorFlag)
|
||||
p[4] |= 0x80;
|
||||
}
|
||||
|
||||
static int
|
||||
_netlogon_decode_sequence_number(void *ptr, uint64_t *n,
|
||||
int initiatorFlag)
|
||||
{
|
||||
uint8_t *p = ptr;
|
||||
uint32_t LowPart, HighPart;
|
||||
int gotInitiatorFlag;
|
||||
|
||||
gotInitiatorFlag = (p[4] & 0x80) != 0;
|
||||
if (gotInitiatorFlag != initiatorFlag)
|
||||
return -1;
|
||||
|
||||
p[4] &= 0x7F; /* clear initiator bit */
|
||||
|
||||
_gss_mg_decode_be_uint32(&p[0], &LowPart);
|
||||
_gss_mg_decode_be_uint32(&p[4], &HighPart);
|
||||
|
||||
*n = (LowPart << 0) | ((uint64_t)HighPart << 32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
_netlogon_checksum_length(NL_AUTH_SIGNATURE *sig)
|
||||
{
|
||||
#if 0
|
||||
return (sig->SignatureAlgorithm == NL_SIGN_ALG_SHA256) ? 32 : 8;
|
||||
#else
|
||||
/* Owing to a bug in Windows it always uses the old value */
|
||||
return 8;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
_netlogon_signature_length(uint16_t alg, int conf_req_flag)
|
||||
{
|
||||
return NL_AUTH_SIGNATURE_COMMON_LENGTH +
|
||||
(alg == NL_SIGN_ALG_SHA256 ? 32 : 8) +
|
||||
(conf_req_flag ? 8 : 0);
|
||||
}
|
||||
|
||||
static inline uint8_t *
|
||||
_netlogon_confounder(NL_AUTH_SIGNATURE *sig)
|
||||
{
|
||||
size_t cksumlen = _netlogon_checksum_length(sig);
|
||||
|
||||
return &sig->Checksum[cksumlen];
|
||||
}
|
||||
|
||||
static int
|
||||
_netlogon_encode_NL_AUTH_SIGNATURE(NL_AUTH_SIGNATURE *sig,
|
||||
uint8_t *p, size_t len)
|
||||
{
|
||||
*p++ = (sig->SignatureAlgorithm >> 0) & 0xFF;
|
||||
*p++ = (sig->SignatureAlgorithm >> 8) & 0xFF;
|
||||
*p++ = (sig->SealAlgorithm >> 0) & 0xFF;
|
||||
*p++ = (sig->SealAlgorithm >> 8) & 0xFF;
|
||||
*p++ = (sig->Pad >> 0) & 0xFF;
|
||||
*p++ = (sig->Pad >> 8) & 0xFF;
|
||||
*p++ = (sig->Flags >> 0) & 0xFF;
|
||||
*p++ = (sig->Flags >> 8) & 0xFF;
|
||||
|
||||
if (len > NL_AUTH_SIGNATURE_HEADER_LENGTH) {
|
||||
memcpy(p, sig->SequenceNumber, 8);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
if (len > NL_AUTH_SIGNATURE_COMMON_LENGTH) {
|
||||
size_t cksumlen = _netlogon_checksum_length(sig);
|
||||
|
||||
memcpy(p, sig->Checksum, cksumlen);
|
||||
p += cksumlen;
|
||||
|
||||
/* Confounder, if present, is immediately after checksum */
|
||||
if (sig->SealAlgorithm != NL_SEAL_ALG_NONE) {
|
||||
memcpy(p, &sig->Checksum[cksumlen], 8);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_netlogon_decode_NL_AUTH_SIGNATURE(const uint8_t *ptr,
|
||||
size_t len,
|
||||
NL_AUTH_SIGNATURE *sig)
|
||||
{
|
||||
const uint8_t *p = ptr;
|
||||
size_t cksumlen;
|
||||
|
||||
if (len < NL_AUTH_SIGNATURE_COMMON_LENGTH)
|
||||
return KRB5_BAD_MSIZE;
|
||||
|
||||
sig->SignatureAlgorithm = (p[0] << 0) | (p[1] << 8);
|
||||
sig->SealAlgorithm = (p[2] << 0) | (p[3] << 8);
|
||||
sig->Pad = (p[4] << 0) | (p[5] << 8);
|
||||
sig->Flags = (p[6] << 0) | (p[7] << 8);
|
||||
p += 8;
|
||||
|
||||
memcpy(sig->SequenceNumber, p, 8);
|
||||
p += 8;
|
||||
|
||||
/* Validate signature algorithm is known and matches enctype */
|
||||
switch (sig->SignatureAlgorithm) {
|
||||
case NL_SIGN_ALG_HMAC_MD5:
|
||||
cksumlen = NL_AUTH_SIGNATURE_LENGTH;
|
||||
break;
|
||||
case NL_SIGN_ALG_SHA256:
|
||||
cksumlen = NL_AUTH_SHA2_SIGNATURE_LENGTH;
|
||||
break;
|
||||
default:
|
||||
return EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sig->SealAlgorithm == NL_SEAL_ALG_NONE)
|
||||
cksumlen -= 8; /* confounder is optional if no sealing */
|
||||
|
||||
if (len < cksumlen)
|
||||
return KRB5_BAD_MSIZE;
|
||||
|
||||
/* Copy variable length checksum */
|
||||
cksumlen = _netlogon_checksum_length(sig);
|
||||
memcpy(sig->Checksum, p, cksumlen);
|
||||
p += cksumlen;
|
||||
|
||||
/* Copy confounder in past checksum */
|
||||
if (sig->SealAlgorithm != NL_SEAL_ALG_NONE)
|
||||
memcpy(&sig->Checksum[cksumlen], p, 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_netlogon_derive_rc4_hmac_key(uint8_t key[16],
|
||||
uint8_t *salt,
|
||||
size_t saltLength,
|
||||
EVP_CIPHER_CTX *rc4Key,
|
||||
int enc)
|
||||
{
|
||||
uint8_t tmpData[MD5_DIGEST_LENGTH];
|
||||
uint8_t derivedKey[MD5_DIGEST_LENGTH];
|
||||
unsigned int len = MD5_DIGEST_LENGTH;
|
||||
|
||||
HMAC(EVP_md5(), key, 16, zeros, sizeof(zeros), tmpData, &len);
|
||||
HMAC(EVP_md5(), tmpData, MD5_DIGEST_LENGTH,
|
||||
salt, saltLength, derivedKey, &len);
|
||||
|
||||
assert(len == MD5_DIGEST_LENGTH);
|
||||
|
||||
EVP_CipherInit_ex(rc4Key, EVP_rc4(), NULL, derivedKey, NULL, enc);
|
||||
|
||||
memset(derivedKey, 0, sizeof(derivedKey));
|
||||
}
|
||||
|
||||
static void
|
||||
_netlogon_derive_rc4_seal_key(gssnetlogon_ctx ctx,
|
||||
NL_AUTH_SIGNATURE *sig,
|
||||
EVP_CIPHER_CTX *sealkey,
|
||||
int enc)
|
||||
{
|
||||
uint8_t xorKey[16];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(xorKey); i++) {
|
||||
xorKey[i] = ctx->SessionKey[i] ^ 0xF0;
|
||||
}
|
||||
|
||||
_netlogon_derive_rc4_hmac_key(xorKey,
|
||||
sig->SequenceNumber, sizeof(sig->SequenceNumber), sealkey, enc);
|
||||
|
||||
memset(xorKey, 0, sizeof(xorKey));
|
||||
}
|
||||
|
||||
static void
|
||||
_netlogon_derive_rc4_seq_key(gssnetlogon_ctx ctx,
|
||||
NL_AUTH_SIGNATURE *sig,
|
||||
EVP_CIPHER_CTX *seqkey,
|
||||
int enc)
|
||||
{
|
||||
_netlogon_derive_rc4_hmac_key(ctx->SessionKey,
|
||||
sig->Checksum, sizeof(sig->Checksum), seqkey, enc);
|
||||
}
|
||||
|
||||
static void
|
||||
_netlogon_derive_aes_seal_key(gssnetlogon_ctx ctx,
|
||||
NL_AUTH_SIGNATURE *sig,
|
||||
EVP_CIPHER_CTX *sealkey,
|
||||
int enc)
|
||||
{
|
||||
uint8_t encryptionKey[16];
|
||||
uint8_t ivec[16];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(encryptionKey); i++) {
|
||||
encryptionKey[i] = ctx->SessionKey[i] ^ 0xF0;
|
||||
}
|
||||
|
||||
memcpy(&ivec[0], sig->SequenceNumber, 8);
|
||||
memcpy(&ivec[8], sig->SequenceNumber, 8);
|
||||
|
||||
EVP_CipherInit_ex(sealkey, EVP_aes_128_cfb8(),
|
||||
NULL, encryptionKey, ivec, enc);
|
||||
|
||||
memset(encryptionKey, 0, sizeof(encryptionKey));
|
||||
}
|
||||
|
||||
static void
|
||||
_netlogon_derive_aes_seq_key(gssnetlogon_ctx ctx,
|
||||
NL_AUTH_SIGNATURE *sig,
|
||||
EVP_CIPHER_CTX *seqkey,
|
||||
int enc)
|
||||
{
|
||||
uint8_t ivec[16];
|
||||
|
||||
memcpy(&ivec[0], sig->Checksum, 8);
|
||||
memcpy(&ivec[8], sig->Checksum, 8);
|
||||
|
||||
EVP_CipherInit_ex(seqkey, EVP_aes_128_cfb8(),
|
||||
NULL, ctx->SessionKey, ivec, enc);
|
||||
}
|
||||
|
||||
static void
|
||||
_netlogon_seal(gssnetlogon_ctx ctx,
|
||||
NL_AUTH_SIGNATURE *sig,
|
||||
gss_iov_buffer_desc *iov,
|
||||
int iov_count,
|
||||
int enc)
|
||||
{
|
||||
EVP_CIPHER_CTX sealkey;
|
||||
int i;
|
||||
uint8_t *confounder = _netlogon_confounder(sig);
|
||||
|
||||
EVP_CIPHER_CTX_init(&sealkey);
|
||||
|
||||
if (sig->SealAlgorithm == NL_SEAL_ALG_AES128)
|
||||
_netlogon_derive_aes_seal_key(ctx, sig, &sealkey, enc);
|
||||
else
|
||||
_netlogon_derive_rc4_seal_key(ctx, sig, &sealkey, enc);
|
||||
|
||||
EVP_Cipher(&sealkey, confounder, confounder, 8);
|
||||
|
||||
/*
|
||||
* For RC4, Windows resets the cipherstate after encrypting
|
||||
* the confounder, thus defeating the purpose of the confounder
|
||||
*/
|
||||
if (sig->SealAlgorithm == NL_SEAL_ALG_RC4) {
|
||||
EVP_CipherFinal_ex(&sealkey, NULL, &i);
|
||||
_netlogon_derive_rc4_seal_key(ctx, sig, &sealkey, enc);
|
||||
}
|
||||
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
gss_iov_buffer_t iovp = &iov[i];
|
||||
|
||||
switch (GSS_IOV_BUFFER_TYPE(iovp->type)) {
|
||||
case GSS_IOV_BUFFER_TYPE_DATA:
|
||||
case GSS_IOV_BUFFER_TYPE_PADDING:
|
||||
EVP_Cipher(&sealkey, iovp->buffer.value, iovp->buffer.value,
|
||||
iovp->buffer.length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EVP_CipherFinal_ex(&sealkey, NULL, &i);
|
||||
EVP_CIPHER_CTX_cleanup(&sealkey);
|
||||
}
|
||||
|
||||
static void
|
||||
_netlogon_seq(gssnetlogon_ctx ctx,
|
||||
NL_AUTH_SIGNATURE *sig,
|
||||
int enc)
|
||||
{
|
||||
EVP_CIPHER_CTX seqkey;
|
||||
|
||||
EVP_CIPHER_CTX_init(&seqkey);
|
||||
|
||||
if (sig->SignatureAlgorithm == NL_SIGN_ALG_SHA256)
|
||||
_netlogon_derive_aes_seq_key(ctx, sig, &seqkey, enc);
|
||||
else
|
||||
_netlogon_derive_rc4_seq_key(ctx, sig, &seqkey, enc);
|
||||
|
||||
EVP_Cipher(&seqkey, sig->SequenceNumber, sig->SequenceNumber, 8);
|
||||
|
||||
EVP_CIPHER_CTX_cleanup(&seqkey);
|
||||
}
|
||||
|
||||
static void
|
||||
_netlogon_digest_md5(gssnetlogon_ctx ctx,
|
||||
NL_AUTH_SIGNATURE *sig,
|
||||
gss_iov_buffer_desc *iov,
|
||||
int iov_count,
|
||||
uint8_t *md)
|
||||
{
|
||||
EVP_MD_CTX *md5;
|
||||
uint8_t header[NL_AUTH_SIGNATURE_HEADER_LENGTH];
|
||||
uint8_t digest[MD5_DIGEST_LENGTH];
|
||||
unsigned int md_len = MD5_DIGEST_LENGTH;
|
||||
int i;
|
||||
|
||||
_netlogon_encode_NL_AUTH_SIGNATURE(sig, header, sizeof(header));
|
||||
|
||||
md5 = EVP_MD_CTX_create();
|
||||
EVP_DigestInit_ex(md5, EVP_md5(), NULL);
|
||||
EVP_DigestUpdate(md5, zeros, sizeof(zeros));
|
||||
EVP_DigestUpdate(md5, header, sizeof(header));
|
||||
|
||||
if (sig->SealAlgorithm != NL_SEAL_ALG_NONE) {
|
||||
EVP_DigestUpdate(md5, sig->Confounder, sizeof(sig->Confounder));
|
||||
}
|
||||
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
gss_iov_buffer_t iovp = &iov[i];
|
||||
|
||||
switch (GSS_IOV_BUFFER_TYPE(iovp->type)) {
|
||||
case GSS_IOV_BUFFER_TYPE_DATA:
|
||||
case GSS_IOV_BUFFER_TYPE_PADDING:
|
||||
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
|
||||
EVP_DigestUpdate(md5, iovp->buffer.value, iovp->buffer.length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
EVP_DigestFinal_ex(md5, digest, NULL);
|
||||
EVP_MD_CTX_destroy(md5);
|
||||
|
||||
HMAC(EVP_md5(), ctx->SessionKey, sizeof(ctx->SessionKey),
|
||||
digest, sizeof(digest), digest, &md_len);
|
||||
memcpy(md, digest, 8);
|
||||
}
|
||||
|
||||
static void
|
||||
_netlogon_digest_sha256(gssnetlogon_ctx ctx,
|
||||
NL_AUTH_SIGNATURE *sig,
|
||||
gss_iov_buffer_desc *iov,
|
||||
int iov_count,
|
||||
uint8_t *md)
|
||||
{
|
||||
HMAC_CTX hmac;
|
||||
uint8_t header[NL_AUTH_SIGNATURE_HEADER_LENGTH];
|
||||
uint8_t digest[SHA256_DIGEST_LENGTH];
|
||||
unsigned int md_len = SHA256_DIGEST_LENGTH;
|
||||
int i;
|
||||
|
||||
/* Encode first 8 bytes of signature into header */
|
||||
_netlogon_encode_NL_AUTH_SIGNATURE(sig, header, sizeof(header));
|
||||
|
||||
HMAC_CTX_init(&hmac);
|
||||
HMAC_Init_ex(&hmac, ctx->SessionKey, sizeof(ctx->SessionKey),
|
||||
EVP_sha256(), NULL);
|
||||
HMAC_Update(&hmac, header, sizeof(header));
|
||||
|
||||
if (sig->SealAlgorithm != NL_SEAL_ALG_NONE) {
|
||||
/*
|
||||
* If the checksum length bug is ever fixed, then be sure to
|
||||
* update this code to point to &sig->Checksum[32] as that is
|
||||
* where the confounder is supposed to be.
|
||||
*/
|
||||
HMAC_Update(&hmac, sig->Confounder, 8);
|
||||
}
|
||||
|
||||
for (i = 0; i < iov_count; i++) {
|
||||
gss_iov_buffer_t iovp = &iov[i];
|
||||
|
||||
switch (GSS_IOV_BUFFER_TYPE(iovp->type)) {
|
||||
case GSS_IOV_BUFFER_TYPE_DATA:
|
||||
case GSS_IOV_BUFFER_TYPE_PADDING:
|
||||
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
|
||||
HMAC_Update(&hmac, iovp->buffer.value, iovp->buffer.length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HMAC_Final(&hmac, digest, &md_len);
|
||||
HMAC_CTX_cleanup(&hmac);
|
||||
memcpy(md, digest, 8);
|
||||
}
|
||||
|
||||
static void
|
||||
_netlogon_digest(gssnetlogon_ctx ctx,
|
||||
NL_AUTH_SIGNATURE *sig,
|
||||
gss_iov_buffer_desc *iov,
|
||||
int iov_count,
|
||||
uint8_t *md)
|
||||
{
|
||||
if (sig->SignatureAlgorithm == NL_SIGN_ALG_SHA256)
|
||||
_netlogon_digest_sha256(ctx, sig, iov, iov_count, md);
|
||||
else
|
||||
_netlogon_digest_md5(ctx, sig, iov, iov_count, md);
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_netlogon_wrap_iov(OM_uint32 * minor_status,
|
||||
gss_ctx_id_t context_handle,
|
||||
int conf_req_flag,
|
||||
gss_qop_t qop_req,
|
||||
int *conf_state,
|
||||
gss_iov_buffer_desc *iov,
|
||||
int iov_count)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
gss_iov_buffer_t header;
|
||||
NL_AUTH_SIGNATURE_U sigbuf = { { 0 } };
|
||||
NL_AUTH_SIGNATURE *sig = NL_AUTH_SIGNATURE_P(&sigbuf);
|
||||
gssnetlogon_ctx ctx = (gssnetlogon_ctx)context_handle;
|
||||
size_t size;
|
||||
uint8_t *seqdata;
|
||||
|
||||
if (ctx->State != NL_AUTH_ESTABLISHED) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
header = _gss_mg_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
|
||||
if (header == NULL) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
size = _netlogon_signature_length(ctx->SignatureAlgorithm, conf_req_flag);
|
||||
|
||||
if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_FLAG_ALLOCATE) {
|
||||
ret = _gss_mg_allocate_buffer(minor_status, header, size);
|
||||
if (GSS_ERROR(ret))
|
||||
return ret;
|
||||
} else if (header->buffer.length < size) {
|
||||
*minor_status = KRB5_BAD_MSIZE;
|
||||
return GSS_S_FAILURE;
|
||||
} else {
|
||||
header->buffer.length = size;
|
||||
}
|
||||
|
||||
memset(header->buffer.value, 0, header->buffer.length);
|
||||
|
||||
sig->SignatureAlgorithm = ctx->SignatureAlgorithm;
|
||||
sig->SealAlgorithm = conf_req_flag ? ctx->SealAlgorithm : NL_SEAL_ALG_NONE;
|
||||
|
||||
if (conf_req_flag)
|
||||
krb5_generate_random_block(_netlogon_confounder(sig), 8);
|
||||
|
||||
sig->Pad = 0xFFFF; /* [MS-NRPC] 3.3.4.2.1.3 */
|
||||
sig->Flags = 0; /* [MS-NRPC] 3.3.4.2.1.4 */
|
||||
HEIMDAL_MUTEX_lock(&ctx->Mutex);
|
||||
_netlogon_encode_sequence_number(ctx->SequenceNumber, sig->SequenceNumber,
|
||||
ctx->LocallyInitiated);
|
||||
ctx->SequenceNumber++;
|
||||
HEIMDAL_MUTEX_unlock(&ctx->Mutex);
|
||||
|
||||
/* [MS-NRPC] 3.3.4.2.1.7: sign header, optional confounder and data */
|
||||
_netlogon_digest(ctx, sig, iov, iov_count, sig->Checksum);
|
||||
|
||||
/* [MS-NRPC] 3.3.4.2.1.8: optionally encrypt confounder and data */
|
||||
if (conf_req_flag)
|
||||
_netlogon_seal(ctx, sig, iov, iov_count, 1);
|
||||
|
||||
/* [MS-NRPC] 3.3.4.2.1.9: encrypt sequence number */
|
||||
_netlogon_seq(ctx, sig, 1);
|
||||
|
||||
_netlogon_encode_NL_AUTH_SIGNATURE(sig, header->buffer.value,
|
||||
header->buffer.length);
|
||||
|
||||
if (conf_state != NULL)
|
||||
*conf_state = conf_req_flag;
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_netlogon_unwrap_iov(OM_uint32 *minor_status,
|
||||
gss_ctx_id_t context_handle,
|
||||
int *conf_state,
|
||||
gss_qop_t *qop_state,
|
||||
gss_iov_buffer_desc *iov,
|
||||
int iov_count)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
gss_iov_buffer_t header;
|
||||
NL_AUTH_SIGNATURE_U sigbuf;
|
||||
NL_AUTH_SIGNATURE *sig = NL_AUTH_SIGNATURE_P(&sigbuf);
|
||||
gssnetlogon_ctx ctx = (gssnetlogon_ctx)context_handle;
|
||||
uint8_t checksum[SHA256_DIGEST_LENGTH];
|
||||
uint64_t SequenceNumber;
|
||||
|
||||
if (ctx->State != NL_AUTH_ESTABLISHED) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
header = _gss_mg_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
|
||||
if (header == NULL) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
ret = _netlogon_decode_NL_AUTH_SIGNATURE(header->buffer.value,
|
||||
header->buffer.length,
|
||||
sig);
|
||||
if (ret != 0) {
|
||||
*minor_status = ret;
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
}
|
||||
|
||||
/* [MS-NRPC] 3.3.4.2.2.1: verify signature algorithm selection */
|
||||
if (sig->SignatureAlgorithm != ctx->SignatureAlgorithm)
|
||||
return GSS_S_BAD_SIG;
|
||||
|
||||
/* [MS-NRPC] 3.3.4.2.2.2: verify encryption algorithm selection */
|
||||
if (sig->SealAlgorithm != NL_SEAL_ALG_NONE &&
|
||||
sig->SealAlgorithm != ctx->SealAlgorithm)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
/* [MS-NRPC] 3.3.4.2.2.3: verify Pad bytes */
|
||||
if (sig->Pad != 0xFFFF)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
/* [MS-NRPC] 3.3.4.2.2.5: decrypt sequence number */
|
||||
_netlogon_seq(ctx, sig, 0);
|
||||
|
||||
/* [MS-NRPC] 3.3.4.2.2.6: decode sequence number */
|
||||
if (_netlogon_decode_sequence_number(sig->SequenceNumber, &SequenceNumber,
|
||||
!ctx->LocallyInitiated) != 0)
|
||||
return GSS_S_UNSEQ_TOKEN;
|
||||
|
||||
/* [MS-NRPC] 3.3.4.2.2.9: decrypt confounder and data */
|
||||
if (sig->SealAlgorithm != NL_SEAL_ALG_NONE)
|
||||
_netlogon_seal(ctx, sig, iov, iov_count, 0);
|
||||
|
||||
/* [MS-NRPC] 3.3.4.2.2.10: verify signature */
|
||||
_netlogon_digest(ctx, sig, iov, iov_count, checksum);
|
||||
if (ct_memcmp(sig->Checksum, checksum, _netlogon_checksum_length(sig)) != 0)
|
||||
return GSS_S_BAD_SIG;
|
||||
|
||||
HEIMDAL_MUTEX_lock(&ctx->Mutex);
|
||||
if (SequenceNumber != ctx->SequenceNumber) {
|
||||
/* [MS-NRPC] 3.3.4.2.2.7: check sequence number */
|
||||
ret = GSS_S_UNSEQ_TOKEN;
|
||||
} else {
|
||||
/* [MS-NRPC] 3.3.4.2.2.8: increment sequence number */
|
||||
ctx->SequenceNumber++;
|
||||
ret = GSS_S_COMPLETE;
|
||||
}
|
||||
HEIMDAL_MUTEX_unlock(&ctx->Mutex);
|
||||
|
||||
if (conf_state != NULL)
|
||||
*conf_state = (sig->SealAlgorithm != NL_SEAL_ALG_NONE);
|
||||
if (qop_state != NULL)
|
||||
*qop_state = GSS_C_QOP_DEFAULT;
|
||||
|
||||
*minor_status = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_netlogon_wrap_iov_length(OM_uint32 * minor_status,
|
||||
gss_ctx_id_t context_handle,
|
||||
int conf_req_flag,
|
||||
gss_qop_t qop_req,
|
||||
int *conf_state,
|
||||
gss_iov_buffer_desc *iov,
|
||||
int iov_count)
|
||||
{
|
||||
OM_uint32 ret;
|
||||
gss_iov_buffer_t iovp;
|
||||
gssnetlogon_ctx ctx = (gssnetlogon_ctx)context_handle;
|
||||
size_t len;
|
||||
|
||||
iovp = _gss_mg_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
|
||||
if (iovp == NULL) {
|
||||
*minor_status = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
len = NL_AUTH_SIGNATURE_COMMON_LENGTH;
|
||||
if (ctx->SignatureAlgorithm == NL_SIGN_ALG_SHA256)
|
||||
len += 32; /* SHA2 checksum size */
|
||||
else
|
||||
len += 8; /* HMAC checksum size */
|
||||
if (conf_req_flag)
|
||||
len += 8; /* counfounder */
|
||||
|
||||
iovp->buffer.length = len;
|
||||
|
||||
iovp = _gss_mg_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
|
||||
if (iovp != NULL)
|
||||
iovp->buffer.length = 0;
|
||||
|
||||
iovp = _gss_mg_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
|
||||
if (iovp != NULL)
|
||||
iovp->buffer.length = 0;
|
||||
|
||||
if (conf_state != NULL)
|
||||
*conf_state = conf_req_flag;
|
||||
|
||||
*minor_status = 0;
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32 _netlogon_get_mic
|
||||
(OM_uint32 * minor_status,
|
||||
gss_const_ctx_id_t context_handle,
|
||||
gss_qop_t qop_req,
|
||||
const gss_buffer_t message_buffer,
|
||||
gss_buffer_t message_token
|
||||
)
|
||||
{
|
||||
gss_iov_buffer_desc iov[2];
|
||||
OM_uint32 ret;
|
||||
|
||||
iov[0].type = GSS_IOV_BUFFER_TYPE_DATA;
|
||||
iov[0].buffer = *message_buffer;
|
||||
iov[1].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE;
|
||||
iov[1].buffer.length = 0;
|
||||
iov[1].buffer.value = NULL;
|
||||
|
||||
ret = _netlogon_wrap_iov(minor_status, context_handle, 0,
|
||||
qop_req, NULL, iov, 2);
|
||||
if (ret == GSS_S_COMPLETE)
|
||||
*message_token = iov[1].buffer;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_netlogon_verify_mic
|
||||
(OM_uint32 * minor_status,
|
||||
gss_const_ctx_id_t context_handle,
|
||||
const gss_buffer_t message_buffer,
|
||||
const gss_buffer_t token_buffer,
|
||||
gss_qop_t * qop_state
|
||||
)
|
||||
{
|
||||
gss_iov_buffer_desc iov[2];
|
||||
|
||||
iov[0].type = GSS_IOV_BUFFER_TYPE_DATA;
|
||||
iov[0].buffer = *message_buffer;
|
||||
iov[1].type = GSS_IOV_BUFFER_TYPE_HEADER;
|
||||
iov[1].buffer = *token_buffer;
|
||||
|
||||
return _netlogon_unwrap_iov(minor_status, context_handle,
|
||||
NULL, qop_state, iov, 2);
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
_netlogon_wrap_size_limit (
|
||||
OM_uint32 * minor_status,
|
||||
gss_const_ctx_id_t context_handle,
|
||||
int conf_req_flag,
|
||||
gss_qop_t qop_req,
|
||||
OM_uint32 req_output_size,
|
||||
OM_uint32 *max_input_size
|
||||
)
|
||||
{
|
||||
gss_iov_buffer_desc iov[1];
|
||||
OM_uint32 ret;
|
||||
|
||||
iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
|
||||
iov[0].buffer.length = 0;
|
||||
|
||||
ret = _netlogon_wrap_iov_length(minor_status, context_handle,
|
||||
conf_req_flag, qop_req, NULL,
|
||||
iov, sizeof(iov)/sizeof(iov[0]));
|
||||
if (GSS_ERROR(ret))
|
||||
return ret;
|
||||
|
||||
if (req_output_size < iov[0].buffer.length)
|
||||
*max_input_size = 0;
|
||||
else
|
||||
*max_input_size = req_output_size - iov[0].buffer.length;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user