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:
Nicolas Williams
2025-10-16 13:06:15 -05:00
parent b857bde4fb
commit cbe156d927
294 changed files with 9592 additions and 29048 deletions
+3 -1
View File
@@ -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
View File
@@ -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;
}
+1
View File
@@ -55,6 +55,7 @@
#include "crypto-headers.h"
#include <krb5.h>
#include <krb5_locl.h>
#include <kadm5/admin.h>
#include <kadm5/kadm5_err.h>
-4
View File
@@ -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 \
-125
View File
@@ -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
-18
View File
@@ -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)
-35
View File
@@ -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
-147
View File
@@ -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
-303
View File
@@ -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;
}
-94
View File
@@ -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
-213
View File
@@ -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");
}
-1
View File
@@ -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)
+1 -1
View File
@@ -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
+25
View File
@@ -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
View File
@@ -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
View File
@@ -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*
-16
View File
@@ -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"
-4
View File
@@ -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
+5
View File
@@ -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__ */
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+12
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+14
View 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
View File
@@ -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,
-289
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+14
View File
@@ -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)
+14
View File
@@ -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
View File
@@ -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) {
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
-31
View File
@@ -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
View File
@@ -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;
}
+4
View File
@@ -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
View File
@@ -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);
+1
View File
@@ -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
View File
@@ -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:
-16
View File
@@ -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)
-14
View File
@@ -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;
}
-280
View File
@@ -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."
}
-36
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
-82
View File
@@ -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;
}
-3
View File
@@ -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>
-7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+2
View File
@@ -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
};
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+8
View File
@@ -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)
{
+6
View File
@@ -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)
{
+6
View File
@@ -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)
{
+7
View File
@@ -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)
{
+1
View File
@@ -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
View File
@@ -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");
+1
View File
@@ -77,6 +77,7 @@ EXPORTS
TicketFlags,
TransitedEncoding,
TypedData,
TYPED-DATA,
KrbFastResponse,
KrbFastFinished,
KrbFastReq,
+6
View File
@@ -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
View File
@@ -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
+9 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
-- &paramPresence ParamOptions DEFAULT absent,
-- &smimeCaps SMIME-CAPS OPTIONAL
} -- WITH SYNTAX {
-- IDENTIFIER &id
-- [PARAMS [TYPE &Params] ARE &paramPresence]
-- [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
View File
@@ -1,6 +1,7 @@
--preserve-binary=Name
--preserve-binary=TBSCertificate
--preserve-binary=TBSCRLCertList
--preserve-binary=SubjectPublicKeyInfo
--sequence=AttributeValues
--sequence=CRLDistributionPoints
--sequence=Extensions
+1
View File
@@ -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
View File
@@ -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;
+45 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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
-41
View File
@@ -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_ */
-1
View File
@@ -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);
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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:
+2 -249
View File
@@ -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
View File
@@ -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:
-3
View File
@@ -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");
-89
View File
@@ -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;
}
-186
View File
@@ -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;
}
-89
View File
@@ -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;
}
-46
View File
@@ -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);
}
-61
View File
@@ -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;
}
-47
View File
@@ -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;
}
-733
View File
@@ -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