wmi-1.3.16 from opsview.com
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
This is a copy of the standard copyright notice on most files in the
|
||||
heimdal tree. This license is confidered to be GPL compatible by the
|
||||
Free Software Foundation (see http://www.fsf.org/licensing/licenses/index_html#GPLCompatibleLicenses)
|
||||
|
||||
Note that the list of copyright holders varies between the individial
|
||||
files. Also note that this Samba4 MODIFIED VERSION may depend on GPL'ed
|
||||
libraries.
|
||||
|
||||
Many thanks to the Heimdal developers for their support and
|
||||
cooperation in the use of the heimdal code in Samba.
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan and others.
|
||||
* (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.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
This directory contains a copy of portions of a project known as
|
||||
'lorikeet-heimdal', a branch of the Heimdal Kerberos distribution.
|
||||
|
||||
The purpose of these files is to provide kerberos support to Samba4 in
|
||||
a predicatable manner, without reliance on the system kerberos
|
||||
libraries.
|
||||
@@ -0,0 +1,25 @@
|
||||
dnl $Id: check-var.m4,v 1.12 2005/06/16 18:59:10 lha Exp $
|
||||
dnl
|
||||
dnl rk_CHECK_VAR(variable, includes)
|
||||
AC_DEFUN([rk_CHECK_VAR], [
|
||||
AC_MSG_CHECKING(for $1)
|
||||
AC_CACHE_VAL(ac_cv_var_$1, [
|
||||
m4_ifval([$2],[
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[$2
|
||||
void * foo(void) { return &$1; }]],[[foo()]])],
|
||||
[ac_cv_var_$1=yes],[ac_cv_var_$1=no])])
|
||||
if test "$ac_cv_var_$1" != yes ; then
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern int $1;
|
||||
int foo(void) { return $1; }]],[[foo()]])],
|
||||
[ac_cv_var_$1=yes],[ac_cv_var_$1=no])
|
||||
fi
|
||||
])
|
||||
ac_foo=`eval echo \\$ac_cv_var_$1`
|
||||
AC_MSG_RESULT($ac_foo)
|
||||
if test "$ac_foo" = yes; then
|
||||
AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_[]$1), 1,
|
||||
[Define if you have the `]$1[' variable.])
|
||||
m4_ifval([$2], AC_CHECK_DECLS([$1],[],[],[$2]))
|
||||
fi
|
||||
])
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
dnl $Id: find-func-no-libs.m4,v 1.6 2004/02/12 14:20:45 lha Exp $
|
||||
dnl
|
||||
dnl
|
||||
dnl Look for function in any of the specified libraries
|
||||
dnl
|
||||
|
||||
dnl AC_FIND_FUNC_NO_LIBS(func, libraries, includes, arguments, extra libs, extra args)
|
||||
AC_DEFUN([AC_FIND_FUNC_NO_LIBS], [
|
||||
AC_FIND_FUNC_NO_LIBS2([$1], ["" $2], [$3], [$4], [$5], [$6])])
|
||||
@@ -0,0 +1,63 @@
|
||||
dnl $Id: find-func-no-libs2.m4,v 1.9 2004/08/26 12:35:42 joda Exp $
|
||||
dnl
|
||||
dnl
|
||||
dnl Look for function in any of the specified libraries
|
||||
dnl
|
||||
|
||||
dnl AC_FIND_FUNC_NO_LIBS2(func, libraries, includes, arguments, extra libs, extra args)
|
||||
AC_DEFUN([AC_FIND_FUNC_NO_LIBS2], [
|
||||
|
||||
AC_MSG_CHECKING([for $1])
|
||||
AC_CACHE_VAL(ac_cv_funclib_$1,
|
||||
[
|
||||
if eval "test \"\$ac_cv_func_$1\" != yes" ; then
|
||||
ac_save_LIBS="$LIBS"
|
||||
for ac_lib in $2; do
|
||||
case "$ac_lib" in
|
||||
"") ;;
|
||||
yes) ac_lib="" ;;
|
||||
no) continue ;;
|
||||
-l*) ;;
|
||||
*) ac_lib="-l$ac_lib" ;;
|
||||
esac
|
||||
LIBS="$6 $ac_lib $5 $ac_save_LIBS"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[$3]],[[$1($4)]])],[eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break])
|
||||
done
|
||||
eval "ac_cv_funclib_$1=\${ac_cv_funclib_$1-no}"
|
||||
LIBS="$ac_save_LIBS"
|
||||
fi
|
||||
])
|
||||
|
||||
eval "ac_res=\$ac_cv_funclib_$1"
|
||||
|
||||
if false; then
|
||||
AC_CHECK_FUNCS($1)
|
||||
dnl AC_CHECK_LIBS($2, foo)
|
||||
fi
|
||||
# $1
|
||||
eval "ac_tr_func=HAVE_[]upcase($1)"
|
||||
eval "ac_tr_lib=HAVE_LIB[]upcase($ac_res | sed -e 's/-l//')"
|
||||
eval "LIB_$1=$ac_res"
|
||||
|
||||
case "$ac_res" in
|
||||
yes)
|
||||
eval "ac_cv_func_$1=yes"
|
||||
eval "LIB_$1="
|
||||
AC_DEFINE_UNQUOTED($ac_tr_func)
|
||||
AC_MSG_RESULT([yes])
|
||||
;;
|
||||
no)
|
||||
eval "ac_cv_func_$1=no"
|
||||
eval "LIB_$1="
|
||||
AC_MSG_RESULT([no])
|
||||
;;
|
||||
*)
|
||||
eval "ac_cv_func_$1=yes"
|
||||
eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
|
||||
AC_DEFINE_UNQUOTED($ac_tr_func)
|
||||
AC_DEFINE_UNQUOTED($ac_tr_lib)
|
||||
AC_MSG_RESULT([yes, in $ac_res])
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(LIB_$1)
|
||||
])
|
||||
@@ -0,0 +1,9 @@
|
||||
dnl $Id: find-func.m4,v 1.2 2004/02/12 14:20:47 lha Exp $
|
||||
dnl
|
||||
dnl AC_FIND_FUNC(func, libraries, includes, arguments)
|
||||
AC_DEFUN([AC_FIND_FUNC], [
|
||||
AC_FIND_FUNC_NO_LIBS([$1], [$2], [$3], [$4])
|
||||
if test -n "$LIB_$1"; then
|
||||
LIBS="$LIB_$1 $LIBS"
|
||||
fi
|
||||
])
|
||||
@@ -0,0 +1,109 @@
|
||||
dnl stuff used by DNS resolv code in roken
|
||||
dnl
|
||||
dnl $Id: resolv.m4,v 1.1 2005/09/02 10:17:38 lha Exp $
|
||||
dnl
|
||||
|
||||
AC_DEFUN([rk_RESOLV],[
|
||||
|
||||
AC_CHECK_HEADERS([arpa/nameser.h])
|
||||
|
||||
AC_CHECK_HEADERS(resolv.h, , , [AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
AC_FIND_FUNC(res_search, resolv,
|
||||
[
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_RESOLV_H
|
||||
#include <resolv.h>
|
||||
#endif
|
||||
],
|
||||
[0,0,0,0,0])
|
||||
|
||||
AC_FIND_FUNC(res_nsearch, resolv,
|
||||
[
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_RESOLV_H
|
||||
#include <resolv.h>
|
||||
#endif
|
||||
],
|
||||
[0,0,0,0,0,0])
|
||||
|
||||
AC_FIND_FUNC(res_ndestroy, resolv,
|
||||
[
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_RESOLV_H
|
||||
#include <resolv.h>
|
||||
#endif
|
||||
],
|
||||
[0])
|
||||
|
||||
AC_FIND_FUNC(dn_expand, resolv,
|
||||
[
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_RESOLV_H
|
||||
#include <resolv.h>
|
||||
#endif
|
||||
],
|
||||
[0,0,0,0,0])
|
||||
|
||||
rk_CHECK_VAR(_res,
|
||||
[#include <stdio.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
#include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_RESOLV_H
|
||||
#include <resolv.h>
|
||||
#endif])
|
||||
|
||||
])
|
||||
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "kdc_locl.h"
|
||||
|
||||
RCSID("$Id: 524.c,v 1.40 2006/10/06 17:06:30 lha Exp $");
|
||||
|
||||
#include <krb5-v4compat.h>
|
||||
|
||||
/*
|
||||
* fetch the server from `t', returning the name in malloced memory in
|
||||
* `spn' and the entry itself in `server'
|
||||
*/
|
||||
|
||||
static krb5_error_code
|
||||
fetch_server (krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
const Ticket *t,
|
||||
char **spn,
|
||||
hdb_entry_ex **server,
|
||||
const char *from)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_principal sprinc;
|
||||
|
||||
ret = _krb5_principalname2krb5_principal(context, &sprinc,
|
||||
t->sname, t->realm);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0, "_krb5_principalname2krb5_principal: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
return ret;
|
||||
}
|
||||
ret = krb5_unparse_name(context, sprinc, spn);
|
||||
if (ret) {
|
||||
krb5_free_principal(context, sprinc);
|
||||
kdc_log(context, config, 0, "krb5_unparse_name: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
return ret;
|
||||
}
|
||||
ret = _kdc_db_fetch(context, config, sprinc, HDB_F_GET_SERVER,
|
||||
NULL, server);
|
||||
krb5_free_principal(context, sprinc);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0,
|
||||
"Request to convert ticket from %s for unknown principal %s: %s",
|
||||
from, *spn, krb5_get_err_text(context, ret));
|
||||
if (ret == HDB_ERR_NOENTRY)
|
||||
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
log_524 (krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
const EncTicketPart *et,
|
||||
const char *from,
|
||||
const char *spn)
|
||||
{
|
||||
krb5_principal client;
|
||||
char *cpn;
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = _krb5_principalname2krb5_principal(context, &client,
|
||||
et->cname, et->crealm);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0, "_krb5_principalname2krb5_principal: %s",
|
||||
krb5_get_err_text (context, ret));
|
||||
return ret;
|
||||
}
|
||||
ret = krb5_unparse_name(context, client, &cpn);
|
||||
if (ret) {
|
||||
krb5_free_principal(context, client);
|
||||
kdc_log(context, config, 0, "krb5_unparse_name: %s",
|
||||
krb5_get_err_text (context, ret));
|
||||
return ret;
|
||||
}
|
||||
kdc_log(context, config, 1, "524-REQ %s from %s for %s", cpn, from, spn);
|
||||
free(cpn);
|
||||
krb5_free_principal(context, client);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
verify_flags (krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
const EncTicketPart *et,
|
||||
const char *spn)
|
||||
{
|
||||
if(et->endtime < kdc_time){
|
||||
kdc_log(context, config, 0, "Ticket expired (%s)", spn);
|
||||
return KRB5KRB_AP_ERR_TKT_EXPIRED;
|
||||
}
|
||||
if(et->flags.invalid){
|
||||
kdc_log(context, config, 0, "Ticket not valid (%s)", spn);
|
||||
return KRB5KRB_AP_ERR_TKT_NYV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* set the `et->caddr' to the most appropriate address to use, where
|
||||
* `addr' is the address the request was received from.
|
||||
*/
|
||||
|
||||
static krb5_error_code
|
||||
set_address (krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
EncTicketPart *et,
|
||||
struct sockaddr *addr,
|
||||
const char *from)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_address *v4_addr;
|
||||
|
||||
v4_addr = malloc (sizeof(*v4_addr));
|
||||
if (v4_addr == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
ret = krb5_sockaddr2address(context, addr, v4_addr);
|
||||
if(ret) {
|
||||
free (v4_addr);
|
||||
kdc_log(context, config, 0, "Failed to convert address (%s)", from);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (et->caddr && !krb5_address_search (context, v4_addr, et->caddr)) {
|
||||
kdc_log(context, config, 0, "Incorrect network address (%s)", from);
|
||||
krb5_free_address(context, v4_addr);
|
||||
free (v4_addr);
|
||||
return KRB5KRB_AP_ERR_BADADDR;
|
||||
}
|
||||
if(v4_addr->addr_type == KRB5_ADDRESS_INET) {
|
||||
/* we need to collapse the addresses in the ticket to a
|
||||
single address; best guess is to use the address the
|
||||
connection came from */
|
||||
|
||||
if (et->caddr != NULL) {
|
||||
free_HostAddresses(et->caddr);
|
||||
} else {
|
||||
et->caddr = malloc (sizeof (*et->caddr));
|
||||
if (et->caddr == NULL) {
|
||||
krb5_free_address(context, v4_addr);
|
||||
free(v4_addr);
|
||||
return ENOMEM;
|
||||
}
|
||||
}
|
||||
et->caddr->val = v4_addr;
|
||||
et->caddr->len = 1;
|
||||
} else {
|
||||
krb5_free_address(context, v4_addr);
|
||||
free(v4_addr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static krb5_error_code
|
||||
encrypt_v4_ticket(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
void *buf,
|
||||
size_t len,
|
||||
krb5_keyblock *skey,
|
||||
EncryptedData *reply)
|
||||
{
|
||||
krb5_crypto crypto;
|
||||
krb5_error_code ret;
|
||||
ret = krb5_crypto_init(context, skey, ETYPE_DES_PCBC_NONE, &crypto);
|
||||
if (ret) {
|
||||
free(buf);
|
||||
kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = krb5_encrypt_EncryptedData(context,
|
||||
crypto,
|
||||
KRB5_KU_TICKET,
|
||||
buf,
|
||||
len,
|
||||
0,
|
||||
reply);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if(ret) {
|
||||
kdc_log(context, config, 0, "Failed to encrypt data: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
encode_524_response(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
const char *spn, const EncTicketPart et,
|
||||
const Ticket *t, hdb_entry_ex *server,
|
||||
EncryptedData *ticket, int *kvno)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
int use_2b;
|
||||
size_t len;
|
||||
|
||||
use_2b = krb5_config_get_bool(context, NULL, "kdc", "use_2b", spn, NULL);
|
||||
if(use_2b) {
|
||||
ASN1_MALLOC_ENCODE(EncryptedData,
|
||||
ticket->cipher.data, ticket->cipher.length,
|
||||
&t->enc_part, &len, ret);
|
||||
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0,
|
||||
"Failed to encode v4 (2b) ticket (%s)", spn);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ticket->etype = 0;
|
||||
ticket->kvno = NULL;
|
||||
*kvno = 213; /* 2b's use this magic kvno */
|
||||
} else {
|
||||
unsigned char buf[MAX_KTXT_LEN + 4 * 4];
|
||||
Key *skey;
|
||||
|
||||
if (!config->enable_v4_cross_realm && strcmp (et.crealm, t->realm) != 0) {
|
||||
kdc_log(context, config, 0, "524 cross-realm %s -> %s disabled", et.crealm,
|
||||
t->realm);
|
||||
return KRB5KDC_ERR_POLICY;
|
||||
}
|
||||
|
||||
ret = _kdc_encode_v4_ticket(context, config,
|
||||
buf + sizeof(buf) - 1, sizeof(buf),
|
||||
&et, &t->sname, &len);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0,
|
||||
"Failed to encode v4 ticket (%s)", spn);
|
||||
return ret;
|
||||
}
|
||||
ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0,
|
||||
"no suitable DES key for server (%s)", spn);
|
||||
return ret;
|
||||
}
|
||||
ret = encrypt_v4_ticket(context, config, buf + sizeof(buf) - len, len,
|
||||
&skey->key, ticket);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0,
|
||||
"Failed to encrypt v4 ticket (%s)", spn);
|
||||
return ret;
|
||||
}
|
||||
*kvno = server->entry.kvno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* process a 5->4 request, based on `t', and received `from, addr',
|
||||
* returning the reply in `reply'
|
||||
*/
|
||||
|
||||
krb5_error_code
|
||||
_kdc_do_524(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
const Ticket *t, krb5_data *reply,
|
||||
const char *from, struct sockaddr *addr)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
krb5_crypto crypto;
|
||||
hdb_entry_ex *server = NULL;
|
||||
Key *skey;
|
||||
krb5_data et_data;
|
||||
EncTicketPart et;
|
||||
EncryptedData ticket;
|
||||
krb5_storage *sp;
|
||||
char *spn = NULL;
|
||||
unsigned char buf[MAX_KTXT_LEN + 4 * 4];
|
||||
size_t len;
|
||||
int kvno = 0;
|
||||
|
||||
if(!config->enable_524) {
|
||||
ret = KRB5KDC_ERR_POLICY;
|
||||
kdc_log(context, config, 0,
|
||||
"Rejected ticket conversion request from %s", from);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = fetch_server (context, config, t, &spn, &server, from);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = hdb_enctype2key(context, &server->entry, t->enc_part.etype, &skey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0,
|
||||
"No suitable key found for server (%s) from %s", spn, from);
|
||||
goto out;
|
||||
}
|
||||
ret = krb5_crypto_init(context, &skey->key, 0, &crypto);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
goto out;
|
||||
}
|
||||
ret = krb5_decrypt_EncryptedData (context,
|
||||
crypto,
|
||||
KRB5_KU_TICKET,
|
||||
&t->enc_part,
|
||||
&et_data);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0,
|
||||
"Failed to decrypt ticket from %s for %s", from, spn);
|
||||
goto out;
|
||||
}
|
||||
ret = krb5_decode_EncTicketPart(context, et_data.data, et_data.length,
|
||||
&et, &len);
|
||||
krb5_data_free(&et_data);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0,
|
||||
"Failed to decode ticket from %s for %s", from, spn);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = log_524 (context, config, &et, from, spn);
|
||||
if (ret) {
|
||||
free_EncTicketPart(&et);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = verify_flags (context, config, &et, spn);
|
||||
if (ret) {
|
||||
free_EncTicketPart(&et);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = set_address (context, config, &et, addr, from);
|
||||
if (ret) {
|
||||
free_EncTicketPart(&et);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = encode_524_response(context, config, spn, et, t,
|
||||
server, &ticket, &kvno);
|
||||
free_EncTicketPart(&et);
|
||||
|
||||
out:
|
||||
/* make reply */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
sp = krb5_storage_from_mem(buf, sizeof(buf));
|
||||
if (sp) {
|
||||
krb5_store_int32(sp, ret);
|
||||
if(ret == 0){
|
||||
krb5_store_int32(sp, kvno);
|
||||
krb5_store_data(sp, ticket.cipher);
|
||||
/* Aargh! This is coded as a KTEXT_ST. */
|
||||
krb5_storage_seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR);
|
||||
krb5_store_int32(sp, 0); /* mbz */
|
||||
free_EncryptedData(&ticket);
|
||||
}
|
||||
ret = krb5_storage_to_data(sp, reply);
|
||||
reply->length = krb5_storage_seek(sp, 0, SEEK_CUR);
|
||||
krb5_storage_free(sp);
|
||||
} else
|
||||
krb5_data_zero(reply);
|
||||
if(spn)
|
||||
free(spn);
|
||||
if(server)
|
||||
_kdc_free_ent (context, server);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2005 Andrew Bartlett <abartlet@samba.org>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 "kdc_locl.h"
|
||||
|
||||
/*
|
||||
* Setup some of the defaults for the KDC configuration.
|
||||
*
|
||||
* Note: Caller must also fill in:
|
||||
* - db
|
||||
* - num_db
|
||||
* - logf
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
krb5_kdc_default_config(krb5_kdc_configuration *config)
|
||||
{
|
||||
memset(config, 0, sizeof(*config));
|
||||
config->require_preauth = TRUE;
|
||||
config->kdc_warn_pwexpire = 0;
|
||||
config->encode_as_rep_as_tgs_rep = FALSE; /* bug compatibility */
|
||||
config->check_ticket_addresses = TRUE;
|
||||
config->allow_null_ticket_addresses = TRUE;
|
||||
config->allow_anonymous = FALSE;
|
||||
config->trpolicy = TRPOLICY_ALWAYS_CHECK;
|
||||
config->enable_v4 = FALSE;
|
||||
config->enable_kaserver = FALSE;
|
||||
config->enable_524 = FALSE; /* overriden by enable_v4 in configure()) */
|
||||
config->enable_v4_cross_realm = FALSE;
|
||||
config->enable_pkinit = FALSE;
|
||||
config->enable_pkinit_princ_in_cert = TRUE;
|
||||
config->db = NULL;
|
||||
config->num_db = 0;
|
||||
config->logf = NULL;
|
||||
}
|
||||
@@ -0,0 +1,712 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "kdc_locl.h"
|
||||
#include <digest_asn1.h>
|
||||
#include <hex.h>
|
||||
|
||||
RCSID("$Id: digest.c,v 1.7 2006/10/22 20:11:44 lha Exp $");
|
||||
|
||||
krb5_error_code
|
||||
_kdc_do_digest(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
const DigestREQ *req, krb5_data *reply,
|
||||
const char *from, struct sockaddr *addr)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
krb5_ticket *ticket = NULL;
|
||||
krb5_auth_context ac = NULL;
|
||||
krb5_keytab id = NULL;
|
||||
krb5_crypto crypto = NULL;
|
||||
DigestReqInner ireq;
|
||||
DigestRepInner r;
|
||||
DigestREP rep;
|
||||
krb5_flags ap_req_options;
|
||||
krb5_data buf;
|
||||
size_t size;
|
||||
krb5_storage *sp = NULL;
|
||||
Checksum res;
|
||||
hdb_entry_ex *server = NULL, *user = NULL;
|
||||
char *password = NULL;
|
||||
krb5_data serverNonce;
|
||||
|
||||
if(!config->enable_digest) {
|
||||
kdc_log(context, config, 0, "Rejected digest request from %s", from);
|
||||
return KRB5KDC_ERR_POLICY;
|
||||
}
|
||||
|
||||
krb5_data_zero(&buf);
|
||||
krb5_data_zero(reply);
|
||||
krb5_data_zero(&serverNonce);
|
||||
memset(&ireq, 0, sizeof(ireq));
|
||||
memset(&r, 0, sizeof(r));
|
||||
memset(&rep, 0, sizeof(rep));
|
||||
|
||||
kdc_log(context, config, 0, "Digest request from %s", from);
|
||||
|
||||
ret = krb5_kt_resolve(context, "HDB:", &id);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0, "Can't open database for digest");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_rd_req(context,
|
||||
&ac,
|
||||
&req->apReq,
|
||||
NULL,
|
||||
id,
|
||||
&ap_req_options,
|
||||
&ticket);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* check the server principal in the ticket matches digest/R@R */
|
||||
{
|
||||
krb5_principal principal = NULL;
|
||||
const char *p, *r;
|
||||
|
||||
ret = krb5_ticket_get_server(context, ticket, &principal);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = EINVAL;
|
||||
krb5_set_error_string(context, "Wrong digest server principal used");
|
||||
p = krb5_principal_get_comp_string(context, principal, 0);
|
||||
if (p == NULL) {
|
||||
krb5_free_principal(context, principal);
|
||||
goto out;
|
||||
}
|
||||
if (strcmp(p, KRB5_DIGEST_NAME) != 0) {
|
||||
krb5_free_principal(context, principal);
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = krb5_principal_get_comp_string(context, principal, 1);
|
||||
if (p == NULL) {
|
||||
krb5_free_principal(context, principal);
|
||||
goto out;
|
||||
}
|
||||
r = krb5_principal_get_realm(context, principal);
|
||||
if (r == NULL) {
|
||||
krb5_free_principal(context, principal);
|
||||
goto out;
|
||||
}
|
||||
if (strcmp(p, r) != 0) {
|
||||
krb5_free_principal(context, principal);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = _kdc_db_fetch(context, config, principal,
|
||||
HDB_F_GET_SERVER, NULL, &server);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
krb5_free_principal(context, principal);
|
||||
}
|
||||
|
||||
/* check the client is allowed to do digest auth */
|
||||
{
|
||||
krb5_principal principal = NULL;
|
||||
hdb_entry_ex *client;
|
||||
|
||||
ret = krb5_ticket_get_client(context, ticket, &principal);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = _kdc_db_fetch(context, config, principal,
|
||||
HDB_F_GET_CLIENT, NULL, &client);
|
||||
krb5_free_principal(context, principal);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (client->entry.flags.allow_digest == 0) {
|
||||
krb5_set_error_string(context,
|
||||
"Client is not permitted to use digest");
|
||||
ret = KRB5KDC_ERR_POLICY;
|
||||
_kdc_free_ent (context, client);
|
||||
goto out;
|
||||
}
|
||||
_kdc_free_ent (context, client);
|
||||
}
|
||||
|
||||
/* unpack request */
|
||||
{
|
||||
krb5_keyblock *key;
|
||||
|
||||
ret = krb5_auth_con_getremotesubkey(context, ac, &key);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (key == NULL) {
|
||||
krb5_set_error_string(context, "digest: remote subkey not found");
|
||||
ret = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_crypto_init(context, key, 0, &crypto);
|
||||
krb5_free_keyblock (context, key);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_decrypt_EncryptedData(context, crypto, KRB5_KU_DIGEST_ENCRYPT,
|
||||
&req->innerReq, &buf);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
crypto = NULL;
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = decode_DigestReqInner(buf.data, buf.length, &ireq, NULL);
|
||||
krb5_data_free(&buf);
|
||||
if (ret) {
|
||||
krb5_set_error_string(context, "Failed to decode digest inner request");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the inner request
|
||||
*/
|
||||
|
||||
switch (ireq.element) {
|
||||
case choice_DigestReqInner_init: {
|
||||
unsigned char server_nonce[16], identifier;
|
||||
|
||||
RAND_pseudo_bytes(&identifier, sizeof(identifier));
|
||||
RAND_pseudo_bytes(server_nonce, sizeof(server_nonce));
|
||||
|
||||
server_nonce[0] = kdc_time & 0xff;
|
||||
server_nonce[1] = (kdc_time >> 8) & 0xff;
|
||||
server_nonce[2] = (kdc_time >> 16) & 0xff;
|
||||
server_nonce[3] = (kdc_time >> 24) & 0xff;
|
||||
|
||||
r.element = choice_DigestRepInner_initReply;
|
||||
|
||||
hex_encode(server_nonce, sizeof(server_nonce), &r.u.initReply.nonce);
|
||||
if (r.u.initReply.nonce == NULL) {
|
||||
krb5_set_error_string(context, "Failed to decode server nonce");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
if (sp == NULL) {
|
||||
ret = ENOMEM;
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
goto out;
|
||||
}
|
||||
ret = krb5_store_stringz(sp, ireq.u.init.type);
|
||||
if (ret) {
|
||||
krb5_clear_error_string(context);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ireq.u.init.channel) {
|
||||
char *s;
|
||||
|
||||
asprintf(&s, "%s-%s:%s", r.u.initReply.nonce,
|
||||
ireq.u.init.channel->cb_type,
|
||||
ireq.u.init.channel->cb_binding);
|
||||
if (s == NULL) {
|
||||
krb5_set_error_string(context, "Failed to allocate "
|
||||
"channel binding");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
free(r.u.initReply.nonce);
|
||||
r.u.initReply.nonce = s;
|
||||
}
|
||||
|
||||
ret = krb5_store_stringz(sp, r.u.initReply.nonce);
|
||||
if (ret) {
|
||||
krb5_clear_error_string(context);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcasecmp(ireq.u.init.type, "CHAP") == 0) {
|
||||
r.u.initReply.identifier =
|
||||
malloc(sizeof(*r.u.initReply.identifier));
|
||||
if (r.u.initReply.identifier == NULL) {
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
asprintf(r.u.initReply.identifier, "%02X", identifier & 0xff);
|
||||
if (*r.u.initReply.identifier == NULL) {
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_store_stringz(sp, *r.u.initReply.identifier);
|
||||
if (ret) {
|
||||
krb5_clear_error_string(context);
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
r.u.initReply.identifier = NULL;
|
||||
|
||||
if (ireq.u.init.hostname) {
|
||||
ret = krb5_store_stringz(sp, *ireq.u.init.hostname);
|
||||
if (ret) {
|
||||
krb5_clear_error_string(context);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = krb5_storage_to_data(sp, &buf);
|
||||
if (ret) {
|
||||
krb5_clear_error_string(context);
|
||||
goto out;
|
||||
}
|
||||
|
||||
{
|
||||
Key *key;
|
||||
krb5_enctype enctype;
|
||||
|
||||
ret = _kdc_get_preferred_key(context,
|
||||
config,
|
||||
server,
|
||||
"digest-service",
|
||||
&enctype,
|
||||
&key);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = krb5_crypto_init(context, &key->key, 0, &crypto);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_create_checksum(context,
|
||||
crypto,
|
||||
KRB5_KU_DIGEST_OPAQUE,
|
||||
0,
|
||||
buf.data,
|
||||
buf.length,
|
||||
&res);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
crypto = NULL;
|
||||
krb5_data_free(&buf);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ASN1_MALLOC_ENCODE(Checksum, buf.data, buf.length, &res, &size, ret);
|
||||
free_Checksum(&res);
|
||||
if (ret) {
|
||||
krb5_set_error_string(context, "Failed to encode "
|
||||
"checksum in digest request");
|
||||
goto out;
|
||||
}
|
||||
if (size != buf.length)
|
||||
krb5_abortx(context, "ASN1 internal error");
|
||||
|
||||
hex_encode(buf.data, buf.length, &r.u.initReply.opaque);
|
||||
free(buf.data);
|
||||
if (r.u.initReply.opaque == NULL) {
|
||||
krb5_clear_error_string(context);
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case choice_DigestReqInner_digestRequest: {
|
||||
krb5_principal clientprincipal;
|
||||
HDB *db;
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
if (sp == NULL) {
|
||||
ret = ENOMEM;
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
goto out;
|
||||
}
|
||||
krb5_store_stringz(sp, ireq.u.digestRequest.type);
|
||||
|
||||
krb5_store_stringz(sp, ireq.u.digestRequest.serverNonce);
|
||||
if (ireq.u.digestRequest.identifier) {
|
||||
ret = krb5_store_stringz(sp, *ireq.u.digestRequest.identifier);
|
||||
if (ret) {
|
||||
krb5_clear_error_string(context);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (ireq.u.digestRequest.hostname) {
|
||||
ret = krb5_store_stringz(sp, *ireq.u.digestRequest.hostname);
|
||||
if (ret) {
|
||||
krb5_clear_error_string(context);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
buf.length = strlen(ireq.u.digestRequest.opaque);
|
||||
buf.data = malloc(buf.length);
|
||||
if (buf.data == NULL) {
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = hex_decode(ireq.u.digestRequest.opaque, buf.data, buf.length);
|
||||
if (ret <= 0) {
|
||||
krb5_set_error_string(context, "Failed to decode opaque");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
buf.length = ret;
|
||||
|
||||
ret = decode_Checksum(buf.data, buf.length, &res, NULL);
|
||||
free(buf.data);
|
||||
if (ret) {
|
||||
krb5_set_error_string(context, "Failed to decode digest Checksum");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_storage_to_data(sp, &buf);
|
||||
if (ret) {
|
||||
krb5_clear_error_string(context);
|
||||
goto out;
|
||||
}
|
||||
|
||||
serverNonce.length = strlen(ireq.u.digestRequest.serverNonce);
|
||||
serverNonce.data = malloc(serverNonce.length);
|
||||
if (serverNonce.data == NULL) {
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* CHAP does the checksum of the raw nonce, but do it for all
|
||||
* types, since we need to check the timestamp.
|
||||
*/
|
||||
{
|
||||
ssize_t ssize;
|
||||
|
||||
ssize = hex_decode(ireq.u.digestRequest.serverNonce,
|
||||
serverNonce.data, serverNonce.length);
|
||||
if (ssize <= 0) {
|
||||
krb5_set_error_string(context, "Failed to decode serverNonce");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
serverNonce.length = ssize;
|
||||
}
|
||||
|
||||
{
|
||||
Key *key;
|
||||
krb5_enctype enctype;
|
||||
|
||||
ret = _kdc_get_preferred_key(context,
|
||||
config,
|
||||
server,
|
||||
"digest-service",
|
||||
&enctype,
|
||||
&key);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = krb5_crypto_init(context, &key->key, 0, &crypto);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_verify_checksum(context, crypto,
|
||||
KRB5_KU_DIGEST_OPAQUE,
|
||||
buf.data, buf.length, &res);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
crypto = NULL;
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* verify time */
|
||||
{
|
||||
unsigned char *p = serverNonce.data;
|
||||
uint32_t t;
|
||||
|
||||
if (serverNonce.length < 4) {
|
||||
krb5_set_error_string(context, "server nonce too short");
|
||||
ret = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
t = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
||||
|
||||
if (abs((kdc_time & 0xffffffff) - t) > context->max_skew) {
|
||||
krb5_set_error_string(context, "time screw in server nonce ");
|
||||
ret = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* get username */
|
||||
ret = krb5_parse_name(context,
|
||||
ireq.u.digestRequest.username,
|
||||
&clientprincipal);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = _kdc_db_fetch(context, config, clientprincipal,
|
||||
HDB_F_GET_CLIENT, &db, &user);
|
||||
|
||||
krb5_free_principal(context, clientprincipal);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = hdb_entry_get_password(context, db, &user->entry, &password);
|
||||
if (ret || password == NULL) {
|
||||
if (ret == 0) {
|
||||
ret = EINVAL;
|
||||
krb5_set_error_string(context, "password missing");
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) {
|
||||
MD5_CTX ctx;
|
||||
unsigned char md[MD5_DIGEST_LENGTH];
|
||||
char id;
|
||||
|
||||
if (ireq.u.digestRequest.identifier == NULL) {
|
||||
krb5_set_error_string(context, "Identifier missing "
|
||||
"from CHAP request");
|
||||
ret = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hex_decode(*ireq.u.digestRequest.identifier, &id, 1) != 1) {
|
||||
krb5_set_error_string(context, "failed to decode identifier");
|
||||
ret = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, &id, 1);
|
||||
MD5_Update(&ctx, password, strlen(password));
|
||||
MD5_Update(&ctx, serverNonce.data, serverNonce.length);
|
||||
MD5_Final(md, &ctx);
|
||||
|
||||
r.element = choice_DigestRepInner_response;
|
||||
hex_encode(md, sizeof(md), &r.u.response.responseData);
|
||||
if (r.u.response.responseData == NULL) {
|
||||
krb5_clear_error_string(context);
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
} else if (strcasecmp(ireq.u.digestRequest.type, "SASL-DIGEST-MD5") == 0) {
|
||||
MD5_CTX ctx;
|
||||
unsigned char md[MD5_DIGEST_LENGTH];
|
||||
char *A1, *A2;
|
||||
|
||||
if (ireq.u.digestRequest.nonceCount == NULL)
|
||||
goto out;
|
||||
if (ireq.u.digestRequest.clientNonce == NULL)
|
||||
goto out;
|
||||
if (ireq.u.digestRequest.qop == NULL)
|
||||
goto out;
|
||||
if (ireq.u.digestRequest.realm == NULL)
|
||||
goto out;
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, ireq.u.digestRequest.username,
|
||||
strlen(ireq.u.digestRequest.username));
|
||||
MD5_Update(&ctx, ":", 1);
|
||||
MD5_Update(&ctx, *ireq.u.digestRequest.realm,
|
||||
strlen(*ireq.u.digestRequest.realm));
|
||||
MD5_Update(&ctx, ":", 1);
|
||||
MD5_Update(&ctx, password, strlen(password));
|
||||
MD5_Final(md, &ctx);
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, md, sizeof(md));
|
||||
MD5_Update(&ctx, ":", 1);
|
||||
MD5_Update(&ctx, ireq.u.digestRequest.serverNonce,
|
||||
strlen(ireq.u.digestRequest.serverNonce));
|
||||
MD5_Update(&ctx, ":", 1);
|
||||
MD5_Update(&ctx, *ireq.u.digestRequest.nonceCount,
|
||||
strlen(*ireq.u.digestRequest.nonceCount));
|
||||
if (ireq.u.digestRequest.authid) {
|
||||
MD5_Update(&ctx, ":", 1);
|
||||
MD5_Update(&ctx, *ireq.u.digestRequest.authid,
|
||||
strlen(*ireq.u.digestRequest.authid));
|
||||
}
|
||||
MD5_Final(md, &ctx);
|
||||
hex_encode(md, sizeof(md), &A1);
|
||||
if (A1 == NULL) {
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, "AUTHENTICATE:", sizeof("AUTHENTICATE:") - 1);
|
||||
MD5_Update(&ctx, *ireq.u.digestRequest.uri,
|
||||
strlen(*ireq.u.digestRequest.uri));
|
||||
|
||||
/* conf|int */
|
||||
if (strcmp(ireq.u.digestRequest.digest, "clear") != 0) {
|
||||
static char conf_zeros[] = ":00000000000000000000000000000000";
|
||||
MD5_Update(&ctx, conf_zeros, sizeof(conf_zeros) - 1);
|
||||
}
|
||||
|
||||
MD5_Final(md, &ctx);
|
||||
hex_encode(md, sizeof(md), &A2);
|
||||
if (A2 == NULL) {
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
ret = ENOMEM;
|
||||
free(A1);
|
||||
goto out;
|
||||
}
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, A1, strlen(A2));
|
||||
MD5_Update(&ctx, ":", 1);
|
||||
MD5_Update(&ctx, ireq.u.digestRequest.serverNonce,
|
||||
strlen(ireq.u.digestRequest.serverNonce));
|
||||
MD5_Update(&ctx, ":", 1);
|
||||
MD5_Update(&ctx, *ireq.u.digestRequest.nonceCount,
|
||||
strlen(*ireq.u.digestRequest.nonceCount));
|
||||
MD5_Update(&ctx, ":", 1);
|
||||
MD5_Update(&ctx, *ireq.u.digestRequest.clientNonce,
|
||||
strlen(*ireq.u.digestRequest.clientNonce));
|
||||
MD5_Update(&ctx, ":", 1);
|
||||
MD5_Update(&ctx, *ireq.u.digestRequest.qop,
|
||||
strlen(*ireq.u.digestRequest.qop));
|
||||
MD5_Update(&ctx, ":", 1);
|
||||
MD5_Update(&ctx, A2, strlen(A2));
|
||||
|
||||
MD5_Final(md, &ctx);
|
||||
|
||||
r.element = choice_DigestRepInner_response;
|
||||
hex_encode(md, sizeof(md), &r.u.response.responseData);
|
||||
|
||||
free(A1);
|
||||
free(A2);
|
||||
|
||||
if (r.u.response.responseData == NULL) {
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
} else {
|
||||
r.element = choice_DigestRepInner_error;
|
||||
asprintf(&r.u.error.reason, "unsupported digest type %s",
|
||||
ireq.u.digestRequest.type);
|
||||
if (r.u.error.reason == NULL) {
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
r.u.error.code = EINVAL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
r.element = choice_DigestRepInner_error;
|
||||
r.u.error.reason = strdup("unknown operation");
|
||||
if (r.u.error.reason == NULL) {
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
r.u.error.code = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
ASN1_MALLOC_ENCODE(DigestRepInner, buf.data, buf.length, &r, &size, ret);
|
||||
if (ret) {
|
||||
krb5_set_error_string(context, "Failed to encode inner digest reply");
|
||||
goto out;
|
||||
}
|
||||
if (size != buf.length)
|
||||
krb5_abortx(context, "ASN1 internal error");
|
||||
|
||||
krb5_auth_con_addflags(context, ac, KRB5_AUTH_CONTEXT_USE_SUBKEY, NULL);
|
||||
|
||||
ret = krb5_mk_rep (context, ac, &rep.apRep);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
{
|
||||
krb5_keyblock *key;
|
||||
|
||||
ret = krb5_auth_con_getlocalsubkey(context, ac, &key);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = krb5_crypto_init(context, key, 0, &crypto);
|
||||
krb5_free_keyblock (context, key);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_encrypt_EncryptedData(context, crypto, KRB5_KU_DIGEST_ENCRYPT,
|
||||
buf.data, buf.length, 0,
|
||||
&rep.innerRep);
|
||||
|
||||
ASN1_MALLOC_ENCODE(DigestREP, reply->data, reply->length, &rep, &size, ret);
|
||||
if (ret) {
|
||||
krb5_set_error_string(context, "Failed to encode digest reply");
|
||||
goto out;
|
||||
}
|
||||
if (size != reply->length)
|
||||
krb5_abortx(context, "ASN1 internal error");
|
||||
|
||||
|
||||
out:
|
||||
if (ac)
|
||||
krb5_auth_con_free(context, ac);
|
||||
if (ret)
|
||||
krb5_warn(context, ret, "Digest request from %s failed", from);
|
||||
if (ticket)
|
||||
krb5_free_ticket(context, ticket);
|
||||
if (id)
|
||||
krb5_kt_close(context, id);
|
||||
if (crypto)
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
if (sp)
|
||||
krb5_storage_free(sp);
|
||||
if (user)
|
||||
_kdc_free_ent (context, user);
|
||||
if (server)
|
||||
_kdc_free_ent (context, server);
|
||||
if (password) {
|
||||
memset(password, 0, strlen(password));
|
||||
free (password);
|
||||
}
|
||||
krb5_data_free(&buf);
|
||||
krb5_data_free(&serverNonce);
|
||||
free_DigestREP(&rep);
|
||||
free_DigestRepInner(&r);
|
||||
free_DigestReqInner(&ireq);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 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: headers.h,v 1.18 2006/10/17 02:22:17 lha Exp $
|
||||
*/
|
||||
|
||||
#ifndef __HEADERS_H__
|
||||
#define __HEADERS_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN6_H
|
||||
#include <netinet/in6.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET6_IN6_H
|
||||
#include <netinet6/in6.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#include <err.h>
|
||||
#include <roken.h>
|
||||
#include <getarg.h>
|
||||
#include <base64.h>
|
||||
#include <parse_units.h>
|
||||
#include <krb5.h>
|
||||
#include <krb5_locl.h>
|
||||
#include <digest_asn1.h>
|
||||
#include <hdb.h>
|
||||
#include <hdb_err.h>
|
||||
#include <der.h>
|
||||
|
||||
#undef ALLOC
|
||||
#define ALLOC(X) ((X) = malloc(sizeof(*(X))))
|
||||
#undef ALLOC_SEQ
|
||||
#define ALLOC_SEQ(X, N) do { (X)->len = (N); \
|
||||
(X)->val = calloc((X)->len, sizeof(*(X)->val)); } while(0)
|
||||
|
||||
#endif /* __HEADERS_H__ */
|
||||
@@ -0,0 +1,942 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "kdc_locl.h"
|
||||
|
||||
RCSID("$Id: kaserver.c,v 1.36 2006/08/23 11:43:44 lha Exp $");
|
||||
|
||||
#include <krb5-v4compat.h>
|
||||
#include <rx.h>
|
||||
|
||||
#define KA_AUTHENTICATION_SERVICE 731
|
||||
#define KA_TICKET_GRANTING_SERVICE 732
|
||||
#define KA_MAINTENANCE_SERVICE 733
|
||||
|
||||
#define AUTHENTICATE_OLD 1
|
||||
#define CHANGEPASSWORD 2
|
||||
#define GETTICKET_OLD 3
|
||||
#define SETPASSWORD 4
|
||||
#define SETFIELDS 5
|
||||
#define CREATEUSER 6
|
||||
#define DELETEUSER 7
|
||||
#define GETENTRY 8
|
||||
#define LISTENTRY 9
|
||||
#define GETSTATS 10
|
||||
#define DEBUG 11
|
||||
#define GETPASSWORD 12
|
||||
#define GETRANDOMKEY 13
|
||||
#define AUTHENTICATE 21
|
||||
#define AUTHENTICATE_V2 22
|
||||
#define GETTICKET 23
|
||||
|
||||
/* XXX - Where do we get these? */
|
||||
|
||||
#define RXGEN_OPCODE (-455)
|
||||
|
||||
#define KADATABASEINCONSISTENT (180480L)
|
||||
#define KAEXIST (180481L)
|
||||
#define KAIO (180482L)
|
||||
#define KACREATEFAIL (180483L)
|
||||
#define KANOENT (180484L)
|
||||
#define KAEMPTY (180485L)
|
||||
#define KABADNAME (180486L)
|
||||
#define KABADINDEX (180487L)
|
||||
#define KANOAUTH (180488L)
|
||||
#define KAANSWERTOOLONG (180489L)
|
||||
#define KABADREQUEST (180490L)
|
||||
#define KAOLDINTERFACE (180491L)
|
||||
#define KABADARGUMENT (180492L)
|
||||
#define KABADCMD (180493L)
|
||||
#define KANOKEYS (180494L)
|
||||
#define KAREADPW (180495L)
|
||||
#define KABADKEY (180496L)
|
||||
#define KAUBIKINIT (180497L)
|
||||
#define KAUBIKCALL (180498L)
|
||||
#define KABADPROTOCOL (180499L)
|
||||
#define KANOCELLS (180500L)
|
||||
#define KANOCELL (180501L)
|
||||
#define KATOOMANYUBIKS (180502L)
|
||||
#define KATOOMANYKEYS (180503L)
|
||||
#define KABADTICKET (180504L)
|
||||
#define KAUNKNOWNKEY (180505L)
|
||||
#define KAKEYCACHEINVALID (180506L)
|
||||
#define KABADSERVER (180507L)
|
||||
#define KABADUSER (180508L)
|
||||
#define KABADCPW (180509L)
|
||||
#define KABADCREATE (180510L)
|
||||
#define KANOTICKET (180511L)
|
||||
#define KAASSOCUSER (180512L)
|
||||
#define KANOTSPECIAL (180513L)
|
||||
#define KACLOCKSKEW (180514L)
|
||||
#define KANORECURSE (180515L)
|
||||
#define KARXFAIL (180516L)
|
||||
#define KANULLPASSWORD (180517L)
|
||||
#define KAINTERNALERROR (180518L)
|
||||
#define KAPWEXPIRED (180519L)
|
||||
#define KAREUSED (180520L)
|
||||
#define KATOOSOON (180521L)
|
||||
#define KALOCKED (180522L)
|
||||
|
||||
|
||||
static krb5_error_code
|
||||
decode_rx_header (krb5_storage *sp,
|
||||
struct rx_header *h)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = krb5_ret_uint32(sp, &h->epoch);
|
||||
if (ret) return ret;
|
||||
ret = krb5_ret_uint32(sp, &h->connid);
|
||||
if (ret) return ret;
|
||||
ret = krb5_ret_uint32(sp, &h->callid);
|
||||
if (ret) return ret;
|
||||
ret = krb5_ret_uint32(sp, &h->seqno);
|
||||
if (ret) return ret;
|
||||
ret = krb5_ret_uint32(sp, &h->serialno);
|
||||
if (ret) return ret;
|
||||
ret = krb5_ret_uint8(sp, &h->type);
|
||||
if (ret) return ret;
|
||||
ret = krb5_ret_uint8(sp, &h->flags);
|
||||
if (ret) return ret;
|
||||
ret = krb5_ret_uint8(sp, &h->status);
|
||||
if (ret) return ret;
|
||||
ret = krb5_ret_uint8(sp, &h->secindex);
|
||||
if (ret) return ret;
|
||||
ret = krb5_ret_uint16(sp, &h->reserved);
|
||||
if (ret) return ret;
|
||||
ret = krb5_ret_uint16(sp, &h->serviceid);
|
||||
if (ret) return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
encode_rx_header (struct rx_header *h,
|
||||
krb5_storage *sp)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = krb5_store_uint32(sp, h->epoch);
|
||||
if (ret) return ret;
|
||||
ret = krb5_store_uint32(sp, h->connid);
|
||||
if (ret) return ret;
|
||||
ret = krb5_store_uint32(sp, h->callid);
|
||||
if (ret) return ret;
|
||||
ret = krb5_store_uint32(sp, h->seqno);
|
||||
if (ret) return ret;
|
||||
ret = krb5_store_uint32(sp, h->serialno);
|
||||
if (ret) return ret;
|
||||
ret = krb5_store_uint8(sp, h->type);
|
||||
if (ret) return ret;
|
||||
ret = krb5_store_uint8(sp, h->flags);
|
||||
if (ret) return ret;
|
||||
ret = krb5_store_uint8(sp, h->status);
|
||||
if (ret) return ret;
|
||||
ret = krb5_store_uint8(sp, h->secindex);
|
||||
if (ret) return ret;
|
||||
ret = krb5_store_uint16(sp, h->reserved);
|
||||
if (ret) return ret;
|
||||
ret = krb5_store_uint16(sp, h->serviceid);
|
||||
if (ret) return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
init_reply_header (struct rx_header *hdr,
|
||||
struct rx_header *reply_hdr,
|
||||
u_char type,
|
||||
u_char flags)
|
||||
{
|
||||
reply_hdr->epoch = hdr->epoch;
|
||||
reply_hdr->connid = hdr->connid;
|
||||
reply_hdr->callid = hdr->callid;
|
||||
reply_hdr->seqno = 1;
|
||||
reply_hdr->serialno = 1;
|
||||
reply_hdr->type = type;
|
||||
reply_hdr->flags = flags;
|
||||
reply_hdr->status = 0;
|
||||
reply_hdr->secindex = 0;
|
||||
reply_hdr->reserved = 0;
|
||||
reply_hdr->serviceid = hdr->serviceid;
|
||||
}
|
||||
|
||||
static void
|
||||
make_error_reply (struct rx_header *hdr,
|
||||
uint32_t ret,
|
||||
krb5_data *reply)
|
||||
|
||||
{
|
||||
krb5_storage *sp;
|
||||
struct rx_header reply_hdr;
|
||||
|
||||
init_reply_header (hdr, &reply_hdr, HT_ABORT, HF_LAST);
|
||||
sp = krb5_storage_emem();
|
||||
ret = encode_rx_header (&reply_hdr, sp);
|
||||
krb5_store_int32(sp, ret);
|
||||
krb5_storage_to_data (sp, reply);
|
||||
krb5_storage_free (sp);
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
krb5_ret_xdr_data(krb5_storage *sp,
|
||||
krb5_data *data)
|
||||
{
|
||||
int ret;
|
||||
int size;
|
||||
ret = krb5_ret_int32(sp, &size);
|
||||
if(ret)
|
||||
return ret;
|
||||
if(size < 0)
|
||||
return ERANGE;
|
||||
data->length = size;
|
||||
if (size) {
|
||||
u_char foo[4];
|
||||
size_t pad = (4 - size % 4) % 4;
|
||||
|
||||
data->data = malloc(size);
|
||||
if (data->data == NULL)
|
||||
return ENOMEM;
|
||||
ret = krb5_storage_read(sp, data->data, size);
|
||||
if(ret != size)
|
||||
return (ret < 0)? errno : KRB5_CC_END;
|
||||
if (pad) {
|
||||
ret = krb5_storage_read(sp, foo, pad);
|
||||
if (ret != pad)
|
||||
return (ret < 0)? errno : KRB5_CC_END;
|
||||
}
|
||||
} else
|
||||
data->data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
krb5_store_xdr_data(krb5_storage *sp,
|
||||
krb5_data data)
|
||||
{
|
||||
u_char zero[4] = {0, 0, 0, 0};
|
||||
int ret;
|
||||
size_t pad;
|
||||
|
||||
ret = krb5_store_int32(sp, data.length);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
ret = krb5_storage_write(sp, data.data, data.length);
|
||||
if(ret != data.length){
|
||||
if(ret < 0)
|
||||
return errno;
|
||||
return KRB5_CC_END;
|
||||
}
|
||||
pad = (4 - data.length % 4) % 4;
|
||||
if (pad) {
|
||||
ret = krb5_storage_write(sp, zero, pad);
|
||||
if (ret != pad) {
|
||||
if (ret < 0)
|
||||
return errno;
|
||||
return KRB5_CC_END;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static krb5_error_code
|
||||
create_reply_ticket (krb5_context context,
|
||||
struct rx_header *hdr,
|
||||
Key *skey,
|
||||
char *name, char *instance, char *realm,
|
||||
struct sockaddr_in *addr,
|
||||
int life,
|
||||
int kvno,
|
||||
int32_t max_seq_len,
|
||||
const char *sname, const char *sinstance,
|
||||
uint32_t challenge,
|
||||
const char *label,
|
||||
krb5_keyblock *key,
|
||||
krb5_data *reply)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_data ticket;
|
||||
krb5_keyblock session;
|
||||
krb5_storage *sp;
|
||||
krb5_data enc_data;
|
||||
struct rx_header reply_hdr;
|
||||
char zero[8];
|
||||
size_t pad;
|
||||
unsigned fyrtiosjuelva;
|
||||
|
||||
/* create the ticket */
|
||||
|
||||
krb5_generate_random_keyblock(context, ETYPE_DES_PCBC_NONE, &session);
|
||||
|
||||
_krb5_krb_create_ticket(context,
|
||||
0,
|
||||
name,
|
||||
instance,
|
||||
realm,
|
||||
addr->sin_addr.s_addr,
|
||||
&session,
|
||||
life,
|
||||
kdc_time,
|
||||
sname,
|
||||
sinstance,
|
||||
&skey->key,
|
||||
&ticket);
|
||||
|
||||
/* create the encrypted part of the reply */
|
||||
sp = krb5_storage_emem ();
|
||||
krb5_generate_random_block(&fyrtiosjuelva, sizeof(fyrtiosjuelva));
|
||||
fyrtiosjuelva &= 0xffffffff;
|
||||
krb5_store_int32 (sp, fyrtiosjuelva);
|
||||
krb5_store_int32 (sp, challenge);
|
||||
krb5_storage_write (sp, session.keyvalue.data, 8);
|
||||
krb5_free_keyblock_contents(context, &session);
|
||||
krb5_store_int32 (sp, kdc_time);
|
||||
krb5_store_int32 (sp, kdc_time + _krb5_krb_life_to_time (0, life));
|
||||
krb5_store_int32 (sp, kvno);
|
||||
krb5_store_int32 (sp, ticket.length);
|
||||
krb5_store_stringz (sp, name);
|
||||
krb5_store_stringz (sp, instance);
|
||||
#if 1 /* XXX - Why shouldn't the realm go here? */
|
||||
krb5_store_stringz (sp, "");
|
||||
#else
|
||||
krb5_store_stringz (sp, realm);
|
||||
#endif
|
||||
krb5_store_stringz (sp, sname);
|
||||
krb5_store_stringz (sp, sinstance);
|
||||
krb5_storage_write (sp, ticket.data, ticket.length);
|
||||
krb5_storage_write (sp, label, strlen(label));
|
||||
|
||||
/* pad to DES block */
|
||||
memset (zero, 0, sizeof(zero));
|
||||
pad = (8 - krb5_storage_seek (sp, 0, SEEK_CUR) % 8) % 8;
|
||||
krb5_storage_write (sp, zero, pad);
|
||||
|
||||
krb5_storage_to_data (sp, &enc_data);
|
||||
krb5_storage_free (sp);
|
||||
|
||||
if (enc_data.length > max_seq_len) {
|
||||
krb5_data_free (&enc_data);
|
||||
make_error_reply (hdr, KAANSWERTOOLONG, reply);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encrypt it */
|
||||
{
|
||||
DES_key_schedule schedule;
|
||||
DES_cblock deskey;
|
||||
|
||||
memcpy (&deskey, key->keyvalue.data, sizeof(deskey));
|
||||
DES_set_key (&deskey, &schedule);
|
||||
DES_pcbc_encrypt (enc_data.data,
|
||||
enc_data.data,
|
||||
enc_data.length,
|
||||
&schedule,
|
||||
&deskey,
|
||||
DES_ENCRYPT);
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
memset (&deskey, 0, sizeof(deskey));
|
||||
}
|
||||
|
||||
/* create the reply packet */
|
||||
init_reply_header (hdr, &reply_hdr, HT_DATA, HF_LAST);
|
||||
sp = krb5_storage_emem ();
|
||||
ret = encode_rx_header (&reply_hdr, sp);
|
||||
krb5_store_int32 (sp, max_seq_len);
|
||||
krb5_store_xdr_data (sp, enc_data);
|
||||
krb5_data_free (&enc_data);
|
||||
krb5_storage_to_data (sp, reply);
|
||||
krb5_storage_free (sp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
unparse_auth_args (krb5_storage *sp,
|
||||
char **name,
|
||||
char **instance,
|
||||
time_t *start_time,
|
||||
time_t *end_time,
|
||||
krb5_data *request,
|
||||
int32_t *max_seq_len)
|
||||
{
|
||||
krb5_data data;
|
||||
int32_t tmp;
|
||||
|
||||
krb5_ret_xdr_data (sp, &data);
|
||||
*name = malloc(data.length + 1);
|
||||
if (*name == NULL)
|
||||
return ENOMEM;
|
||||
memcpy (*name, data.data, data.length);
|
||||
(*name)[data.length] = '\0';
|
||||
krb5_data_free (&data);
|
||||
|
||||
krb5_ret_xdr_data (sp, &data);
|
||||
*instance = malloc(data.length + 1);
|
||||
if (*instance == NULL) {
|
||||
free (*name);
|
||||
return ENOMEM;
|
||||
}
|
||||
memcpy (*instance, data.data, data.length);
|
||||
(*instance)[data.length] = '\0';
|
||||
krb5_data_free (&data);
|
||||
|
||||
krb5_ret_int32 (sp, &tmp);
|
||||
*start_time = tmp;
|
||||
krb5_ret_int32 (sp, &tmp);
|
||||
*end_time = tmp;
|
||||
krb5_ret_xdr_data (sp, request);
|
||||
krb5_ret_int32 (sp, max_seq_len);
|
||||
/* ignore the rest */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
do_authenticate (krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
struct rx_header *hdr,
|
||||
krb5_storage *sp,
|
||||
struct sockaddr_in *addr,
|
||||
const char *from,
|
||||
krb5_data *reply)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
char *name = NULL;
|
||||
char *instance = NULL;
|
||||
time_t start_time;
|
||||
time_t end_time;
|
||||
krb5_data request;
|
||||
int32_t max_seq_len;
|
||||
hdb_entry_ex *client_entry = NULL;
|
||||
hdb_entry_ex *server_entry = NULL;
|
||||
Key *ckey = NULL;
|
||||
Key *skey = NULL;
|
||||
krb5_storage *reply_sp;
|
||||
time_t max_life;
|
||||
uint8_t life;
|
||||
int32_t chal;
|
||||
char client_name[256];
|
||||
char server_name[256];
|
||||
|
||||
krb5_data_zero (&request);
|
||||
|
||||
ret = unparse_auth_args (sp, &name, &instance, &start_time, &end_time,
|
||||
&request, &max_seq_len);
|
||||
if (ret != 0 || request.length < 8) {
|
||||
make_error_reply (hdr, KABADREQUEST, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
snprintf (client_name, sizeof(client_name), "%s.%s@%s",
|
||||
name, instance, config->v4_realm);
|
||||
snprintf (server_name, sizeof(server_name), "%s.%s@%s",
|
||||
"krbtgt", config->v4_realm, config->v4_realm);
|
||||
|
||||
kdc_log(context, config, 0, "AS-REQ (kaserver) %s from %s for %s",
|
||||
client_name, from, server_name);
|
||||
|
||||
ret = _kdc_db_fetch4 (context, config, name, instance,
|
||||
config->v4_realm, HDB_F_GET_CLIENT,
|
||||
&client_entry);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0, "Client not found in database: %s: %s",
|
||||
client_name, krb5_get_err_text(context, ret));
|
||||
make_error_reply (hdr, KANOENT, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = _kdc_db_fetch4 (context, config, "krbtgt",
|
||||
config->v4_realm, config->v4_realm,
|
||||
HDB_F_GET_KRBTGT, &server_entry);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0, "Server not found in database: %s: %s",
|
||||
server_name, krb5_get_err_text(context, ret));
|
||||
make_error_reply (hdr, KANOENT, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = _kdc_check_flags (context, config,
|
||||
client_entry, client_name,
|
||||
server_entry, server_name,
|
||||
TRUE);
|
||||
if (ret) {
|
||||
make_error_reply (hdr, KAPWEXPIRED, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* find a DES key */
|
||||
ret = _kdc_get_des_key(context, client_entry, FALSE, TRUE, &ckey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0, "no suitable DES key for client");
|
||||
make_error_reply (hdr, KANOKEYS, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* find a DES key */
|
||||
ret = _kdc_get_des_key(context, server_entry, TRUE, TRUE, &skey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0, "no suitable DES key for server");
|
||||
make_error_reply (hdr, KANOKEYS, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
{
|
||||
DES_cblock key;
|
||||
DES_key_schedule schedule;
|
||||
|
||||
/* try to decode the `request' */
|
||||
memcpy (&key, ckey->key.keyvalue.data, sizeof(key));
|
||||
DES_set_key (&key, &schedule);
|
||||
DES_pcbc_encrypt (request.data,
|
||||
request.data,
|
||||
request.length,
|
||||
&schedule,
|
||||
&key,
|
||||
DES_DECRYPT);
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
memset (&key, 0, sizeof(key));
|
||||
}
|
||||
|
||||
/* check for the magic label */
|
||||
if (memcmp ((char *)request.data + 4, "gTGS", 4) != 0) {
|
||||
kdc_log(context, config, 0, "preauth failed for %s", client_name);
|
||||
make_error_reply (hdr, KABADREQUEST, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
reply_sp = krb5_storage_from_mem (request.data, 4);
|
||||
krb5_ret_int32 (reply_sp, &chal);
|
||||
krb5_storage_free (reply_sp);
|
||||
|
||||
if (abs(chal - kdc_time) > context->max_skew) {
|
||||
make_error_reply (hdr, KACLOCKSKEW, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* life */
|
||||
max_life = end_time - kdc_time;
|
||||
/* end_time - kdc_time can sometimes be non-positive due to slight
|
||||
time skew between client and server. Let's make sure it is postive */
|
||||
if(max_life < 1)
|
||||
max_life = 1;
|
||||
if (client_entry->entry.max_life)
|
||||
max_life = min(max_life, *client_entry->entry.max_life);
|
||||
if (server_entry->entry.max_life)
|
||||
max_life = min(max_life, *server_entry->entry.max_life);
|
||||
|
||||
life = krb_time_to_life(kdc_time, kdc_time + max_life);
|
||||
|
||||
create_reply_ticket (context,
|
||||
hdr, skey,
|
||||
name, instance, config->v4_realm,
|
||||
addr, life, server_entry->entry.kvno,
|
||||
max_seq_len,
|
||||
"krbtgt", config->v4_realm,
|
||||
chal + 1, "tgsT",
|
||||
&ckey->key, reply);
|
||||
|
||||
out:
|
||||
if (request.length) {
|
||||
memset (request.data, 0, request.length);
|
||||
krb5_data_free (&request);
|
||||
}
|
||||
if (name)
|
||||
free (name);
|
||||
if (instance)
|
||||
free (instance);
|
||||
if (client_entry)
|
||||
_kdc_free_ent (context, client_entry);
|
||||
if (server_entry)
|
||||
_kdc_free_ent (context, server_entry);
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
unparse_getticket_args (krb5_storage *sp,
|
||||
int *kvno,
|
||||
char **auth_domain,
|
||||
krb5_data *ticket,
|
||||
char **name,
|
||||
char **instance,
|
||||
krb5_data *times,
|
||||
int32_t *max_seq_len)
|
||||
{
|
||||
krb5_data data;
|
||||
int32_t tmp;
|
||||
|
||||
krb5_ret_int32 (sp, &tmp);
|
||||
*kvno = tmp;
|
||||
|
||||
krb5_ret_xdr_data (sp, &data);
|
||||
*auth_domain = malloc(data.length + 1);
|
||||
if (*auth_domain == NULL)
|
||||
return ENOMEM;
|
||||
memcpy (*auth_domain, data.data, data.length);
|
||||
(*auth_domain)[data.length] = '\0';
|
||||
krb5_data_free (&data);
|
||||
|
||||
krb5_ret_xdr_data (sp, ticket);
|
||||
|
||||
krb5_ret_xdr_data (sp, &data);
|
||||
*name = malloc(data.length + 1);
|
||||
if (*name == NULL) {
|
||||
free (*auth_domain);
|
||||
return ENOMEM;
|
||||
}
|
||||
memcpy (*name, data.data, data.length);
|
||||
(*name)[data.length] = '\0';
|
||||
krb5_data_free (&data);
|
||||
|
||||
krb5_ret_xdr_data (sp, &data);
|
||||
*instance = malloc(data.length + 1);
|
||||
if (*instance == NULL) {
|
||||
free (*auth_domain);
|
||||
free (*name);
|
||||
return ENOMEM;
|
||||
}
|
||||
memcpy (*instance, data.data, data.length);
|
||||
(*instance)[data.length] = '\0';
|
||||
krb5_data_free (&data);
|
||||
|
||||
krb5_ret_xdr_data (sp, times);
|
||||
|
||||
krb5_ret_int32 (sp, max_seq_len);
|
||||
/* ignore the rest */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
do_getticket (krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
struct rx_header *hdr,
|
||||
krb5_storage *sp,
|
||||
struct sockaddr_in *addr,
|
||||
const char *from,
|
||||
krb5_data *reply)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
int kvno;
|
||||
char *auth_domain = NULL;
|
||||
krb5_data aticket;
|
||||
char *name = NULL;
|
||||
char *instance = NULL;
|
||||
krb5_data times;
|
||||
int32_t max_seq_len;
|
||||
hdb_entry_ex *server_entry = NULL;
|
||||
hdb_entry_ex *client_entry = NULL;
|
||||
hdb_entry_ex *krbtgt_entry = NULL;
|
||||
Key *kkey = NULL;
|
||||
Key *skey = NULL;
|
||||
DES_cblock key;
|
||||
DES_key_schedule schedule;
|
||||
DES_cblock session;
|
||||
time_t max_life;
|
||||
int8_t life;
|
||||
time_t start_time, end_time;
|
||||
char server_name[256];
|
||||
char client_name[256];
|
||||
struct _krb5_krb_auth_data ad;
|
||||
|
||||
krb5_data_zero (&aticket);
|
||||
krb5_data_zero (×);
|
||||
|
||||
memset(&ad, 0, sizeof(ad));
|
||||
|
||||
unparse_getticket_args (sp, &kvno, &auth_domain, &aticket,
|
||||
&name, &instance, ×, &max_seq_len);
|
||||
if (times.length < 8) {
|
||||
make_error_reply (hdr, KABADREQUEST, reply);
|
||||
goto out;
|
||||
|
||||
}
|
||||
|
||||
snprintf (server_name, sizeof(server_name),
|
||||
"%s.%s@%s", name, instance, config->v4_realm);
|
||||
|
||||
ret = _kdc_db_fetch4 (context, config, name, instance,
|
||||
config->v4_realm, HDB_F_GET_SERVER, &server_entry);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0, "Server not found in database: %s: %s",
|
||||
server_name, krb5_get_err_text(context, ret));
|
||||
make_error_reply (hdr, KANOENT, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = _kdc_db_fetch4 (context, config, "krbtgt",
|
||||
config->v4_realm, config->v4_realm, HDB_F_GET_KRBTGT, &krbtgt_entry);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0,
|
||||
"Server not found in database: %s.%s@%s: %s",
|
||||
"krbtgt", config->v4_realm, config->v4_realm,
|
||||
krb5_get_err_text(context, ret));
|
||||
make_error_reply (hdr, KANOENT, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* find a DES key */
|
||||
ret = _kdc_get_des_key(context, krbtgt_entry, TRUE, TRUE, &kkey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0, "no suitable DES key for krbtgt");
|
||||
make_error_reply (hdr, KANOKEYS, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* find a DES key */
|
||||
ret = _kdc_get_des_key(context, server_entry, TRUE, TRUE, &skey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0, "no suitable DES key for server");
|
||||
make_error_reply (hdr, KANOKEYS, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* decrypt the incoming ticket */
|
||||
memcpy (&key, kkey->key.keyvalue.data, sizeof(key));
|
||||
|
||||
/* unpack the ticket */
|
||||
{
|
||||
char *sname = NULL;
|
||||
char *sinstance = NULL;
|
||||
|
||||
ret = _krb5_krb_decomp_ticket(context, &aticket, &kkey->key,
|
||||
config->v4_realm, &sname,
|
||||
&sinstance, &ad);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0,
|
||||
"kaserver: decomp failed for %s.%s with %d",
|
||||
sname, sinstance, ret);
|
||||
make_error_reply (hdr, KABADTICKET, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp (sname, "krbtgt") != 0
|
||||
|| strcmp (sinstance, config->v4_realm) != 0) {
|
||||
kdc_log(context, config, 0, "no TGT: %s.%s for %s.%s@%s",
|
||||
sname, sinstance,
|
||||
ad.pname, ad.pinst, ad.prealm);
|
||||
make_error_reply (hdr, KABADTICKET, reply);
|
||||
free(sname);
|
||||
free(sinstance);
|
||||
goto out;
|
||||
}
|
||||
free(sname);
|
||||
free(sinstance);
|
||||
|
||||
if (kdc_time > _krb5_krb_life_to_time(ad.time_sec, ad.life)) {
|
||||
kdc_log(context, config, 0, "TGT expired: %s.%s@%s",
|
||||
ad.pname, ad.pinst, ad.prealm);
|
||||
make_error_reply (hdr, KABADTICKET, reply);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf (client_name, sizeof(client_name),
|
||||
"%s.%s@%s", ad.pname, ad.pinst, ad.prealm);
|
||||
|
||||
kdc_log(context, config, 0, "TGS-REQ (kaserver) %s from %s for %s",
|
||||
client_name, from, server_name);
|
||||
|
||||
ret = _kdc_db_fetch4 (context, config,
|
||||
ad.pname, ad.pinst, ad.prealm, HDB_F_GET_CLIENT,
|
||||
&client_entry);
|
||||
if(ret && ret != HDB_ERR_NOENTRY) {
|
||||
kdc_log(context, config, 0,
|
||||
"Client not found in database: (krb4) %s: %s",
|
||||
client_name, krb5_get_err_text(context, ret));
|
||||
make_error_reply (hdr, KANOENT, reply);
|
||||
goto out;
|
||||
}
|
||||
if (client_entry == NULL && strcmp(ad.prealm, config->v4_realm) == 0) {
|
||||
kdc_log(context, config, 0,
|
||||
"Local client not found in database: (krb4) "
|
||||
"%s", client_name);
|
||||
make_error_reply (hdr, KANOENT, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = _kdc_check_flags (context, config,
|
||||
client_entry, client_name,
|
||||
server_entry, server_name,
|
||||
FALSE);
|
||||
if (ret) {
|
||||
make_error_reply (hdr, KAPWEXPIRED, reply);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* decrypt the times */
|
||||
memcpy(&session, ad.session.keyvalue.data, sizeof(session));
|
||||
DES_set_key (&session, &schedule);
|
||||
DES_ecb_encrypt (times.data,
|
||||
times.data,
|
||||
&schedule,
|
||||
DES_DECRYPT);
|
||||
memset (&schedule, 0, sizeof(schedule));
|
||||
memset (&session, 0, sizeof(session));
|
||||
|
||||
/* and extract them */
|
||||
{
|
||||
krb5_storage *tsp;
|
||||
int32_t tmp;
|
||||
|
||||
tsp = krb5_storage_from_mem (times.data, times.length);
|
||||
krb5_ret_int32 (tsp, &tmp);
|
||||
start_time = tmp;
|
||||
krb5_ret_int32 (tsp, &tmp);
|
||||
end_time = tmp;
|
||||
krb5_storage_free (tsp);
|
||||
}
|
||||
|
||||
/* life */
|
||||
max_life = end_time - kdc_time;
|
||||
/* end_time - kdc_time can sometimes be non-positive due to slight
|
||||
time skew between client and server. Let's make sure it is postive */
|
||||
if(max_life < 1)
|
||||
max_life = 1;
|
||||
if (krbtgt_entry->entry.max_life)
|
||||
max_life = min(max_life, *krbtgt_entry->entry.max_life);
|
||||
if (server_entry->entry.max_life)
|
||||
max_life = min(max_life, *server_entry->entry.max_life);
|
||||
/* if this is a cross realm request, the client_entry will likely
|
||||
be NULL */
|
||||
if (client_entry && client_entry->entry.max_life)
|
||||
max_life = min(max_life, *client_entry->entry.max_life);
|
||||
|
||||
life = _krb5_krb_time_to_life(kdc_time, kdc_time + max_life);
|
||||
|
||||
create_reply_ticket (context,
|
||||
hdr, skey,
|
||||
ad.pname, ad.pinst, ad.prealm,
|
||||
addr, life, server_entry->entry.kvno,
|
||||
max_seq_len,
|
||||
name, instance,
|
||||
0, "gtkt",
|
||||
&ad.session, reply);
|
||||
|
||||
out:
|
||||
_krb5_krb_free_auth_data(context, &ad);
|
||||
if (aticket.length) {
|
||||
memset (aticket.data, 0, aticket.length);
|
||||
krb5_data_free (&aticket);
|
||||
}
|
||||
if (times.length) {
|
||||
memset (times.data, 0, times.length);
|
||||
krb5_data_free (×);
|
||||
}
|
||||
if (auth_domain)
|
||||
free (auth_domain);
|
||||
if (name)
|
||||
free (name);
|
||||
if (instance)
|
||||
free (instance);
|
||||
if (krbtgt_entry)
|
||||
_kdc_free_ent (context, krbtgt_entry);
|
||||
if (server_entry)
|
||||
_kdc_free_ent (context, server_entry);
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
_kdc_do_kaserver(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
unsigned char *buf,
|
||||
size_t len,
|
||||
krb5_data *reply,
|
||||
const char *from,
|
||||
struct sockaddr_in *addr)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
struct rx_header hdr;
|
||||
uint32_t op;
|
||||
krb5_storage *sp;
|
||||
|
||||
if (len < RX_HEADER_SIZE)
|
||||
return -1;
|
||||
sp = krb5_storage_from_mem (buf, len);
|
||||
|
||||
ret = decode_rx_header (sp, &hdr);
|
||||
if (ret)
|
||||
goto out;
|
||||
buf += RX_HEADER_SIZE;
|
||||
len -= RX_HEADER_SIZE;
|
||||
|
||||
switch (hdr.type) {
|
||||
case HT_DATA :
|
||||
break;
|
||||
case HT_ACK :
|
||||
case HT_BUSY :
|
||||
case HT_ABORT :
|
||||
case HT_ACKALL :
|
||||
case HT_CHAL :
|
||||
case HT_RESP :
|
||||
case HT_DEBUG :
|
||||
default:
|
||||
/* drop */
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
if (hdr.serviceid != KA_AUTHENTICATION_SERVICE
|
||||
&& hdr.serviceid != KA_TICKET_GRANTING_SERVICE) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = krb5_ret_uint32(sp, &op);
|
||||
if (ret)
|
||||
goto out;
|
||||
switch (op) {
|
||||
case AUTHENTICATE :
|
||||
case AUTHENTICATE_V2 :
|
||||
do_authenticate (context, config, &hdr, sp, addr, from, reply);
|
||||
break;
|
||||
case GETTICKET :
|
||||
do_getticket (context, config, &hdr, sp, addr, from, reply);
|
||||
break;
|
||||
case AUTHENTICATE_OLD :
|
||||
case CHANGEPASSWORD :
|
||||
case GETTICKET_OLD :
|
||||
case SETPASSWORD :
|
||||
case SETFIELDS :
|
||||
case CREATEUSER :
|
||||
case DELETEUSER :
|
||||
case GETENTRY :
|
||||
case LISTENTRY :
|
||||
case GETSTATS :
|
||||
case DEBUG :
|
||||
case GETPASSWORD :
|
||||
case GETRANDOMKEY :
|
||||
default :
|
||||
make_error_reply (&hdr, RXGEN_OPCODE, reply);
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
krb5_storage_free (sp);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
/* This is a generated file */
|
||||
#ifndef __kdc_private_h__
|
||||
#define __kdc_private_h__
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
krb5_error_code
|
||||
_kdc_add_KRB5SignedPath (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
hdb_entry_ex */*krbtgt*/,
|
||||
krb5_enctype /*enctype*/,
|
||||
krb5_const_principal /*server*/,
|
||||
KRB5SignedPathPrincipals */*principals*/,
|
||||
EncTicketPart */*tkt*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_as_rep (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
KDC_REQ */*req*/,
|
||||
const krb5_data */*req_buffer*/,
|
||||
krb5_data */*reply*/,
|
||||
const char */*from*/,
|
||||
struct sockaddr */*from_addr*/,
|
||||
int /*datagram_reply*/);
|
||||
|
||||
krb5_boolean
|
||||
_kdc_check_addresses (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
HostAddresses */*addresses*/,
|
||||
const struct sockaddr */*from*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_check_flags (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
hdb_entry_ex */*client_ex*/,
|
||||
const char */*client_name*/,
|
||||
hdb_entry_ex */*server_ex*/,
|
||||
const char */*server_name*/,
|
||||
krb5_boolean /*is_as_req*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_db_fetch (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
krb5_const_principal /*principal*/,
|
||||
unsigned /*flags*/,
|
||||
HDB **/*db*/,
|
||||
hdb_entry_ex **/*h*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_db_fetch4 (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
const char */*name*/,
|
||||
const char */*instance*/,
|
||||
const char */*realm*/,
|
||||
unsigned /*flags*/,
|
||||
hdb_entry_ex **/*ent*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_do_524 (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
const Ticket */*t*/,
|
||||
krb5_data */*reply*/,
|
||||
const char */*from*/,
|
||||
struct sockaddr */*addr*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_do_digest (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
const DigestREQ */*req*/,
|
||||
krb5_data */*reply*/,
|
||||
const char */*from*/,
|
||||
struct sockaddr */*addr*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_do_kaserver (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
unsigned char */*buf*/,
|
||||
size_t /*len*/,
|
||||
krb5_data */*reply*/,
|
||||
const char */*from*/,
|
||||
struct sockaddr_in */*addr*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_do_version4 (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
unsigned char */*buf*/,
|
||||
size_t /*len*/,
|
||||
krb5_data */*reply*/,
|
||||
const char */*from*/,
|
||||
struct sockaddr_in */*addr*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_encode_reply (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
KDC_REP */*rep*/,
|
||||
const EncTicketPart */*et*/,
|
||||
EncKDCRepPart */*ek*/,
|
||||
krb5_enctype /*etype*/,
|
||||
int /*skvno*/,
|
||||
const EncryptionKey */*skey*/,
|
||||
int /*ckvno*/,
|
||||
const EncryptionKey */*ckey*/,
|
||||
const char **/*e_text*/,
|
||||
krb5_data */*reply*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_encode_v4_ticket (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
void */*buf*/,
|
||||
size_t /*len*/,
|
||||
const EncTicketPart */*et*/,
|
||||
const PrincipalName */*service*/,
|
||||
size_t */*size*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_find_etype (
|
||||
krb5_context /*context*/,
|
||||
const hdb_entry_ex */*princ*/,
|
||||
krb5_enctype */*etypes*/,
|
||||
unsigned /*len*/,
|
||||
Key **/*ret_key*/,
|
||||
krb5_enctype */*ret_etype*/);
|
||||
|
||||
PA_DATA*
|
||||
_kdc_find_padata (
|
||||
KDC_REQ */*req*/,
|
||||
int */*start*/,
|
||||
int /*type*/);
|
||||
|
||||
void
|
||||
_kdc_fix_time (time_t **/*t*/);
|
||||
|
||||
void
|
||||
_kdc_free_ent (
|
||||
krb5_context /*context*/,
|
||||
hdb_entry_ex */*ent*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_get_des_key (
|
||||
krb5_context /*context*/,
|
||||
hdb_entry_ex */*principal*/,
|
||||
krb5_boolean /*is_server*/,
|
||||
krb5_boolean /*prefer_afs_key*/,
|
||||
Key **/*ret_key*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_get_preferred_key (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
hdb_entry_ex */*h*/,
|
||||
const char */*name*/,
|
||||
krb5_enctype */*enctype*/,
|
||||
Key **/*key*/);
|
||||
|
||||
void
|
||||
_kdc_log_timestamp (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
const char */*type*/,
|
||||
KerberosTime /*authtime*/,
|
||||
KerberosTime */*starttime*/,
|
||||
KerberosTime /*endtime*/,
|
||||
KerberosTime */*renew_till*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_make_anonymous_principalname (PrincipalName */*pn*/);
|
||||
|
||||
int
|
||||
_kdc_maybe_version4 (
|
||||
unsigned char */*buf*/,
|
||||
int /*len*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_pk_check_client (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
const hdb_entry_ex */*client*/,
|
||||
pk_client_params */*client_params*/,
|
||||
char **/*subject_name*/);
|
||||
|
||||
void
|
||||
_kdc_pk_free_client_param (
|
||||
krb5_context /*context*/,
|
||||
pk_client_params */*client_params*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_pk_initialize (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
const char */*user_id*/,
|
||||
const char */*anchors*/,
|
||||
char **/*pool*/,
|
||||
char **/*revoke_list*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_pk_mk_pa_reply (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
pk_client_params */*client_params*/,
|
||||
const hdb_entry_ex */*client*/,
|
||||
const KDC_REQ */*req*/,
|
||||
const krb5_data */*req_buffer*/,
|
||||
krb5_keyblock **/*reply_key*/,
|
||||
METHOD_DATA */*md*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_pk_rd_padata (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
KDC_REQ */*req*/,
|
||||
PA_DATA */*pa*/,
|
||||
pk_client_params **/*ret_params*/);
|
||||
|
||||
krb5_error_code
|
||||
_kdc_tgs_rep (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
KDC_REQ */*req*/,
|
||||
krb5_data */*data*/,
|
||||
const char */*from*/,
|
||||
struct sockaddr */*from_addr*/);
|
||||
|
||||
#endif /* __kdc_private_h__ */
|
||||
@@ -0,0 +1,70 @@
|
||||
/* This is a generated file */
|
||||
#ifndef __kdc_protos_h__
|
||||
#define __kdc_protos_h__
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void
|
||||
kdc_log (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
int /*level*/,
|
||||
const char */*fmt*/,
|
||||
...);
|
||||
|
||||
char*
|
||||
kdc_log_msg (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
int /*level*/,
|
||||
const char */*fmt*/,
|
||||
...);
|
||||
|
||||
char*
|
||||
kdc_log_msg_va (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
int /*level*/,
|
||||
const char */*fmt*/,
|
||||
va_list /*ap*/);
|
||||
|
||||
void
|
||||
kdc_openlog (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/);
|
||||
|
||||
void
|
||||
krb5_kdc_default_config (krb5_kdc_configuration */*config*/);
|
||||
|
||||
int
|
||||
krb5_kdc_process_krb5_request (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
unsigned char */*buf*/,
|
||||
size_t /*len*/,
|
||||
krb5_data */*reply*/,
|
||||
const char */*from*/,
|
||||
struct sockaddr */*addr*/,
|
||||
int /*datagram_reply*/);
|
||||
|
||||
int
|
||||
krb5_kdc_process_request (
|
||||
krb5_context /*context*/,
|
||||
krb5_kdc_configuration */*config*/,
|
||||
unsigned char */*buf*/,
|
||||
size_t /*len*/,
|
||||
krb5_data */*reply*/,
|
||||
krb5_boolean */*prependlength*/,
|
||||
const char */*from*/,
|
||||
struct sockaddr */*addr*/,
|
||||
int /*datagram_reply*/);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __kdc_protos_h__ */
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2003 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
*
|
||||
* Copyright (c) 2005 Andrew Bartlett <abartlet@samba.org>
|
||||
*
|
||||
* 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: kdc.h,v 1.9 2006/10/09 15:34:07 lha Exp $
|
||||
*/
|
||||
|
||||
#ifndef __KDC_H__
|
||||
#define __KDC_H__
|
||||
|
||||
#include <krb5.h>
|
||||
|
||||
enum krb5_kdc_trpolicy {
|
||||
TRPOLICY_ALWAYS_CHECK,
|
||||
TRPOLICY_ALLOW_PER_PRINCIPAL,
|
||||
TRPOLICY_ALWAYS_HONOUR_REQUEST
|
||||
};
|
||||
|
||||
typedef struct krb5_kdc_configuration {
|
||||
krb5_boolean require_preauth; /* require preauth for all principals */
|
||||
time_t kdc_warn_pwexpire; /* time before expiration to print a warning */
|
||||
|
||||
struct HDB **db;
|
||||
int num_db;
|
||||
|
||||
krb5_boolean encode_as_rep_as_tgs_rep; /* bug compatibility */
|
||||
|
||||
krb5_boolean check_ticket_addresses;
|
||||
krb5_boolean allow_null_ticket_addresses;
|
||||
krb5_boolean allow_anonymous;
|
||||
enum krb5_kdc_trpolicy trpolicy;
|
||||
|
||||
char *v4_realm;
|
||||
krb5_boolean enable_v4;
|
||||
krb5_boolean enable_v4_cross_realm;
|
||||
krb5_boolean enable_v4_per_principal;
|
||||
|
||||
krb5_boolean enable_kaserver;
|
||||
|
||||
krb5_boolean enable_524;
|
||||
|
||||
krb5_boolean enable_pkinit;
|
||||
krb5_boolean enable_pkinit_princ_in_cert;
|
||||
char *pkinit_kdc_ocsp_file;
|
||||
|
||||
krb5_log_facility *logf;
|
||||
|
||||
int pkinit_dh_min_bits;
|
||||
|
||||
int enable_digest;
|
||||
size_t max_datagram_reply_length;
|
||||
|
||||
} krb5_kdc_configuration;
|
||||
|
||||
#include <kdc-protos.h>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: kdc_locl.h,v 1.74 2005/12/12 12:23:33 lha Exp $
|
||||
*/
|
||||
|
||||
#ifndef __KDC_LOCL_H__
|
||||
#define __KDC_LOCL_H__
|
||||
|
||||
#include "headers.h"
|
||||
#include "kdc.h"
|
||||
|
||||
typedef struct pk_client_params pk_client_params;
|
||||
#include <kdc-private.h>
|
||||
|
||||
extern sig_atomic_t exit_flag;
|
||||
extern size_t max_request;
|
||||
extern const char *port_str;
|
||||
extern krb5_addresses explicit_addresses;
|
||||
|
||||
extern int enable_http;
|
||||
|
||||
#define DETACH_IS_DEFAULT FALSE
|
||||
|
||||
extern int detach_from_console;
|
||||
|
||||
#define _PATH_KDC_CONF HDB_DB_DIR "/kdc.conf"
|
||||
#define DEFAULT_LOG_DEST "0-1/FILE:" HDB_DB_DIR "/kdc.log"
|
||||
|
||||
extern struct timeval _kdc_now;
|
||||
#define kdc_time (_kdc_now.tv_sec)
|
||||
|
||||
void
|
||||
loop(krb5_context context, krb5_kdc_configuration *config);
|
||||
|
||||
krb5_kdc_configuration *
|
||||
configure(krb5_context context, int argc, char **argv);
|
||||
|
||||
#endif /* __KDC_LOCL_H__ */
|
||||
@@ -0,0 +1,808 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 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.
|
||||
*/
|
||||
|
||||
#include "kdc_locl.h"
|
||||
|
||||
#include <krb5-v4compat.h>
|
||||
|
||||
RCSID("$Id: kerberos4.c,v 1.63 2006/10/08 13:43:27 lha Exp $");
|
||||
|
||||
#ifndef swap32
|
||||
static uint32_t
|
||||
swap32(uint32_t x)
|
||||
{
|
||||
return ((x << 24) & 0xff000000) |
|
||||
((x << 8) & 0xff0000) |
|
||||
((x >> 8) & 0xff00) |
|
||||
((x >> 24) & 0xff);
|
||||
}
|
||||
#endif /* swap32 */
|
||||
|
||||
int
|
||||
_kdc_maybe_version4(unsigned char *buf, int len)
|
||||
{
|
||||
return len > 0 && *buf == 4;
|
||||
}
|
||||
|
||||
static void
|
||||
make_err_reply(krb5_context context, krb5_data *reply,
|
||||
int code, const char *msg)
|
||||
{
|
||||
_krb5_krb_cr_err_reply(context, "", "", "",
|
||||
kdc_time, code, msg, reply);
|
||||
}
|
||||
|
||||
struct valid_princ_ctx {
|
||||
krb5_kdc_configuration *config;
|
||||
unsigned flags;
|
||||
};
|
||||
|
||||
static krb5_boolean
|
||||
valid_princ(krb5_context context,
|
||||
void *funcctx,
|
||||
krb5_principal princ)
|
||||
{
|
||||
struct valid_princ_ctx *ctx = funcctx;
|
||||
krb5_error_code ret;
|
||||
char *s;
|
||||
hdb_entry_ex *ent;
|
||||
|
||||
ret = krb5_unparse_name(context, princ, &s);
|
||||
if (ret)
|
||||
return FALSE;
|
||||
ret = _kdc_db_fetch(context, ctx->config, princ, ctx->flags, NULL, &ent);
|
||||
if (ret) {
|
||||
kdc_log(context, ctx->config, 7, "Lookup %s failed: %s", s,
|
||||
krb5_get_err_text (context, ret));
|
||||
free(s);
|
||||
return FALSE;
|
||||
}
|
||||
kdc_log(context, ctx->config, 7, "Lookup %s succeeded", s);
|
||||
free(s);
|
||||
_kdc_free_ent(context, ent);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
_kdc_db_fetch4(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
const char *name, const char *instance, const char *realm,
|
||||
unsigned flags,
|
||||
hdb_entry_ex **ent)
|
||||
{
|
||||
krb5_principal p;
|
||||
krb5_error_code ret;
|
||||
struct valid_princ_ctx ctx;
|
||||
|
||||
ctx.config = config;
|
||||
ctx.flags = flags;
|
||||
|
||||
ret = krb5_425_conv_principal_ext2(context, name, instance, realm,
|
||||
valid_princ, &ctx, 0, &p);
|
||||
if(ret)
|
||||
return ret;
|
||||
ret = _kdc_db_fetch(context, config, p, flags, NULL, ent);
|
||||
krb5_free_principal(context, p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define RCHECK(X, L) if(X){make_err_reply(context, reply, KFAILURE, "Packet too short"); goto L;}
|
||||
|
||||
/*
|
||||
* Process the v4 request in `buf, len' (received from `addr'
|
||||
* (with string `from').
|
||||
* Return an error code and a reply in `reply'.
|
||||
*/
|
||||
|
||||
krb5_error_code
|
||||
_kdc_do_version4(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
unsigned char *buf,
|
||||
size_t len,
|
||||
krb5_data *reply,
|
||||
const char *from,
|
||||
struct sockaddr_in *addr)
|
||||
{
|
||||
krb5_storage *sp;
|
||||
krb5_error_code ret;
|
||||
hdb_entry_ex *client = NULL, *server = NULL;
|
||||
Key *ckey, *skey;
|
||||
int8_t pvno;
|
||||
int8_t msg_type;
|
||||
int lsb;
|
||||
char *name = NULL, *inst = NULL, *realm = NULL;
|
||||
char *sname = NULL, *sinst = NULL;
|
||||
int32_t req_time;
|
||||
time_t max_life;
|
||||
uint8_t life;
|
||||
char client_name[256];
|
||||
char server_name[256];
|
||||
|
||||
if(!config->enable_v4) {
|
||||
kdc_log(context, config, 0,
|
||||
"Rejected version 4 request from %s", from);
|
||||
make_err_reply(context, reply, KDC_GEN_ERR, "function not enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
sp = krb5_storage_from_mem(buf, len);
|
||||
RCHECK(krb5_ret_int8(sp, &pvno), out);
|
||||
if(pvno != 4){
|
||||
kdc_log(context, config, 0,
|
||||
"Protocol version mismatch (krb4) (%d)", pvno);
|
||||
make_err_reply(context, reply, KDC_PKT_VER, "protocol mismatch");
|
||||
goto out;
|
||||
}
|
||||
RCHECK(krb5_ret_int8(sp, &msg_type), out);
|
||||
lsb = msg_type & 1;
|
||||
msg_type &= ~1;
|
||||
switch(msg_type){
|
||||
case AUTH_MSG_KDC_REQUEST: {
|
||||
krb5_data ticket, cipher;
|
||||
krb5_keyblock session;
|
||||
|
||||
krb5_data_zero(&ticket);
|
||||
krb5_data_zero(&cipher);
|
||||
|
||||
RCHECK(krb5_ret_stringz(sp, &name), out1);
|
||||
RCHECK(krb5_ret_stringz(sp, &inst), out1);
|
||||
RCHECK(krb5_ret_stringz(sp, &realm), out1);
|
||||
RCHECK(krb5_ret_int32(sp, &req_time), out1);
|
||||
if(lsb)
|
||||
req_time = swap32(req_time);
|
||||
RCHECK(krb5_ret_uint8(sp, &life), out1);
|
||||
RCHECK(krb5_ret_stringz(sp, &sname), out1);
|
||||
RCHECK(krb5_ret_stringz(sp, &sinst), out1);
|
||||
snprintf (client_name, sizeof(client_name),
|
||||
"%s.%s@%s", name, inst, realm);
|
||||
snprintf (server_name, sizeof(server_name),
|
||||
"%s.%s@%s", sname, sinst, config->v4_realm);
|
||||
|
||||
kdc_log(context, config, 0, "AS-REQ (krb4) %s from %s for %s",
|
||||
client_name, from, server_name);
|
||||
|
||||
ret = _kdc_db_fetch4(context, config, name, inst, realm,
|
||||
HDB_F_GET_CLIENT, &client);
|
||||
if(ret) {
|
||||
kdc_log(context, config, 0, "Client not found in database: %s: %s",
|
||||
client_name, krb5_get_err_text(context, ret));
|
||||
make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN,
|
||||
"principal unknown");
|
||||
goto out1;
|
||||
}
|
||||
ret = _kdc_db_fetch4(context, config, sname, sinst, config->v4_realm,
|
||||
HDB_F_GET_SERVER, &server);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0, "Server not found in database: %s: %s",
|
||||
server_name, krb5_get_err_text(context, ret));
|
||||
make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN,
|
||||
"principal unknown");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
ret = _kdc_check_flags (context, config,
|
||||
client, client_name,
|
||||
server, server_name,
|
||||
TRUE);
|
||||
if (ret) {
|
||||
/* good error code? */
|
||||
make_err_reply(context, reply, KERB_ERR_NAME_EXP,
|
||||
"operation not allowed");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
if (config->enable_v4_per_principal &&
|
||||
client->entry.flags.allow_kerberos4 == 0)
|
||||
{
|
||||
kdc_log(context, config, 0,
|
||||
"Per principal Kerberos 4 flag not turned on for %s",
|
||||
client_name);
|
||||
make_err_reply(context, reply, KERB_ERR_NULL_KEY,
|
||||
"allow kerberos4 flag required");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
/*
|
||||
* There's no way to do pre-authentication in v4 and thus no
|
||||
* good error code to return if preauthentication is required.
|
||||
*/
|
||||
|
||||
if (config->require_preauth
|
||||
|| client->entry.flags.require_preauth
|
||||
|| server->entry.flags.require_preauth) {
|
||||
kdc_log(context, config, 0,
|
||||
"Pre-authentication required for v4-request: "
|
||||
"%s for %s",
|
||||
client_name, server_name);
|
||||
make_err_reply(context, reply, KERB_ERR_NULL_KEY,
|
||||
"preauth required");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
ret = _kdc_get_des_key(context, client, FALSE, FALSE, &ckey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0, "no suitable DES key for client");
|
||||
make_err_reply(context, reply, KDC_NULL_KEY,
|
||||
"no suitable DES key for client");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* this is not necessary with the new code in libkrb */
|
||||
/* find a properly salted key */
|
||||
while(ckey->salt == NULL || ckey->salt->salt.length != 0)
|
||||
ret = hdb_next_keytype2key(context, &client->entry, KEYTYPE_DES, &ckey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0, "No version-4 salted key in database -- %s.%s@%s",
|
||||
name, inst, realm);
|
||||
make_err_reply(context, reply, KDC_NULL_KEY,
|
||||
"No version-4 salted key in database");
|
||||
goto out1;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0, "no suitable DES key for server");
|
||||
/* XXX */
|
||||
make_err_reply(context, reply, KDC_NULL_KEY,
|
||||
"no suitable DES key for server");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
max_life = _krb5_krb_life_to_time(0, life);
|
||||
if(client->entry.max_life)
|
||||
max_life = min(max_life, *client->entry.max_life);
|
||||
if(server->entry.max_life)
|
||||
max_life = min(max_life, *server->entry.max_life);
|
||||
|
||||
life = krb_time_to_life(kdc_time, kdc_time + max_life);
|
||||
|
||||
ret = krb5_generate_random_keyblock(context,
|
||||
ETYPE_DES_PCBC_NONE,
|
||||
&session);
|
||||
if (ret) {
|
||||
make_err_reply(context, reply, KFAILURE,
|
||||
"Not enough random i KDC");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
ret = _krb5_krb_create_ticket(context,
|
||||
0,
|
||||
name,
|
||||
inst,
|
||||
config->v4_realm,
|
||||
addr->sin_addr.s_addr,
|
||||
&session,
|
||||
life,
|
||||
kdc_time,
|
||||
sname,
|
||||
sinst,
|
||||
&skey->key,
|
||||
&ticket);
|
||||
if (ret) {
|
||||
krb5_free_keyblock_contents(context, &session);
|
||||
make_err_reply(context, reply, KFAILURE,
|
||||
"failed to create v4 ticket");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
ret = _krb5_krb_create_ciph(context,
|
||||
&session,
|
||||
sname,
|
||||
sinst,
|
||||
config->v4_realm,
|
||||
life,
|
||||
server->entry.kvno % 255,
|
||||
&ticket,
|
||||
kdc_time,
|
||||
&ckey->key,
|
||||
&cipher);
|
||||
krb5_free_keyblock_contents(context, &session);
|
||||
krb5_data_free(&ticket);
|
||||
if (ret) {
|
||||
make_err_reply(context, reply, KFAILURE,
|
||||
"Failed to create v4 cipher");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
ret = _krb5_krb_create_auth_reply(context,
|
||||
name,
|
||||
inst,
|
||||
realm,
|
||||
req_time,
|
||||
0,
|
||||
client->entry.pw_end ? *client->entry.pw_end : 0,
|
||||
client->entry.kvno % 256,
|
||||
&cipher,
|
||||
reply);
|
||||
krb5_data_free(&cipher);
|
||||
|
||||
out1:
|
||||
break;
|
||||
}
|
||||
case AUTH_MSG_APPL_REQUEST: {
|
||||
struct _krb5_krb_auth_data ad;
|
||||
int8_t kvno;
|
||||
int8_t ticket_len;
|
||||
int8_t req_len;
|
||||
krb5_data auth;
|
||||
int32_t address;
|
||||
size_t pos;
|
||||
krb5_principal tgt_princ = NULL;
|
||||
hdb_entry_ex *tgt = NULL;
|
||||
Key *tkey;
|
||||
time_t max_end, actual_end, issue_time;
|
||||
|
||||
memset(&ad, 0, sizeof(ad));
|
||||
krb5_data_zero(&auth);
|
||||
|
||||
RCHECK(krb5_ret_int8(sp, &kvno), out2);
|
||||
RCHECK(krb5_ret_stringz(sp, &realm), out2);
|
||||
|
||||
ret = krb5_425_conv_principal(context, "krbtgt", realm,
|
||||
config->v4_realm,
|
||||
&tgt_princ);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0,
|
||||
"Converting krbtgt principal (krb4): %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
make_err_reply(context, reply, KFAILURE,
|
||||
"Failed to convert v4 principal (krbtgt)");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ret = _kdc_db_fetch(context, config, tgt_princ,
|
||||
HDB_F_GET_KRBTGT, NULL, &tgt);
|
||||
if(ret){
|
||||
char *s;
|
||||
s = kdc_log_msg(context, config, 0, "Ticket-granting ticket not "
|
||||
"found in database (krb4): krbtgt.%s@%s: %s",
|
||||
realm, config->v4_realm,
|
||||
krb5_get_err_text(context, ret));
|
||||
make_err_reply(context, reply, KFAILURE, s);
|
||||
free(s);
|
||||
goto out2;
|
||||
}
|
||||
|
||||
if(tgt->entry.kvno % 256 != kvno){
|
||||
kdc_log(context, config, 0,
|
||||
"tgs-req (krb4) with old kvno %d (current %d) for "
|
||||
"krbtgt.%s@%s", kvno, tgt->entry.kvno % 256,
|
||||
realm, config->v4_realm);
|
||||
make_err_reply(context, reply, KDC_AUTH_EXP,
|
||||
"old krbtgt kvno used");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ret = _kdc_get_des_key(context, tgt, TRUE, FALSE, &tkey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0,
|
||||
"no suitable DES key for krbtgt (krb4)");
|
||||
/* XXX */
|
||||
make_err_reply(context, reply, KDC_NULL_KEY,
|
||||
"no suitable DES key for krbtgt");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
RCHECK(krb5_ret_int8(sp, &ticket_len), out2);
|
||||
RCHECK(krb5_ret_int8(sp, &req_len), out2);
|
||||
|
||||
pos = krb5_storage_seek(sp, ticket_len + req_len, SEEK_CUR);
|
||||
|
||||
auth.data = buf;
|
||||
auth.length = pos;
|
||||
|
||||
if (config->check_ticket_addresses)
|
||||
address = addr->sin_addr.s_addr;
|
||||
else
|
||||
address = 0;
|
||||
|
||||
ret = _krb5_krb_rd_req(context, &auth, "krbtgt", realm,
|
||||
config->v4_realm,
|
||||
address, &tkey->key, &ad);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0, "krb_rd_req: %d", ret);
|
||||
make_err_reply(context, reply, ret, "failed to parse request");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
RCHECK(krb5_ret_int32(sp, &req_time), out2);
|
||||
if(lsb)
|
||||
req_time = swap32(req_time);
|
||||
RCHECK(krb5_ret_uint8(sp, &life), out2);
|
||||
RCHECK(krb5_ret_stringz(sp, &sname), out2);
|
||||
RCHECK(krb5_ret_stringz(sp, &sinst), out2);
|
||||
snprintf (server_name, sizeof(server_name),
|
||||
"%s.%s@%s",
|
||||
sname, sinst, config->v4_realm);
|
||||
snprintf (client_name, sizeof(client_name),
|
||||
"%s.%s@%s",
|
||||
ad.pname, ad.pinst, ad.prealm);
|
||||
|
||||
kdc_log(context, config, 0, "TGS-REQ (krb4) %s from %s for %s",
|
||||
client_name, from, server_name);
|
||||
|
||||
if(strcmp(ad.prealm, realm)){
|
||||
kdc_log(context, config, 0,
|
||||
"Can't hop realms (krb4) %s -> %s", realm, ad.prealm);
|
||||
make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN,
|
||||
"Can't hop realms");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
if (!config->enable_v4_cross_realm && strcmp(realm, config->v4_realm) != 0) {
|
||||
kdc_log(context, config, 0,
|
||||
"krb4 Cross-realm %s -> %s disabled",
|
||||
realm, config->v4_realm);
|
||||
make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN,
|
||||
"Can't hop realms");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
if(strcmp(sname, "changepw") == 0){
|
||||
kdc_log(context, config, 0,
|
||||
"Bad request for changepw ticket (krb4)");
|
||||
make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN,
|
||||
"Can't authorize password change based on TGT");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ret = _kdc_db_fetch4(context, config, ad.pname, ad.pinst, ad.prealm,
|
||||
HDB_F_GET_CLIENT, &client);
|
||||
if(ret && ret != HDB_ERR_NOENTRY) {
|
||||
char *s;
|
||||
s = kdc_log_msg(context, config, 0,
|
||||
"Client not found in database: (krb4) %s: %s",
|
||||
client_name, krb5_get_err_text(context, ret));
|
||||
make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, s);
|
||||
free(s);
|
||||
goto out2;
|
||||
}
|
||||
if (client == NULL && strcmp(ad.prealm, config->v4_realm) == 0) {
|
||||
char *s;
|
||||
s = kdc_log_msg(context, config, 0,
|
||||
"Local client not found in database: (krb4) "
|
||||
"%s", client_name);
|
||||
make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, s);
|
||||
free(s);
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ret = _kdc_db_fetch4(context, config, sname, sinst, config->v4_realm,
|
||||
HDB_F_GET_SERVER, &server);
|
||||
if(ret){
|
||||
char *s;
|
||||
s = kdc_log_msg(context, config, 0,
|
||||
"Server not found in database (krb4): %s: %s",
|
||||
server_name, krb5_get_err_text(context, ret));
|
||||
make_err_reply(context, reply, KERB_ERR_PRINCIPAL_UNKNOWN, s);
|
||||
free(s);
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ret = _kdc_check_flags (context, config,
|
||||
client, client_name,
|
||||
server, server_name,
|
||||
FALSE);
|
||||
if (ret) {
|
||||
/* good error code? */
|
||||
make_err_reply(context, reply, KERB_ERR_NAME_EXP,
|
||||
"operation not allowed");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
|
||||
if(ret){
|
||||
kdc_log(context, config, 0,
|
||||
"no suitable DES key for server (krb4)");
|
||||
/* XXX */
|
||||
make_err_reply(context, reply, KDC_NULL_KEY,
|
||||
"no suitable DES key for server");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
max_end = _krb5_krb_life_to_time(ad.time_sec, ad.life);
|
||||
max_end = min(max_end, _krb5_krb_life_to_time(kdc_time, life));
|
||||
if(server->entry.max_life)
|
||||
max_end = min(max_end, kdc_time + *server->entry.max_life);
|
||||
if(client && client->entry.max_life)
|
||||
max_end = min(max_end, kdc_time + *client->entry.max_life);
|
||||
life = min(life, krb_time_to_life(kdc_time, max_end));
|
||||
|
||||
issue_time = kdc_time;
|
||||
actual_end = _krb5_krb_life_to_time(issue_time, life);
|
||||
while (actual_end > max_end && life > 1) {
|
||||
/* move them into the next earlier lifetime bracket */
|
||||
life--;
|
||||
actual_end = _krb5_krb_life_to_time(issue_time, life);
|
||||
}
|
||||
if (actual_end > max_end) {
|
||||
/* if life <= 1 and it's still too long, backdate the ticket */
|
||||
issue_time -= actual_end - max_end;
|
||||
}
|
||||
|
||||
{
|
||||
krb5_data ticket, cipher;
|
||||
krb5_keyblock session;
|
||||
|
||||
krb5_data_zero(&ticket);
|
||||
krb5_data_zero(&cipher);
|
||||
|
||||
ret = krb5_generate_random_keyblock(context,
|
||||
ETYPE_DES_PCBC_NONE,
|
||||
&session);
|
||||
if (ret) {
|
||||
make_err_reply(context, reply, KFAILURE,
|
||||
"Not enough random i KDC");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ret = _krb5_krb_create_ticket(context,
|
||||
0,
|
||||
ad.pname,
|
||||
ad.pinst,
|
||||
ad.prealm,
|
||||
addr->sin_addr.s_addr,
|
||||
&session,
|
||||
life,
|
||||
issue_time,
|
||||
sname,
|
||||
sinst,
|
||||
&skey->key,
|
||||
&ticket);
|
||||
if (ret) {
|
||||
krb5_free_keyblock_contents(context, &session);
|
||||
make_err_reply(context, reply, KFAILURE,
|
||||
"failed to create v4 ticket");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ret = _krb5_krb_create_ciph(context,
|
||||
&session,
|
||||
sname,
|
||||
sinst,
|
||||
config->v4_realm,
|
||||
life,
|
||||
server->entry.kvno % 255,
|
||||
&ticket,
|
||||
issue_time,
|
||||
&ad.session,
|
||||
&cipher);
|
||||
krb5_free_keyblock_contents(context, &session);
|
||||
if (ret) {
|
||||
make_err_reply(context, reply, KFAILURE,
|
||||
"failed to create v4 cipher");
|
||||
goto out2;
|
||||
}
|
||||
|
||||
ret = _krb5_krb_create_auth_reply(context,
|
||||
ad.pname,
|
||||
ad.pinst,
|
||||
ad.prealm,
|
||||
req_time,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&cipher,
|
||||
reply);
|
||||
krb5_data_free(&cipher);
|
||||
}
|
||||
out2:
|
||||
_krb5_krb_free_auth_data(context, &ad);
|
||||
if(tgt_princ)
|
||||
krb5_free_principal(context, tgt_princ);
|
||||
if(tgt)
|
||||
_kdc_free_ent(context, tgt);
|
||||
break;
|
||||
}
|
||||
case AUTH_MSG_ERR_REPLY:
|
||||
break;
|
||||
default:
|
||||
kdc_log(context, config, 0, "Unknown message type (krb4): %d from %s",
|
||||
msg_type, from);
|
||||
|
||||
make_err_reply(context, reply, KFAILURE, "Unknown message type");
|
||||
}
|
||||
out:
|
||||
if(name)
|
||||
free(name);
|
||||
if(inst)
|
||||
free(inst);
|
||||
if(realm)
|
||||
free(realm);
|
||||
if(sname)
|
||||
free(sname);
|
||||
if(sinst)
|
||||
free(sinst);
|
||||
if(client)
|
||||
_kdc_free_ent(context, client);
|
||||
if(server)
|
||||
_kdc_free_ent(context, server);
|
||||
krb5_storage_free(sp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
_kdc_encode_v4_ticket(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
void *buf, size_t len, const EncTicketPart *et,
|
||||
const PrincipalName *service, size_t *size)
|
||||
{
|
||||
krb5_storage *sp;
|
||||
krb5_error_code ret;
|
||||
char name[40], inst[40], realm[40];
|
||||
char sname[40], sinst[40];
|
||||
|
||||
{
|
||||
krb5_principal princ;
|
||||
_krb5_principalname2krb5_principal(context,
|
||||
&princ,
|
||||
*service,
|
||||
et->crealm);
|
||||
ret = krb5_524_conv_principal(context,
|
||||
princ,
|
||||
sname,
|
||||
sinst,
|
||||
realm);
|
||||
krb5_free_principal(context, princ);
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
_krb5_principalname2krb5_principal(context,
|
||||
&princ,
|
||||
et->cname,
|
||||
et->crealm);
|
||||
|
||||
ret = krb5_524_conv_principal(context,
|
||||
princ,
|
||||
name,
|
||||
inst,
|
||||
realm);
|
||||
krb5_free_principal(context, princ);
|
||||
}
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
|
||||
krb5_store_int8(sp, 0); /* flags */
|
||||
krb5_store_stringz(sp, name);
|
||||
krb5_store_stringz(sp, inst);
|
||||
krb5_store_stringz(sp, realm);
|
||||
{
|
||||
unsigned char tmp[4] = { 0, 0, 0, 0 };
|
||||
int i;
|
||||
if(et->caddr){
|
||||
for(i = 0; i < et->caddr->len; i++)
|
||||
if(et->caddr->val[i].addr_type == AF_INET &&
|
||||
et->caddr->val[i].address.length == 4){
|
||||
memcpy(tmp, et->caddr->val[i].address.data, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
krb5_storage_write(sp, tmp, sizeof(tmp));
|
||||
}
|
||||
|
||||
if((et->key.keytype != ETYPE_DES_CBC_MD5 &&
|
||||
et->key.keytype != ETYPE_DES_CBC_MD4 &&
|
||||
et->key.keytype != ETYPE_DES_CBC_CRC) ||
|
||||
et->key.keyvalue.length != 8)
|
||||
return -1;
|
||||
krb5_storage_write(sp, et->key.keyvalue.data, 8);
|
||||
|
||||
{
|
||||
time_t start = et->starttime ? *et->starttime : et->authtime;
|
||||
krb5_store_int8(sp, krb_time_to_life(start, et->endtime));
|
||||
krb5_store_int32(sp, start);
|
||||
}
|
||||
|
||||
krb5_store_stringz(sp, sname);
|
||||
krb5_store_stringz(sp, sinst);
|
||||
|
||||
{
|
||||
krb5_data data;
|
||||
krb5_storage_to_data(sp, &data);
|
||||
krb5_storage_free(sp);
|
||||
*size = (data.length + 7) & ~7; /* pad to 8 bytes */
|
||||
if(*size > len)
|
||||
return -1;
|
||||
memset((unsigned char*)buf - *size + 1, 0, *size);
|
||||
memcpy((unsigned char*)buf - *size + 1, data.data, data.length);
|
||||
krb5_data_free(&data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
_kdc_get_des_key(krb5_context context,
|
||||
hdb_entry_ex *principal, krb5_boolean is_server,
|
||||
krb5_boolean prefer_afs_key, Key **ret_key)
|
||||
{
|
||||
Key *v5_key = NULL, *v4_key = NULL, *afs_key = NULL, *server_key = NULL;
|
||||
int i;
|
||||
krb5_enctype etypes[] = { ETYPE_DES_CBC_MD5,
|
||||
ETYPE_DES_CBC_MD4,
|
||||
ETYPE_DES_CBC_CRC };
|
||||
|
||||
for(i = 0;
|
||||
i < sizeof(etypes)/sizeof(etypes[0])
|
||||
&& (v5_key == NULL || v4_key == NULL ||
|
||||
afs_key == NULL || server_key == NULL);
|
||||
++i) {
|
||||
Key *key = NULL;
|
||||
while(hdb_next_enctype2key(context, &principal->entry, etypes[i], &key) == 0) {
|
||||
if(key->salt == NULL) {
|
||||
if(v5_key == NULL)
|
||||
v5_key = key;
|
||||
} else if(key->salt->type == hdb_pw_salt &&
|
||||
key->salt->salt.length == 0) {
|
||||
if(v4_key == NULL)
|
||||
v4_key = key;
|
||||
} else if(key->salt->type == hdb_afs3_salt) {
|
||||
if(afs_key == NULL)
|
||||
afs_key = key;
|
||||
} else if(server_key == NULL)
|
||||
server_key = key;
|
||||
}
|
||||
}
|
||||
|
||||
if(prefer_afs_key) {
|
||||
if(afs_key)
|
||||
*ret_key = afs_key;
|
||||
else if(v4_key)
|
||||
*ret_key = v4_key;
|
||||
else if(v5_key)
|
||||
*ret_key = v5_key;
|
||||
else if(is_server && server_key)
|
||||
*ret_key = server_key;
|
||||
else
|
||||
return KERB_ERR_NULL_KEY;
|
||||
} else {
|
||||
if(v4_key)
|
||||
*ret_key = v4_key;
|
||||
else if(afs_key)
|
||||
*ret_key = afs_key;
|
||||
else if(v5_key)
|
||||
*ret_key = v5_key;
|
||||
else if(is_server && server_key)
|
||||
*ret_key = server_key;
|
||||
else
|
||||
return KERB_ERR_NULL_KEY;
|
||||
}
|
||||
|
||||
if((*ret_key)->key.keyvalue.length == 0)
|
||||
return KERB_ERR_NULL_KEY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 2002 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 "kdc_locl.h"
|
||||
RCSID("$Id: log.c,v 1.16 2005/06/30 01:52:48 lha Exp $");
|
||||
|
||||
void
|
||||
kdc_openlog(krb5_context context,
|
||||
krb5_kdc_configuration *config)
|
||||
{
|
||||
char **s = NULL, **p;
|
||||
krb5_initlog(context, "kdc", &config->logf);
|
||||
s = krb5_config_get_strings(context, NULL, "kdc", "logging", NULL);
|
||||
if(s == NULL)
|
||||
s = krb5_config_get_strings(context, NULL, "logging", "kdc", NULL);
|
||||
if(s){
|
||||
for(p = s; *p; p++)
|
||||
krb5_addlog_dest(context, config->logf, *p);
|
||||
krb5_config_free_strings(s);
|
||||
}else
|
||||
krb5_addlog_dest(context, config->logf, DEFAULT_LOG_DEST);
|
||||
krb5_set_warn_dest(context, config->logf);
|
||||
}
|
||||
|
||||
char*
|
||||
kdc_log_msg_va(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
int level, const char *fmt, va_list ap)
|
||||
{
|
||||
char *msg;
|
||||
krb5_vlog_msg(context, config->logf, &msg, level, fmt, ap);
|
||||
return msg;
|
||||
}
|
||||
|
||||
char*
|
||||
kdc_log_msg(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *s;
|
||||
va_start(ap, fmt);
|
||||
s = kdc_log_msg_va(context, config, level, fmt, ap);
|
||||
va_end(ap);
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
kdc_log(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *s;
|
||||
va_start(ap, fmt);
|
||||
s = kdc_log_msg_va(context, config, level, fmt, ap);
|
||||
if(s) free(s);
|
||||
va_end(ap);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "kdc_locl.h"
|
||||
|
||||
RCSID("$Id: misc.c,v 1.32 2006/08/28 14:41:49 lha Exp $");
|
||||
|
||||
struct timeval _kdc_now;
|
||||
|
||||
krb5_error_code
|
||||
_kdc_db_fetch(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
krb5_const_principal principal,
|
||||
unsigned flags,
|
||||
HDB **db,
|
||||
hdb_entry_ex **h)
|
||||
{
|
||||
hdb_entry_ex *ent;
|
||||
krb5_error_code ret = HDB_ERR_NOENTRY;
|
||||
int i;
|
||||
|
||||
ent = calloc (1, sizeof (*ent));
|
||||
if (ent == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
for(i = 0; i < config->num_db; i++) {
|
||||
ret = config->db[i]->hdb_open(context, config->db[i], O_RDONLY, 0);
|
||||
if (ret) {
|
||||
kdc_log(context, config, 0, "Failed to open database: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
continue;
|
||||
}
|
||||
ret = config->db[i]->hdb_fetch(context,
|
||||
config->db[i],
|
||||
principal,
|
||||
flags | HDB_F_DECRYPT,
|
||||
ent);
|
||||
config->db[i]->hdb_close(context, config->db[i]);
|
||||
if(ret == 0) {
|
||||
if (db)
|
||||
*db = config->db[i];
|
||||
*h = ent;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
free(ent);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_kdc_free_ent(krb5_context context, hdb_entry_ex *ent)
|
||||
{
|
||||
hdb_free_entry (context, ent);
|
||||
free (ent);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the order list of preferred encryption types and sort the
|
||||
* available keys and return the most preferred key.
|
||||
*/
|
||||
|
||||
krb5_error_code
|
||||
_kdc_get_preferred_key(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
hdb_entry_ex *h,
|
||||
const char *name,
|
||||
krb5_enctype *enctype,
|
||||
Key **key)
|
||||
{
|
||||
const krb5_enctype *p;
|
||||
krb5_error_code ret;
|
||||
int i;
|
||||
|
||||
p = krb5_kerberos_enctypes(context);
|
||||
|
||||
for (i = 0; p[i] != ETYPE_NULL; i++) {
|
||||
if (krb5_enctype_valid(context, p[i]) != 0)
|
||||
continue;
|
||||
ret = hdb_enctype2key(context, &h->entry, p[i], key);
|
||||
if (ret == 0) {
|
||||
*enctype = p[i];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
krb5_set_error_string(context, "No valid kerberos key found for %s", name);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
Executable
+1463
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "kdc_locl.h"
|
||||
|
||||
RCSID("$Id: process.c,v 1.5 2006/10/09 15:37:39 lha Exp $");
|
||||
|
||||
/*
|
||||
* handle the request in `buf, len', from `addr' (or `from' as a string),
|
||||
* sending a reply in `reply'.
|
||||
*/
|
||||
|
||||
int
|
||||
krb5_kdc_process_request(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
unsigned char *buf,
|
||||
size_t len,
|
||||
krb5_data *reply,
|
||||
krb5_boolean *prependlength,
|
||||
const char *from,
|
||||
struct sockaddr *addr,
|
||||
int datagram_reply)
|
||||
{
|
||||
KDC_REQ req;
|
||||
Ticket ticket;
|
||||
DigestREQ digestreq;
|
||||
krb5_error_code ret;
|
||||
size_t i;
|
||||
|
||||
gettimeofday(&_kdc_now, NULL);
|
||||
if(decode_AS_REQ(buf, len, &req, &i) == 0){
|
||||
krb5_data req_buffer;
|
||||
|
||||
req_buffer.data = buf;
|
||||
req_buffer.length = len;
|
||||
|
||||
ret = _kdc_as_rep(context, config, &req, &req_buffer,
|
||||
reply, from, addr, datagram_reply);
|
||||
free_AS_REQ(&req);
|
||||
return ret;
|
||||
}else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
|
||||
ret = _kdc_tgs_rep(context, config, &req, reply, from, addr);
|
||||
free_TGS_REQ(&req);
|
||||
return ret;
|
||||
}else if(decode_Ticket(buf, len, &ticket, &i) == 0){
|
||||
ret = _kdc_do_524(context, config, &ticket, reply, from, addr);
|
||||
free_Ticket(&ticket);
|
||||
return ret;
|
||||
}else if(decode_DigestREQ(buf, len, &digestreq, &i) == 0){
|
||||
ret = _kdc_do_digest(context, config, &digestreq, reply, from, addr);
|
||||
free_DigestREQ(&digestreq);
|
||||
return ret;
|
||||
} else if(_kdc_maybe_version4(buf, len)){
|
||||
*prependlength = FALSE; /* elbitapmoc sdrawkcab XXX */
|
||||
_kdc_do_version4(context, config, buf, len, reply, from,
|
||||
(struct sockaddr_in*)addr);
|
||||
return 0;
|
||||
} else if (config->enable_kaserver) {
|
||||
ret = _kdc_do_kaserver(context, config, buf, len, reply, from,
|
||||
(struct sockaddr_in*)addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* handle the request in `buf, len', from `addr' (or `from' as a string),
|
||||
* sending a reply in `reply'.
|
||||
*
|
||||
* This only processes krb5 requests
|
||||
*/
|
||||
|
||||
int
|
||||
krb5_kdc_process_krb5_request(krb5_context context,
|
||||
krb5_kdc_configuration *config,
|
||||
unsigned char *buf,
|
||||
size_t len,
|
||||
krb5_data *reply,
|
||||
const char *from,
|
||||
struct sockaddr *addr,
|
||||
int datagram_reply)
|
||||
{
|
||||
KDC_REQ req;
|
||||
krb5_error_code ret;
|
||||
size_t i;
|
||||
|
||||
gettimeofday(&_kdc_now, NULL);
|
||||
if(decode_AS_REQ(buf, len, &req, &i) == 0){
|
||||
krb5_data req_buffer;
|
||||
|
||||
req_buffer.data = buf;
|
||||
req_buffer.length = len;
|
||||
|
||||
ret = _kdc_as_rep(context, config, &req, &req_buffer,
|
||||
reply, from, addr, datagram_reply);
|
||||
free_AS_REQ(&req);
|
||||
return ret;
|
||||
}else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
|
||||
ret = _kdc_tgs_rep(context, config, &req, reply, from, addr);
|
||||
free_TGS_REQ(&req);
|
||||
return ret;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 1997 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: rx.h,v 1.5 2006/05/05 10:51:10 lha Exp $ */
|
||||
|
||||
#ifndef __RX_H__
|
||||
#define __RX_H__
|
||||
|
||||
/* header of a RPC packet */
|
||||
|
||||
enum rx_header_type {
|
||||
HT_DATA = 1,
|
||||
HT_ACK = 2,
|
||||
HT_BUSY = 3,
|
||||
HT_ABORT = 4,
|
||||
HT_ACKALL = 5,
|
||||
HT_CHAL = 6,
|
||||
HT_RESP = 7,
|
||||
HT_DEBUG = 8
|
||||
};
|
||||
|
||||
/* For flags in header */
|
||||
|
||||
enum rx_header_flag {
|
||||
HF_CLIENT_INITIATED = 1,
|
||||
HF_REQ_ACK = 2,
|
||||
HF_LAST = 4,
|
||||
HF_MORE = 8
|
||||
};
|
||||
|
||||
struct rx_header {
|
||||
uint32_t epoch;
|
||||
uint32_t connid; /* And channel ID */
|
||||
uint32_t callid;
|
||||
uint32_t seqno;
|
||||
uint32_t serialno;
|
||||
u_char type;
|
||||
u_char flags;
|
||||
u_char status;
|
||||
u_char secindex;
|
||||
uint16_t reserved; /* ??? verifier? */
|
||||
uint16_t serviceid;
|
||||
/* This should be the other way around according to everything but */
|
||||
/* tcpdump */
|
||||
};
|
||||
|
||||
#define RX_HEADER_SIZE 28
|
||||
|
||||
#endif /* __RX_H__ */
|
||||
@@ -0,0 +1,157 @@
|
||||
-- From RFC 3369 --
|
||||
-- $Id: CMS.asn1,v 1.5 2006/09/07 12:20:42 lha Exp $ --
|
||||
|
||||
CMS DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS CertificateSerialNumber, AlgorithmIdentifier, Name,
|
||||
Attribute, Certificate, Name, SubjectKeyIdentifier FROM rfc2459
|
||||
heim_any, heim_any_set FROM heim;
|
||||
|
||||
id-pkcs7 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
||||
us(840) rsadsi(113549) pkcs(1) pkcs7(7) }
|
||||
|
||||
id-pkcs7-data OBJECT IDENTIFIER ::= { id-pkcs7 1 }
|
||||
id-pkcs7-signedData OBJECT IDENTIFIER ::= { id-pkcs7 2 }
|
||||
id-pkcs7-envelopedData OBJECT IDENTIFIER ::= { id-pkcs7 3 }
|
||||
id-pkcs7-signedAndEnvelopedData OBJECT IDENTIFIER ::= { id-pkcs7 4 }
|
||||
id-pkcs7-digestedData OBJECT IDENTIFIER ::= { id-pkcs7 5 }
|
||||
id-pkcs7-encryptedData OBJECT IDENTIFIER ::= { id-pkcs7 6 }
|
||||
|
||||
CMSVersion ::= INTEGER {
|
||||
CMSVersion_v0(0),
|
||||
CMSVersion_v1(1),
|
||||
CMSVersion_v2(2),
|
||||
CMSVersion_v3(3),
|
||||
CMSVersion_v4(4)
|
||||
}
|
||||
|
||||
DigestAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
|
||||
SignatureAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
|
||||
ContentType ::= OBJECT IDENTIFIER
|
||||
MessageDigest ::= OCTET STRING
|
||||
|
||||
ContentInfo ::= SEQUENCE {
|
||||
contentType ContentType,
|
||||
content [0] EXPLICIT heim_any OPTIONAL -- DEFINED BY contentType
|
||||
}
|
||||
|
||||
EncapsulatedContentInfo ::= SEQUENCE {
|
||||
eContentType ContentType,
|
||||
eContent [0] EXPLICIT OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
CertificateSet ::= SET OF heim_any
|
||||
|
||||
CertificateList ::= Certificate
|
||||
|
||||
CertificateRevocationLists ::= SET OF CertificateList
|
||||
|
||||
IssuerAndSerialNumber ::= SEQUENCE {
|
||||
issuer Name,
|
||||
serialNumber CertificateSerialNumber
|
||||
}
|
||||
|
||||
-- RecipientIdentifier is same as SignerIdentifier,
|
||||
-- lets glue them togheter and save some bytes and share code for them
|
||||
|
||||
CMSIdentifier ::= CHOICE {
|
||||
issuerAndSerialNumber IssuerAndSerialNumber,
|
||||
subjectKeyIdentifier [0] SubjectKeyIdentifier
|
||||
}
|
||||
|
||||
SignerIdentifier ::= CMSIdentifier
|
||||
RecipientIdentifier ::= CMSIdentifier
|
||||
|
||||
--- CMSAttributes are the combined UnsignedAttributes and SignedAttributes
|
||||
--- to store space and share code
|
||||
|
||||
CMSAttributes ::= SET OF Attribute -- SIZE (1..MAX)
|
||||
|
||||
SignatureValue ::= OCTET STRING
|
||||
|
||||
SignerInfo ::= SEQUENCE {
|
||||
version CMSVersion,
|
||||
sid SignerIdentifier,
|
||||
digestAlgorithm DigestAlgorithmIdentifier,
|
||||
signedAttrs [0] IMPLICIT -- CMSAttributes --
|
||||
SET OF Attribute OPTIONAL,
|
||||
signatureAlgorithm SignatureAlgorithmIdentifier,
|
||||
signature SignatureValue,
|
||||
unsignedAttrs [1] IMPLICIT -- CMSAttributes --
|
||||
SET OF Attribute OPTIONAL
|
||||
}
|
||||
|
||||
SignerInfos ::= SET OF SignerInfo
|
||||
|
||||
SignedData ::= SEQUENCE {
|
||||
version CMSVersion,
|
||||
digestAlgorithms DigestAlgorithmIdentifiers,
|
||||
encapContentInfo EncapsulatedContentInfo,
|
||||
certificates [0] IMPLICIT -- CertificateSet --
|
||||
SET OF heim_any OPTIONAL,
|
||||
crls [1] IMPLICIT -- CertificateRevocationLists --
|
||||
heim_any OPTIONAL,
|
||||
signerInfos SignerInfos
|
||||
}
|
||||
|
||||
OriginatorInfo ::= SEQUENCE {
|
||||
certs [0] IMPLICIT -- CertificateSet --
|
||||
SET OF heim_any OPTIONAL,
|
||||
crls [1] IMPLICIT --CertificateRevocationLists --
|
||||
heim_any OPTIONAL
|
||||
}
|
||||
|
||||
KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
|
||||
EncryptedKey ::= OCTET STRING
|
||||
|
||||
KeyTransRecipientInfo ::= SEQUENCE {
|
||||
version CMSVersion, -- always set to 0 or 2
|
||||
rid RecipientIdentifier,
|
||||
keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
|
||||
encryptedKey EncryptedKey
|
||||
}
|
||||
|
||||
RecipientInfo ::= KeyTransRecipientInfo
|
||||
|
||||
RecipientInfos ::= SET OF RecipientInfo
|
||||
|
||||
EncryptedContent ::= OCTET STRING
|
||||
|
||||
EncryptedContentInfo ::= SEQUENCE {
|
||||
contentType ContentType,
|
||||
contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
|
||||
encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
UnprotectedAttributes ::= SET OF Attribute -- SIZE (1..MAX)
|
||||
|
||||
CMSEncryptedData ::= SEQUENCE {
|
||||
version CMSVersion,
|
||||
encryptedContentInfo EncryptedContentInfo,
|
||||
unprotectedAttrs [1] IMPLICIT -- UnprotectedAttributes --
|
||||
heim_any OPTIONAL
|
||||
}
|
||||
|
||||
EnvelopedData ::= SEQUENCE {
|
||||
version CMSVersion,
|
||||
originatorInfo [0] IMPLICIT -- OriginatorInfo -- heim_any OPTIONAL,
|
||||
recipientInfos RecipientInfos,
|
||||
encryptedContentInfo EncryptedContentInfo,
|
||||
unprotectedAttrs [1] IMPLICIT -- UnprotectedAttributes --
|
||||
heim_any OPTIONAL
|
||||
}
|
||||
|
||||
-- Data ::= OCTET STRING
|
||||
|
||||
CMSRC2CBCParameter ::= SEQUENCE {
|
||||
rc2ParameterVersion INTEGER (0..4294967295),
|
||||
iv OCTET STRING -- exactly 8 octets
|
||||
}
|
||||
|
||||
CMSCBCParameter ::= OCTET STRING
|
||||
|
||||
END
|
||||
@@ -0,0 +1,65 @@
|
||||
/* $Id: asn1-common.h,v 1.6 2006/10/14 05:09:47 lha Exp $ */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifndef __asn1_common_definitions__
|
||||
#define __asn1_common_definitions__
|
||||
|
||||
typedef struct heim_integer {
|
||||
size_t length;
|
||||
void *data;
|
||||
int negative;
|
||||
} heim_integer;
|
||||
|
||||
typedef struct heim_octet_string {
|
||||
size_t length;
|
||||
void *data;
|
||||
} heim_octet_string;
|
||||
|
||||
typedef char *heim_general_string;
|
||||
typedef char *heim_utf8_string;
|
||||
typedef char *heim_printable_string;
|
||||
typedef char *heim_ia5_string;
|
||||
|
||||
typedef struct heim_bmp_string {
|
||||
size_t length;
|
||||
uint16_t *data;
|
||||
} heim_bmp_string;
|
||||
|
||||
typedef struct heim_universal_string {
|
||||
size_t length;
|
||||
uint32_t *data;
|
||||
} heim_universal_string;
|
||||
|
||||
|
||||
typedef struct heim_oid {
|
||||
size_t length;
|
||||
unsigned *components;
|
||||
} heim_oid;
|
||||
|
||||
typedef struct heim_bit_string {
|
||||
size_t length;
|
||||
void *data;
|
||||
} heim_bit_string;
|
||||
|
||||
typedef struct heim_octet_string heim_any;
|
||||
typedef struct heim_octet_string heim_any_set;
|
||||
|
||||
#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \
|
||||
do { \
|
||||
(BL) = length_##T((S)); \
|
||||
(B) = malloc((BL)); \
|
||||
if((B) == NULL) { \
|
||||
(R) = ENOMEM; \
|
||||
} else { \
|
||||
(R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \
|
||||
(S), (L)); \
|
||||
if((R) != 0) { \
|
||||
free((B)); \
|
||||
(B) = NULL; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# Error messages for the asn.1 library
|
||||
#
|
||||
# This might look like a com_err file, but is not
|
||||
#
|
||||
id "$Id: asn1_err.et,v 1.6 2006/10/24 14:11:20 lha Exp $"
|
||||
|
||||
error_table asn1
|
||||
prefix ASN1
|
||||
error_code BAD_TIMEFORMAT, "ASN.1 failed call to system time library"
|
||||
error_code MISSING_FIELD, "ASN.1 structure is missing a required field"
|
||||
error_code MISPLACED_FIELD, "ASN.1 unexpected field number"
|
||||
error_code TYPE_MISMATCH, "ASN.1 type numbers are inconsistent"
|
||||
error_code OVERFLOW, "ASN.1 value too large"
|
||||
error_code OVERRUN, "ASN.1 encoding ended unexpectedly"
|
||||
error_code BAD_ID, "ASN.1 identifier doesn't match expected value"
|
||||
error_code BAD_LENGTH, "ASN.1 length doesn't match expected value"
|
||||
error_code BAD_FORMAT, "ASN.1 badly-formatted encoding"
|
||||
error_code PARSE_ERROR, "ASN.1 parse error"
|
||||
error_code EXTRA_DATA, "ASN.1 extra data past end of end structure"
|
||||
end
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
#include <com_err.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <getarg.h>
|
||||
#include <hex.h>
|
||||
#include <err.h>
|
||||
|
||||
RCSID("$Id: asn1_gen.c,v 1.4 2006/01/30 15:06:03 lha Exp $");
|
||||
|
||||
static int
|
||||
doit(const char *fn)
|
||||
{
|
||||
char buf[2048];
|
||||
char *fnout;
|
||||
const char *bname;
|
||||
unsigned long line = 0;
|
||||
FILE *f, *fout;
|
||||
size_t offset = 0;
|
||||
|
||||
f = fopen(fn, "r");
|
||||
if (f == NULL)
|
||||
err(1, "fopen");
|
||||
|
||||
bname = strrchr(fn, '/');
|
||||
if (bname)
|
||||
bname++;
|
||||
else
|
||||
bname = fn;
|
||||
|
||||
asprintf(&fnout, "%s.out", bname);
|
||||
if (fnout == NULL)
|
||||
errx(1, "malloc");
|
||||
|
||||
fout = fopen(fnout, "w");
|
||||
if (fout == NULL)
|
||||
err(1, "fopen: output file");
|
||||
|
||||
while (fgets(buf, sizeof(buf), f) != NULL) {
|
||||
char *ptr, *class, *type, *tag, *length, *data, *foo;
|
||||
int ret, l, c, ty, ta;
|
||||
unsigned char p[6], *pdata;
|
||||
size_t sz;
|
||||
|
||||
line++;
|
||||
|
||||
buf[strcspn(buf, "\r\n")] = '\0';
|
||||
if (buf[0] == '#' || buf[0] == '\0')
|
||||
continue;
|
||||
|
||||
ptr = buf;
|
||||
while (isspace((unsigned char)*ptr))
|
||||
ptr++;
|
||||
|
||||
class = strtok_r(ptr, " \t\n", &foo);
|
||||
if (class == NULL) errx(1, "class missing on line %lu", line);
|
||||
type = strtok_r(NULL, " \t\n", &foo);
|
||||
if (type == NULL) errx(1, "type missing on line %lu", line);
|
||||
tag = strtok_r(NULL, " \t\n", &foo);
|
||||
if (tag == NULL) errx(1, "tag missing on line %lu", line);
|
||||
length = strtok_r(NULL, " \t\n", &foo);
|
||||
if (length == NULL) errx(1, "length missing on line %lu", line);
|
||||
data = strtok_r(NULL, " \t\n", &foo);
|
||||
|
||||
c = der_get_class_num(class);
|
||||
if (c == -1) errx(1, "no valid class on line %lu", line);
|
||||
ty = der_get_type_num(type);
|
||||
if (ty == -1) errx(1, "no valid type on line %lu", line);
|
||||
ta = der_get_tag_num(tag);
|
||||
if (ta == -1)
|
||||
ta = atoi(tag);
|
||||
|
||||
l = atoi(length);
|
||||
|
||||
printf("line: %3lu offset: %3lu class: %d type: %d "
|
||||
"tag: %3d length: %3d %s\n",
|
||||
line, (unsigned long)offset, c, ty, ta, l,
|
||||
data ? "<have data>" : "<no data>");
|
||||
|
||||
ret = der_put_length_and_tag(p + sizeof(p) - 1, sizeof(p),
|
||||
l,
|
||||
c,
|
||||
ty,
|
||||
ta,
|
||||
&sz);
|
||||
if (ret)
|
||||
errx(1, "der_put_length_and_tag: %d", ret);
|
||||
|
||||
if (fwrite(p + sizeof(p) - sz , sz, 1, fout) != 1)
|
||||
err(1, "fwrite length/tag failed");
|
||||
offset += sz;
|
||||
|
||||
if (data) {
|
||||
size_t datalen;
|
||||
|
||||
datalen = strlen(data) / 2;
|
||||
pdata = emalloc(sz);
|
||||
|
||||
if (hex_decode(data, pdata, datalen) != datalen)
|
||||
errx(1, "failed to decode data");
|
||||
|
||||
if (fwrite(pdata, datalen, 1, fout) != 1)
|
||||
err(1, "fwrite data failed");
|
||||
offset += datalen;
|
||||
|
||||
free(pdata);
|
||||
}
|
||||
}
|
||||
printf("line: eof offset: %lu\n", (unsigned long)offset);
|
||||
|
||||
fclose(fout);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int version_flag;
|
||||
static int help_flag;
|
||||
struct getargs args[] = {
|
||||
{ "version", 0, arg_flag, &version_flag },
|
||||
{ "help", 0, arg_flag, &help_flag }
|
||||
};
|
||||
int num_args = sizeof(args) / sizeof(args[0]);
|
||||
|
||||
static void
|
||||
usage(int code)
|
||||
{
|
||||
arg_printusage(args, num_args, NULL, "parse-file");
|
||||
exit(code);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int 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);
|
||||
}
|
||||
argv += optidx;
|
||||
argc -= optidx;
|
||||
if (argc != 1)
|
||||
usage (1);
|
||||
|
||||
return doit (argv[0]);
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/* $NetBSD: queue.h,v 1.38 2004/04/18 14:12:05 lukem Exp $ */
|
||||
/* $Id: asn1_queue.h,v 1.2 2005/07/12 06:27:15 lha Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||
*/
|
||||
|
||||
#ifndef _ASN1_QUEUE_H_
|
||||
#define _ASN1_QUEUE_H_
|
||||
|
||||
/*
|
||||
* Tail queue definitions.
|
||||
*/
|
||||
#define ASN1_TAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *tqh_first; /* first element */ \
|
||||
struct type **tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define ASN1_TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).tqh_first }
|
||||
#define ASN1_TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *tqe_next; /* next element */ \
|
||||
struct type **tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#if defined(_KERNEL) && defined(QUEUEDEBUG)
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD(head, elm, field) \
|
||||
if ((head)->tqh_first && \
|
||||
(head)->tqh_first->field.tqe_prev != &(head)->tqh_first) \
|
||||
panic("ASN1_TAILQ_INSERT_HEAD %p %s:%d", (head), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL(head, elm, field) \
|
||||
if (*(head)->tqh_last != NULL) \
|
||||
panic("ASN1_TAILQ_INSERT_TAIL %p %s:%d", (head), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_OP(elm, field) \
|
||||
if ((elm)->field.tqe_next && \
|
||||
(elm)->field.tqe_next->field.tqe_prev != \
|
||||
&(elm)->field.tqe_next) \
|
||||
panic("ASN1_TAILQ_* forw %p %s:%d", (elm), __FILE__, __LINE__);\
|
||||
if (*(elm)->field.tqe_prev != (elm)) \
|
||||
panic("ASN1_TAILQ_* back %p %s:%d", (elm), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_PREREMOVE(head, elm, field) \
|
||||
if ((elm)->field.tqe_next == NULL && \
|
||||
(head)->tqh_last != &(elm)->field.tqe_next) \
|
||||
panic("ASN1_TAILQ_PREREMOVE head %p elm %p %s:%d", \
|
||||
(head), (elm), __FILE__, __LINE__);
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE(elm, field) \
|
||||
(elm)->field.tqe_next = (void *)1L; \
|
||||
(elm)->field.tqe_prev = (void *)1L;
|
||||
#else
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD(head, elm, field)
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL(head, elm, field)
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_OP(elm, field)
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_PREREMOVE(head, elm, field)
|
||||
#define QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE(elm, field)
|
||||
#endif
|
||||
|
||||
#define ASN1_TAILQ_INIT(head) do { \
|
||||
(head)->tqh_first = NULL; \
|
||||
(head)->tqh_last = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
QUEUEDEBUG_ASN1_TAILQ_INSERT_HEAD((head), (elm), field) \
|
||||
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
|
||||
(head)->tqh_first->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(head)->tqh_first = (elm); \
|
||||
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
QUEUEDEBUG_ASN1_TAILQ_INSERT_TAIL((head), (elm), field) \
|
||||
(elm)->field.tqe_next = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
QUEUEDEBUG_ASN1_TAILQ_OP((listelm), field) \
|
||||
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(listelm)->field.tqe_next = (elm); \
|
||||
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
QUEUEDEBUG_ASN1_TAILQ_OP((listelm), field) \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
(elm)->field.tqe_next = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_REMOVE(head, elm, field) do { \
|
||||
QUEUEDEBUG_ASN1_TAILQ_PREREMOVE((head), (elm), field) \
|
||||
QUEUEDEBUG_ASN1_TAILQ_OP((elm), field) \
|
||||
if (((elm)->field.tqe_next) != NULL) \
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
||||
QUEUEDEBUG_ASN1_TAILQ_POSTREMOVE((elm), field); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define ASN1_TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = ((head)->tqh_first); \
|
||||
(var); \
|
||||
(var) = ((var)->field.tqe_next))
|
||||
|
||||
#define ASN1_TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
|
||||
(var); \
|
||||
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
|
||||
|
||||
/*
|
||||
* Tail queue access methods.
|
||||
*/
|
||||
#define ASN1_TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
#define ASN1_TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define ASN1_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#define ASN1_TAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
#define ASN1_TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
|
||||
#endif /* !_ASN1_QUEUE_H_ */
|
||||
@@ -0,0 +1,34 @@
|
||||
-- $Id: canthandle.asn1,v 1.6 2006/01/18 19:12:33 lha Exp $ --
|
||||
|
||||
CANTHANDLE DEFINITIONS ::= BEGIN
|
||||
|
||||
-- Code the tag [1] but not the [ CONTEXT CONS UT_Sequence ] for Kaka2
|
||||
-- Workaround: use inline the structure directly
|
||||
-- Code the tag [2] but it should be primitive since KAKA3 is
|
||||
-- Workaround: use the INTEGER type directly
|
||||
|
||||
Kaka2 ::= SEQUENCE {
|
||||
kaka2-1 [0] INTEGER
|
||||
}
|
||||
|
||||
Kaka3 ::= INTEGER
|
||||
|
||||
Foo ::= SEQUENCE {
|
||||
kaka1 [0] IMPLICIT INTEGER OPTIONAL,
|
||||
kaka2 [1] IMPLICIT Kaka2 OPTIONAL,
|
||||
kaka3 [2] IMPLICIT Kaka3 OPTIONAL
|
||||
}
|
||||
|
||||
-- Don't code kaka if its 1
|
||||
-- Workaround is to use OPTIONAL and check for in the encoder stubs
|
||||
|
||||
Bar ::= SEQUENCE {
|
||||
kaka [0] INTEGER DEFAULT 1
|
||||
}
|
||||
|
||||
-- Can't handle primitives in SET OF
|
||||
-- Workaround is to define a type that is only an integer and use that
|
||||
|
||||
Baz ::= SET OF INTEGER
|
||||
|
||||
END
|
||||
@@ -0,0 +1,542 @@
|
||||
/* This is a generated file */
|
||||
#ifndef __der_protos_h__
|
||||
#define __der_protos_h__
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int
|
||||
copy_heim_any (
|
||||
const heim_any */*from*/,
|
||||
heim_any */*to*/);
|
||||
|
||||
int
|
||||
copy_heim_any_set (
|
||||
const heim_any_set */*from*/,
|
||||
heim_any_set */*to*/);
|
||||
|
||||
int
|
||||
decode_heim_any (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_any */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
decode_heim_any_set (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_any_set */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_copy_bit_string (
|
||||
const heim_bit_string */*from*/,
|
||||
heim_bit_string */*to*/);
|
||||
|
||||
int
|
||||
der_copy_bmp_string (
|
||||
const heim_bmp_string */*from*/,
|
||||
heim_bmp_string */*to*/);
|
||||
|
||||
int
|
||||
der_copy_general_string (
|
||||
const heim_general_string */*from*/,
|
||||
heim_general_string */*to*/);
|
||||
|
||||
int
|
||||
der_copy_heim_integer (
|
||||
const heim_integer */*from*/,
|
||||
heim_integer */*to*/);
|
||||
|
||||
int
|
||||
der_copy_ia5_string (
|
||||
const heim_printable_string */*from*/,
|
||||
heim_printable_string */*to*/);
|
||||
|
||||
int
|
||||
der_copy_octet_string (
|
||||
const heim_octet_string */*from*/,
|
||||
heim_octet_string */*to*/);
|
||||
|
||||
int
|
||||
der_copy_oid (
|
||||
const heim_oid */*from*/,
|
||||
heim_oid */*to*/);
|
||||
|
||||
int
|
||||
der_copy_printable_string (
|
||||
const heim_printable_string */*from*/,
|
||||
heim_printable_string */*to*/);
|
||||
|
||||
int
|
||||
der_copy_universal_string (
|
||||
const heim_universal_string */*from*/,
|
||||
heim_universal_string */*to*/);
|
||||
|
||||
int
|
||||
der_copy_utf8string (
|
||||
const heim_utf8_string */*from*/,
|
||||
heim_utf8_string */*to*/);
|
||||
|
||||
void
|
||||
der_free_bit_string (heim_bit_string */*k*/);
|
||||
|
||||
void
|
||||
der_free_bmp_string (heim_bmp_string */*k*/);
|
||||
|
||||
void
|
||||
der_free_general_string (heim_general_string */*str*/);
|
||||
|
||||
void
|
||||
der_free_heim_integer (heim_integer */*k*/);
|
||||
|
||||
void
|
||||
der_free_ia5_string (heim_ia5_string */*str*/);
|
||||
|
||||
void
|
||||
der_free_octet_string (heim_octet_string */*k*/);
|
||||
|
||||
void
|
||||
der_free_oid (heim_oid */*k*/);
|
||||
|
||||
void
|
||||
der_free_printable_string (heim_printable_string */*str*/);
|
||||
|
||||
void
|
||||
der_free_universal_string (heim_universal_string */*k*/);
|
||||
|
||||
void
|
||||
der_free_utf8string (heim_utf8_string */*str*/);
|
||||
|
||||
int
|
||||
der_get_bit_string (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_bit_string */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_bmp_string (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_bmp_string */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_boolean (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
int */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
const char *
|
||||
der_get_class_name (unsigned /*num*/);
|
||||
|
||||
int
|
||||
der_get_class_num (const char */*name*/);
|
||||
|
||||
int
|
||||
der_get_general_string (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_general_string */*str*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_generalized_time (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
time_t */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_heim_integer (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_integer */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_ia5_string (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_ia5_string */*str*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_integer (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
int */*ret*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_length (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
size_t */*val*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_octet_string (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_octet_string */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_oid (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_oid */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_printable_string (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_printable_string */*str*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_tag (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
Der_class */*class*/,
|
||||
Der_type */*type*/,
|
||||
unsigned int */*tag*/,
|
||||
size_t */*size*/);
|
||||
|
||||
const char *
|
||||
der_get_tag_name (unsigned /*num*/);
|
||||
|
||||
int
|
||||
der_get_tag_num (const char */*name*/);
|
||||
|
||||
const char *
|
||||
der_get_type_name (unsigned /*num*/);
|
||||
|
||||
int
|
||||
der_get_type_num (const char */*name*/);
|
||||
|
||||
int
|
||||
der_get_universal_string (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_universal_string */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_unsigned (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
unsigned */*ret*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_utctime (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
time_t */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_get_utf8string (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
heim_utf8_string */*str*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_heim_bit_string_cmp (
|
||||
const heim_bit_string */*p*/,
|
||||
const heim_bit_string */*q*/);
|
||||
|
||||
int
|
||||
der_heim_bmp_string_cmp (
|
||||
const heim_bmp_string */*p*/,
|
||||
const heim_bmp_string */*q*/);
|
||||
|
||||
int
|
||||
der_heim_integer_cmp (
|
||||
const heim_integer */*p*/,
|
||||
const heim_integer */*q*/);
|
||||
|
||||
int
|
||||
der_heim_octet_string_cmp (
|
||||
const heim_octet_string */*p*/,
|
||||
const heim_octet_string */*q*/);
|
||||
|
||||
int
|
||||
der_heim_oid_cmp (
|
||||
const heim_oid */*p*/,
|
||||
const heim_oid */*q*/);
|
||||
|
||||
int
|
||||
der_heim_universal_string_cmp (
|
||||
const heim_universal_string */*p*/,
|
||||
const heim_universal_string */*q*/);
|
||||
|
||||
size_t
|
||||
der_length_bit_string (const heim_bit_string */*k*/);
|
||||
|
||||
size_t
|
||||
der_length_bmp_string (const heim_bmp_string */*data*/);
|
||||
|
||||
size_t
|
||||
der_length_boolean (const int */*k*/);
|
||||
|
||||
size_t
|
||||
der_length_enumerated (const unsigned */*data*/);
|
||||
|
||||
size_t
|
||||
der_length_general_string (const heim_general_string */*data*/);
|
||||
|
||||
size_t
|
||||
der_length_generalized_time (const time_t */*t*/);
|
||||
|
||||
size_t
|
||||
der_length_heim_integer (const heim_integer */*k*/);
|
||||
|
||||
size_t
|
||||
der_length_ia5_string (const heim_ia5_string */*data*/);
|
||||
|
||||
size_t
|
||||
der_length_integer (const int */*data*/);
|
||||
|
||||
size_t
|
||||
der_length_len (size_t /*len*/);
|
||||
|
||||
size_t
|
||||
der_length_octet_string (const heim_octet_string */*k*/);
|
||||
|
||||
size_t
|
||||
der_length_oid (const heim_oid */*k*/);
|
||||
|
||||
size_t
|
||||
der_length_printable_string (const heim_printable_string */*data*/);
|
||||
|
||||
size_t
|
||||
der_length_universal_string (const heim_universal_string */*data*/);
|
||||
|
||||
size_t
|
||||
der_length_unsigned (const unsigned */*data*/);
|
||||
|
||||
size_t
|
||||
der_length_utctime (const time_t */*t*/);
|
||||
|
||||
size_t
|
||||
der_length_utf8string (const heim_utf8_string */*data*/);
|
||||
|
||||
int
|
||||
der_match_tag (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
Der_class /*class*/,
|
||||
Der_type /*type*/,
|
||||
unsigned int /*tag*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_match_tag_and_length (
|
||||
const unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
Der_class /*class*/,
|
||||
Der_type /*type*/,
|
||||
unsigned int /*tag*/,
|
||||
size_t */*length_ret*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_parse_heim_oid (
|
||||
const char */*str*/,
|
||||
const char */*sep*/,
|
||||
heim_oid */*data*/);
|
||||
|
||||
int
|
||||
der_parse_hex_heim_integer (
|
||||
const char */*p*/,
|
||||
heim_integer */*data*/);
|
||||
|
||||
int
|
||||
der_print_heim_oid (
|
||||
const heim_oid */*oid*/,
|
||||
char /*delim*/,
|
||||
char **/*str*/);
|
||||
|
||||
int
|
||||
der_print_hex_heim_integer (
|
||||
const heim_integer */*data*/,
|
||||
char **/*p*/);
|
||||
|
||||
int
|
||||
der_put_bit_string (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_bit_string */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_bmp_string (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_bmp_string */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_boolean (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const int */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_general_string (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_general_string */*str*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_generalized_time (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const time_t */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_heim_integer (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_integer */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_ia5_string (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_ia5_string */*str*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_integer (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const int */*v*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_length (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
size_t /*val*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_length_and_tag (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
size_t /*len_val*/,
|
||||
Der_class /*class*/,
|
||||
Der_type /*type*/,
|
||||
unsigned int /*tag*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_octet_string (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_octet_string */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_oid (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_oid */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_printable_string (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_printable_string */*str*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_tag (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
Der_class /*class*/,
|
||||
Der_type /*type*/,
|
||||
unsigned int /*tag*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_universal_string (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_universal_string */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_unsigned (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const unsigned */*v*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_utctime (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const time_t */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
der_put_utf8string (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_utf8_string */*str*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
encode_heim_any (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_any */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
int
|
||||
encode_heim_any_set (
|
||||
unsigned char */*p*/,
|
||||
size_t /*len*/,
|
||||
const heim_any_set */*data*/,
|
||||
size_t */*size*/);
|
||||
|
||||
void
|
||||
free_heim_any (heim_any */*data*/);
|
||||
|
||||
void
|
||||
free_heim_any_set (heim_any_set */*data*/);
|
||||
|
||||
int
|
||||
heim_any_cmp (
|
||||
const heim_any_set */*p*/,
|
||||
const heim_any_set */*q*/);
|
||||
|
||||
size_t
|
||||
length_heim_any (const heim_any */*data*/);
|
||||
|
||||
size_t
|
||||
length_heim_any_set (const heim_any */*data*/);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __der_protos_h__ */
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
#include <com_err.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <getarg.h>
|
||||
#include <err.h>
|
||||
|
||||
RCSID("$Id: der.c,v 1.2 2005/07/12 06:27:19 lha Exp $");
|
||||
|
||||
|
||||
static const char *class_names[] = {
|
||||
"UNIV", /* 0 */
|
||||
"APPL", /* 1 */
|
||||
"CONTEXT", /* 2 */
|
||||
"PRIVATE" /* 3 */
|
||||
};
|
||||
|
||||
static const char *type_names[] = {
|
||||
"PRIM", /* 0 */
|
||||
"CONS" /* 1 */
|
||||
};
|
||||
|
||||
static const char *tag_names[] = {
|
||||
"EndOfContent", /* 0 */
|
||||
"Boolean", /* 1 */
|
||||
"Integer", /* 2 */
|
||||
"BitString", /* 3 */
|
||||
"OctetString", /* 4 */
|
||||
"Null", /* 5 */
|
||||
"ObjectID", /* 6 */
|
||||
NULL, /* 7 */
|
||||
NULL, /* 8 */
|
||||
NULL, /* 9 */
|
||||
"Enumerated", /* 10 */
|
||||
NULL, /* 11 */
|
||||
NULL, /* 12 */
|
||||
NULL, /* 13 */
|
||||
NULL, /* 14 */
|
||||
NULL, /* 15 */
|
||||
"Sequence", /* 16 */
|
||||
"Set", /* 17 */
|
||||
NULL, /* 18 */
|
||||
"PrintableString", /* 19 */
|
||||
NULL, /* 20 */
|
||||
NULL, /* 21 */
|
||||
"IA5String", /* 22 */
|
||||
"UTCTime", /* 23 */
|
||||
"GeneralizedTime", /* 24 */
|
||||
NULL, /* 25 */
|
||||
"VisibleString", /* 26 */
|
||||
"GeneralString", /* 27 */
|
||||
NULL, /* 28 */
|
||||
NULL, /* 29 */
|
||||
"BMPString" /* 30 */
|
||||
};
|
||||
|
||||
static int
|
||||
get_type(const char *name, const char *list[], unsigned len)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < len; i++)
|
||||
if (list[i] && strcasecmp(list[i], name) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define SIZEOF_ARRAY(a) (sizeof((a))/sizeof((a)[0]))
|
||||
|
||||
const char *
|
||||
der_get_class_name(unsigned num)
|
||||
{
|
||||
if (num >= SIZEOF_ARRAY(class_names))
|
||||
return NULL;
|
||||
return class_names[num];
|
||||
}
|
||||
|
||||
int
|
||||
der_get_class_num(const char *name)
|
||||
{
|
||||
return get_type(name, class_names, SIZEOF_ARRAY(class_names));
|
||||
}
|
||||
|
||||
const char *
|
||||
der_get_type_name(unsigned num)
|
||||
{
|
||||
if (num >= SIZEOF_ARRAY(type_names))
|
||||
return NULL;
|
||||
return type_names[num];
|
||||
}
|
||||
|
||||
int
|
||||
der_get_type_num(const char *name)
|
||||
{
|
||||
return get_type(name, type_names, SIZEOF_ARRAY(type_names));
|
||||
}
|
||||
|
||||
const char *
|
||||
der_get_tag_name(unsigned num)
|
||||
{
|
||||
if (num >= SIZEOF_ARRAY(tag_names))
|
||||
return NULL;
|
||||
return tag_names[num];
|
||||
}
|
||||
|
||||
int
|
||||
der_get_tag_num(const char *name)
|
||||
{
|
||||
return get_type(name, tag_names, SIZEOF_ARRAY(tag_names));
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 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: der.h,v 1.36 2006/10/14 05:16:08 lha Exp $ */
|
||||
|
||||
#ifndef __DER_H__
|
||||
#define __DER_H__
|
||||
|
||||
typedef enum {
|
||||
ASN1_C_UNIV = 0,
|
||||
ASN1_C_APPL = 1,
|
||||
ASN1_C_CONTEXT = 2,
|
||||
ASN1_C_PRIVATE = 3
|
||||
} Der_class;
|
||||
|
||||
typedef enum {PRIM = 0, CONS = 1} Der_type;
|
||||
|
||||
#define MAKE_TAG(CLASS, TYPE, TAG) (((CLASS) << 6) | ((TYPE) << 5) | (TAG))
|
||||
|
||||
/* Universal tags */
|
||||
|
||||
enum {
|
||||
UT_EndOfContent = 0,
|
||||
UT_Boolean = 1,
|
||||
UT_Integer = 2,
|
||||
UT_BitString = 3,
|
||||
UT_OctetString = 4,
|
||||
UT_Null = 5,
|
||||
UT_OID = 6,
|
||||
UT_Enumerated = 10,
|
||||
UT_UTF8String = 12,
|
||||
UT_Sequence = 16,
|
||||
UT_Set = 17,
|
||||
UT_PrintableString = 19,
|
||||
UT_IA5String = 22,
|
||||
UT_UTCTime = 23,
|
||||
UT_GeneralizedTime = 24,
|
||||
UT_UniversalString = 25,
|
||||
UT_VisibleString = 26,
|
||||
UT_GeneralString = 27,
|
||||
UT_BMPString = 30,
|
||||
/* unsupported types */
|
||||
UT_ObjectDescriptor = 7,
|
||||
UT_External = 8,
|
||||
UT_Real = 9,
|
||||
UT_EmbeddedPDV = 11,
|
||||
UT_RelativeOID = 13,
|
||||
UT_NumericString = 18,
|
||||
UT_TeletexString = 20,
|
||||
UT_VideotexString = 21,
|
||||
UT_GraphicString = 25
|
||||
};
|
||||
|
||||
#define ASN1_INDEFINITE 0xdce0deed
|
||||
|
||||
typedef struct heim_der_time_t {
|
||||
time_t dt_sec;
|
||||
unsigned long dt_nsec;
|
||||
} heim_der_time_t;
|
||||
|
||||
typedef struct heim_ber_time_t {
|
||||
time_t bt_sec;
|
||||
unsigned bt_nsec;
|
||||
int bt_zone;
|
||||
} heim_ber_time_t;
|
||||
|
||||
#include <der-protos.h>
|
||||
|
||||
int _heim_fix_dce(size_t reallen, size_t *len);
|
||||
int _heim_der_set_sort(const void *, const void *);
|
||||
int _heim_time2generalizedtime (time_t, heim_octet_string *, int);
|
||||
|
||||
#endif /* __DER_H__ */
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
|
||||
int
|
||||
der_heim_oid_cmp(const heim_oid *p, const heim_oid *q)
|
||||
{
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->components,
|
||||
q->components,
|
||||
p->length * sizeof(*p->components));
|
||||
}
|
||||
|
||||
int
|
||||
der_heim_octet_string_cmp(const heim_octet_string *p,
|
||||
const heim_octet_string *q)
|
||||
{
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->data, q->data, p->length);
|
||||
}
|
||||
|
||||
int
|
||||
der_heim_bit_string_cmp(const heim_bit_string *p,
|
||||
const heim_bit_string *q)
|
||||
{
|
||||
int i, r1, r2;
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
i = memcmp(p->data, q->data, p->length / 8);
|
||||
if (i)
|
||||
return i;
|
||||
if ((p->length % 8) == 0)
|
||||
return 0;
|
||||
i = (p->length / 8);
|
||||
r1 = ((unsigned char *)p->data)[i];
|
||||
r2 = ((unsigned char *)q->data)[i];
|
||||
i = 8 - (p->length % 8);
|
||||
r1 = r1 >> i;
|
||||
r2 = r2 >> i;
|
||||
return r1 - r2;
|
||||
}
|
||||
|
||||
int
|
||||
der_heim_integer_cmp(const heim_integer *p,
|
||||
const heim_integer *q)
|
||||
{
|
||||
if (p->negative != q->negative)
|
||||
return q->negative - p->negative;
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->data, q->data, p->length);
|
||||
}
|
||||
|
||||
int
|
||||
der_heim_bmp_string_cmp(const heim_bmp_string *p, const heim_bmp_string *q)
|
||||
{
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->data, q->data, q->length * sizeof(q->data[0]));
|
||||
}
|
||||
|
||||
int
|
||||
der_heim_universal_string_cmp(const heim_universal_string *p,
|
||||
const heim_universal_string *q)
|
||||
{
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->data, q->data, q->length * sizeof(q->data[0]));
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 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.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
|
||||
RCSID("$Id: der_copy.c,v 1.16 2006/10/14 05:30:02 lha Exp $");
|
||||
|
||||
int
|
||||
der_copy_general_string (const heim_general_string *from,
|
||||
heim_general_string *to)
|
||||
{
|
||||
*to = strdup(*from);
|
||||
if(*to == NULL)
|
||||
return ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_utf8string (const heim_utf8_string *from, heim_utf8_string *to)
|
||||
{
|
||||
return der_copy_general_string(from, to);
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_printable_string (const heim_printable_string *from,
|
||||
heim_printable_string *to)
|
||||
{
|
||||
return der_copy_general_string(from, to);
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_ia5_string (const heim_printable_string *from,
|
||||
heim_printable_string *to)
|
||||
{
|
||||
return der_copy_general_string(from, to);
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_bmp_string (const heim_bmp_string *from, heim_bmp_string *to)
|
||||
{
|
||||
to->length = from->length;
|
||||
to->data = malloc(to->length * sizeof(to->data[0]));
|
||||
if(to->length != 0 && to->data == NULL)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_universal_string (const heim_universal_string *from,
|
||||
heim_universal_string *to)
|
||||
{
|
||||
to->length = from->length;
|
||||
to->data = malloc(to->length * sizeof(to->data[0]));
|
||||
if(to->length != 0 && to->data == NULL)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, to->length * sizeof(to->data[0]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_octet_string (const heim_octet_string *from, heim_octet_string *to)
|
||||
{
|
||||
to->length = from->length;
|
||||
to->data = malloc(to->length);
|
||||
if(to->length != 0 && to->data == NULL)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, to->length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_heim_integer (const heim_integer *from, heim_integer *to)
|
||||
{
|
||||
to->length = from->length;
|
||||
to->data = malloc(to->length);
|
||||
if(to->length != 0 && to->data == NULL)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, to->length);
|
||||
to->negative = from->negative;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_oid (const heim_oid *from, heim_oid *to)
|
||||
{
|
||||
to->length = from->length;
|
||||
to->components = malloc(to->length * sizeof(*to->components));
|
||||
if (to->length != 0 && to->components == NULL)
|
||||
return ENOMEM;
|
||||
memcpy(to->components, from->components,
|
||||
to->length * sizeof(*to->components));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_copy_bit_string (const heim_bit_string *from, heim_bit_string *to)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = (from->length + 7) / 8;
|
||||
to->length = from->length;
|
||||
to->data = malloc(len);
|
||||
if(len != 0 && to->data == NULL)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, len);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
#include <hex.h>
|
||||
|
||||
RCSID("$Id: der_format.c,v 1.6 2006/10/21 18:24:15 lha Exp $");
|
||||
|
||||
int
|
||||
der_parse_hex_heim_integer (const char *p, heim_integer *data)
|
||||
{
|
||||
ssize_t len;
|
||||
|
||||
data->length = 0;
|
||||
data->negative = 0;
|
||||
data->data = NULL;
|
||||
|
||||
if (*p == '-') {
|
||||
p++;
|
||||
data->negative = 1;
|
||||
}
|
||||
|
||||
len = strlen(p);
|
||||
if (len < 0) {
|
||||
data->data = NULL;
|
||||
data->length = 0;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
data->length = (len / 2) + 1;
|
||||
data->data = malloc(data->length);
|
||||
if (data->data == NULL) {
|
||||
data->length = 0;
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
len = hex_decode(p, data->data, data->length);
|
||||
if (len < 0) {
|
||||
free(data->data);
|
||||
data->data = NULL;
|
||||
data->length = 0;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char *q = data->data;
|
||||
while(*q == 0 && len > 0) {
|
||||
q++;
|
||||
len--;
|
||||
}
|
||||
data->length = len;
|
||||
memmove(data->data, q, len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_print_hex_heim_integer (const heim_integer *data, char **p)
|
||||
{
|
||||
ssize_t len;
|
||||
char *q;
|
||||
|
||||
len = hex_encode(data->data, data->length, p);
|
||||
if (len < 0)
|
||||
return ENOMEM;
|
||||
|
||||
if (data->negative) {
|
||||
len = asprintf(&q, "-%s", *p);
|
||||
free(*p);
|
||||
if (len < 0)
|
||||
return ENOMEM;
|
||||
*p = q;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_print_heim_oid (const heim_oid *oid, char delim, char **str)
|
||||
{
|
||||
struct rk_strpool *p = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < oid->length ; i++) {
|
||||
p = rk_strpoolprintf(p, "%d%s",
|
||||
oid->components[i],
|
||||
i < oid->length - 1 ? " " : "");
|
||||
if (p == NULL) {
|
||||
*str = NULL;
|
||||
return ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
*str = rk_strpoolcollect(p);
|
||||
if (*str == NULL)
|
||||
return ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_parse_heim_oid (const char *str, const char *sep, heim_oid *data)
|
||||
{
|
||||
char *s, *w, *brkt, *endptr;
|
||||
unsigned int *c;
|
||||
long l;
|
||||
|
||||
data->length = 0;
|
||||
data->components = NULL;
|
||||
|
||||
if (sep == NULL)
|
||||
sep = ".";
|
||||
|
||||
s = strdup(str);
|
||||
|
||||
for (w = strtok_r(s, sep, &brkt);
|
||||
w != NULL;
|
||||
w = strtok_r(NULL, sep, &brkt)) {
|
||||
|
||||
c = realloc(data->components,
|
||||
(data->length + 1) * sizeof(data->components[0]));
|
||||
if (c == NULL) {
|
||||
der_free_oid(data);
|
||||
free(s);
|
||||
return ENOMEM;
|
||||
}
|
||||
data->components = c;
|
||||
|
||||
l = strtol(w, &endptr, 10);
|
||||
if (*endptr != '\0' || l < 0 || l > INT_MAX) {
|
||||
der_free_oid(data);
|
||||
free(s);
|
||||
return EINVAL;
|
||||
}
|
||||
data->components[data->length++] = l;
|
||||
}
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
|
||||
RCSID("$Id: der_free.c,v 1.13 2006/10/14 05:30:47 lha Exp $");
|
||||
|
||||
void
|
||||
der_free_general_string (heim_general_string *str)
|
||||
{
|
||||
free(*str);
|
||||
*str = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_utf8string (heim_utf8_string *str)
|
||||
{
|
||||
free(*str);
|
||||
*str = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_printable_string (heim_printable_string *str)
|
||||
{
|
||||
free(*str);
|
||||
*str = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_ia5_string (heim_ia5_string *str)
|
||||
{
|
||||
free(*str);
|
||||
*str = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_bmp_string (heim_bmp_string *k)
|
||||
{
|
||||
free(k->data);
|
||||
k->data = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_universal_string (heim_universal_string *k)
|
||||
{
|
||||
free(k->data);
|
||||
k->data = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_octet_string (heim_octet_string *k)
|
||||
{
|
||||
free(k->data);
|
||||
k->data = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_heim_integer (heim_integer *k)
|
||||
{
|
||||
free(k->data);
|
||||
k->data = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_oid (heim_oid *k)
|
||||
{
|
||||
free(k->components);
|
||||
k->components = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
der_free_bit_string (heim_bit_string *k)
|
||||
{
|
||||
free(k->data);
|
||||
k->data = NULL;
|
||||
k->length = 0;
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
|
||||
RCSID("$Id: der_get.c,v 1.50 2006/10/19 16:27:44 lha Exp $");
|
||||
|
||||
#include <version.h>
|
||||
|
||||
/*
|
||||
* All decoding functions take a pointer `p' to first position in
|
||||
* which to read, from the left, `len' which means the maximum number
|
||||
* of characters we are able to read, `ret' were the value will be
|
||||
* returned and `size' where the number of used bytes is stored.
|
||||
* Either 0 or an error code is returned.
|
||||
*/
|
||||
|
||||
int
|
||||
der_get_unsigned (const unsigned char *p, size_t len,
|
||||
unsigned *ret, size_t *size)
|
||||
{
|
||||
unsigned val = 0;
|
||||
size_t oldlen = len;
|
||||
|
||||
if (len == sizeof(unsigned) + 1 && p[0] == 0)
|
||||
;
|
||||
else if (len > sizeof(unsigned))
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
while (len--)
|
||||
val = val * 256 + *p++;
|
||||
*ret = val;
|
||||
if(size) *size = oldlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_integer (const unsigned char *p, size_t len,
|
||||
int *ret, size_t *size)
|
||||
{
|
||||
int val = 0;
|
||||
size_t oldlen = len;
|
||||
|
||||
if (len > sizeof(int))
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
if (len > 0) {
|
||||
val = (signed char)*p++;
|
||||
while (--len)
|
||||
val = val * 256 + *p++;
|
||||
}
|
||||
*ret = val;
|
||||
if(size) *size = oldlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_length (const unsigned char *p, size_t len,
|
||||
size_t *val, size_t *size)
|
||||
{
|
||||
size_t v;
|
||||
|
||||
if (len <= 0)
|
||||
return ASN1_OVERRUN;
|
||||
--len;
|
||||
v = *p++;
|
||||
if (v < 128) {
|
||||
*val = v;
|
||||
if(size) *size = 1;
|
||||
} else {
|
||||
int e;
|
||||
size_t l;
|
||||
unsigned tmp;
|
||||
|
||||
if(v == 0x80){
|
||||
*val = ASN1_INDEFINITE;
|
||||
if(size) *size = 1;
|
||||
return 0;
|
||||
}
|
||||
v &= 0x7F;
|
||||
if (len < v)
|
||||
return ASN1_OVERRUN;
|
||||
e = der_get_unsigned (p, v, &tmp, &l);
|
||||
if(e) return e;
|
||||
*val = tmp;
|
||||
if(size) *size = l + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_boolean(const unsigned char *p, size_t len, int *data, size_t *size)
|
||||
{
|
||||
if(len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
if(*p != 0)
|
||||
*data = 1;
|
||||
else
|
||||
*data = 0;
|
||||
*size = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_general_string (const unsigned char *p, size_t len,
|
||||
heim_general_string *str, size_t *size)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (len > len + 1)
|
||||
return ASN1_BAD_LENGTH;
|
||||
|
||||
s = malloc (len + 1);
|
||||
if (s == NULL)
|
||||
return ENOMEM;
|
||||
memcpy (s, p, len);
|
||||
s[len] = '\0';
|
||||
*str = s;
|
||||
if(size) *size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_utf8string (const unsigned char *p, size_t len,
|
||||
heim_utf8_string *str, size_t *size)
|
||||
{
|
||||
return der_get_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_get_printable_string (const unsigned char *p, size_t len,
|
||||
heim_printable_string *str, size_t *size)
|
||||
{
|
||||
return der_get_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_get_ia5_string (const unsigned char *p, size_t len,
|
||||
heim_ia5_string *str, size_t *size)
|
||||
{
|
||||
return der_get_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_get_bmp_string (const unsigned char *p, size_t len,
|
||||
heim_bmp_string *data, size_t *size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (len & 1)
|
||||
return ASN1_BAD_FORMAT;
|
||||
data->length = len / 2;
|
||||
data->data = malloc(data->length * sizeof(data->data[0]));
|
||||
if (data->data == NULL && data->length != 0)
|
||||
return ENOMEM;
|
||||
|
||||
for (i = 0; i < data->length; i++) {
|
||||
data->data[i] = (p[0] << 8) | p[1];
|
||||
p += 2;
|
||||
}
|
||||
if (size) *size = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_universal_string (const unsigned char *p, size_t len,
|
||||
heim_universal_string *data, size_t *size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (len & 3)
|
||||
return ASN1_BAD_FORMAT;
|
||||
data->length = len / 4;
|
||||
data->data = malloc(data->length * sizeof(data->data[0]));
|
||||
if (data->data == NULL && data->length != 0)
|
||||
return ENOMEM;
|
||||
|
||||
for (i = 0; i < data->length; i++) {
|
||||
data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
||||
p += 4;
|
||||
}
|
||||
if (size) *size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_octet_string (const unsigned char *p, size_t len,
|
||||
heim_octet_string *data, size_t *size)
|
||||
{
|
||||
data->length = len;
|
||||
data->data = malloc(len);
|
||||
if (data->data == NULL && data->length != 0)
|
||||
return ENOMEM;
|
||||
memcpy (data->data, p, len);
|
||||
if(size) *size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_heim_integer (const unsigned char *p, size_t len,
|
||||
heim_integer *data, size_t *size)
|
||||
{
|
||||
data->length = 0;
|
||||
data->negative = 0;
|
||||
data->data = NULL;
|
||||
|
||||
if (len == 0) {
|
||||
if (size)
|
||||
*size = 0;
|
||||
return 0;
|
||||
}
|
||||
if (p[0] & 0x80) {
|
||||
unsigned char *q;
|
||||
int carry = 1;
|
||||
data->negative = 1;
|
||||
|
||||
data->length = len;
|
||||
|
||||
if (p[0] == 0xff) {
|
||||
p++;
|
||||
data->length--;
|
||||
}
|
||||
data->data = malloc(data->length);
|
||||
if (data->data == NULL) {
|
||||
data->length = 0;
|
||||
if (size)
|
||||
*size = 0;
|
||||
return ENOMEM;
|
||||
}
|
||||
q = &((unsigned char*)data->data)[data->length - 1];
|
||||
p += data->length - 1;
|
||||
while (q >= (unsigned char*)data->data) {
|
||||
*q = *p ^ 0xff;
|
||||
if (carry)
|
||||
carry = !++*q;
|
||||
p--;
|
||||
q--;
|
||||
}
|
||||
} else {
|
||||
data->negative = 0;
|
||||
data->length = len;
|
||||
|
||||
if (p[0] == 0) {
|
||||
p++;
|
||||
data->length--;
|
||||
}
|
||||
data->data = malloc(data->length);
|
||||
if (data->data == NULL && data->length != 0) {
|
||||
data->length = 0;
|
||||
if (size)
|
||||
*size = 0;
|
||||
return ENOMEM;
|
||||
}
|
||||
memcpy(data->data, p, data->length);
|
||||
}
|
||||
if (size)
|
||||
*size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
generalizedtime2time (const char *s, time_t *t)
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
if (sscanf (s, "%04d%02d%02d%02d%02d%02dZ",
|
||||
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
|
||||
&tm.tm_min, &tm.tm_sec) != 6) {
|
||||
if (sscanf (s, "%02d%02d%02d%02d%02d%02dZ",
|
||||
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour,
|
||||
&tm.tm_min, &tm.tm_sec) != 6)
|
||||
return ASN1_BAD_TIMEFORMAT;
|
||||
if (tm.tm_year < 50)
|
||||
tm.tm_year += 2000;
|
||||
else
|
||||
tm.tm_year += 1900;
|
||||
}
|
||||
tm.tm_year -= 1900;
|
||||
tm.tm_mon -= 1;
|
||||
*t = _der_timegm (&tm);
|
||||
return 0;
|
||||
}
|
||||
#undef timegm
|
||||
|
||||
static int
|
||||
der_get_time (const unsigned char *p, size_t len,
|
||||
time_t *data, size_t *size)
|
||||
{
|
||||
heim_octet_string k;
|
||||
char *times;
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = der_get_octet_string (p, len, &k, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
times = realloc(k.data, k.length + 1);
|
||||
if (times == NULL){
|
||||
free(k.data);
|
||||
return ENOMEM;
|
||||
}
|
||||
times[k.length] = 0;
|
||||
e = generalizedtime2time(times, data);
|
||||
free (times);
|
||||
if(size) *size = ret;
|
||||
return e;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_generalized_time (const unsigned char *p, size_t len,
|
||||
time_t *data, size_t *size)
|
||||
{
|
||||
return der_get_time(p, len, data, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_get_utctime (const unsigned char *p, size_t len,
|
||||
time_t *data, size_t *size)
|
||||
{
|
||||
return der_get_time(p, len, data, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_get_oid (const unsigned char *p, size_t len,
|
||||
heim_oid *data, size_t *size)
|
||||
{
|
||||
int n;
|
||||
size_t oldlen = len;
|
||||
|
||||
if (len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
|
||||
if (len > len + 1)
|
||||
return ASN1_BAD_LENGTH;
|
||||
|
||||
data->components = malloc((len + 1) * sizeof(*data->components));
|
||||
if (data->components == NULL)
|
||||
return ENOMEM;
|
||||
data->components[0] = (*p) / 40;
|
||||
data->components[1] = (*p) % 40;
|
||||
--len;
|
||||
++p;
|
||||
for (n = 2; len > 0; ++n) {
|
||||
unsigned u = 0, u1;
|
||||
|
||||
do {
|
||||
--len;
|
||||
u1 = u * 128 + (*p++ % 128);
|
||||
/* check that we don't overflow the element */
|
||||
if (u1 < u) {
|
||||
der_free_oid(data);
|
||||
return ASN1_OVERRUN;
|
||||
}
|
||||
u = u1;
|
||||
} while (len > 0 && p[-1] & 0x80);
|
||||
data->components[n] = u;
|
||||
}
|
||||
if (n > 2 && p[-1] & 0x80) {
|
||||
der_free_oid (data);
|
||||
return ASN1_OVERRUN;
|
||||
}
|
||||
data->length = n;
|
||||
if (size)
|
||||
*size = oldlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_tag (const unsigned char *p, size_t len,
|
||||
Der_class *class, Der_type *type,
|
||||
unsigned int *tag, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
if (len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
*class = (Der_class)(((*p) >> 6) & 0x03);
|
||||
*type = (Der_type)(((*p) >> 5) & 0x01);
|
||||
*tag = (*p) & 0x1f;
|
||||
p++; len--; ret++;
|
||||
if(*tag == 0x1f) {
|
||||
unsigned int continuation;
|
||||
unsigned int tag1;
|
||||
*tag = 0;
|
||||
do {
|
||||
if(len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
continuation = *p & 128;
|
||||
tag1 = *tag * 128 + (*p % 128);
|
||||
/* check that we don't overflow the tag */
|
||||
if (tag1 < *tag)
|
||||
return ASN1_OVERFLOW;
|
||||
*tag = tag1;
|
||||
p++; len--; ret++;
|
||||
} while(continuation);
|
||||
}
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_match_tag (const unsigned char *p, size_t len,
|
||||
Der_class class, Der_type type,
|
||||
unsigned int tag, size_t *size)
|
||||
{
|
||||
size_t l;
|
||||
Der_class thisclass;
|
||||
Der_type thistype;
|
||||
unsigned int thistag;
|
||||
int e;
|
||||
|
||||
e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
|
||||
if (e) return e;
|
||||
if (class != thisclass || type != thistype)
|
||||
return ASN1_BAD_ID;
|
||||
if(tag > thistag)
|
||||
return ASN1_MISPLACED_FIELD;
|
||||
if(tag < thistag)
|
||||
return ASN1_MISSING_FIELD;
|
||||
if(size) *size = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_match_tag_and_length (const unsigned char *p, size_t len,
|
||||
Der_class class, Der_type type, unsigned int tag,
|
||||
size_t *length_ret, size_t *size)
|
||||
{
|
||||
size_t l, ret = 0;
|
||||
int e;
|
||||
|
||||
e = der_match_tag (p, len, class, type, tag, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
e = der_get_length (p, len, length_ret, &l);
|
||||
if (e) return e;
|
||||
p += l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
if(size) *size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Old versions of DCE was based on a very early beta of the MIT code,
|
||||
* which used MAVROS for ASN.1 encoding. MAVROS had the interesting
|
||||
* feature that it encoded data in the forward direction, which has
|
||||
* it's problems, since you have no idea how long the data will be
|
||||
* until after you're done. MAVROS solved this by reserving one byte
|
||||
* for length, and later, if the actual length was longer, it reverted
|
||||
* to indefinite, BER style, lengths. The version of MAVROS used by
|
||||
* the DCE people could apparently generate correct X.509 DER encodings, and
|
||||
* did this by making space for the length after encoding, but
|
||||
* unfortunately this feature wasn't used with Kerberos.
|
||||
*/
|
||||
|
||||
int
|
||||
_heim_fix_dce(size_t reallen, size_t *len)
|
||||
{
|
||||
if(reallen == ASN1_INDEFINITE)
|
||||
return 1;
|
||||
if(*len < reallen)
|
||||
return -1;
|
||||
*len = reallen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_get_bit_string (const unsigned char *p, size_t len,
|
||||
heim_bit_string *data, size_t *size)
|
||||
{
|
||||
if (len < 1)
|
||||
return ASN1_OVERRUN;
|
||||
if (p[0] > 7)
|
||||
return ASN1_BAD_FORMAT;
|
||||
if (len - 1 == 0 && p[0] != 0)
|
||||
return ASN1_BAD_FORMAT;
|
||||
/* check if any of the three upper bits are set
|
||||
* any of them will cause a interger overrun */
|
||||
if ((len - 1) >> (sizeof(len) * 8 - 3))
|
||||
return ASN1_OVERRUN;
|
||||
data->length = (len - 1) * 8;
|
||||
data->data = malloc(len - 1);
|
||||
if (data->data == NULL && (len - 1) != 0)
|
||||
return ENOMEM;
|
||||
memcpy (data->data, p + 1, len - 1);
|
||||
data->length -= p[0];
|
||||
if(size) *size = len;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
|
||||
RCSID("$Id: der_length.c,v 1.19 2006/10/14 05:26:06 lha Exp $");
|
||||
|
||||
size_t
|
||||
_heim_len_unsigned (unsigned val)
|
||||
{
|
||||
size_t ret = 0;
|
||||
int last_val_gt_128;
|
||||
|
||||
do {
|
||||
++ret;
|
||||
last_val_gt_128 = (val >= 128);
|
||||
val /= 256;
|
||||
} while (val);
|
||||
|
||||
if(last_val_gt_128)
|
||||
ret++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
_heim_len_int (int val)
|
||||
{
|
||||
unsigned char q;
|
||||
size_t ret = 0;
|
||||
|
||||
if (val >= 0) {
|
||||
do {
|
||||
q = val % 256;
|
||||
ret++;
|
||||
val /= 256;
|
||||
} while(val);
|
||||
if(q >= 128)
|
||||
ret++;
|
||||
} else {
|
||||
val = ~val;
|
||||
do {
|
||||
q = ~(val % 256);
|
||||
ret++;
|
||||
val /= 256;
|
||||
} while(val);
|
||||
if(q < 128)
|
||||
ret++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static size_t
|
||||
len_oid (const heim_oid *oid)
|
||||
{
|
||||
size_t ret = 1;
|
||||
int n;
|
||||
|
||||
for (n = 2; n < oid->length; ++n) {
|
||||
unsigned u = oid->components[n];
|
||||
|
||||
do {
|
||||
++ret;
|
||||
u /= 128;
|
||||
} while(u > 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_len (size_t len)
|
||||
{
|
||||
if (len < 128)
|
||||
return 1;
|
||||
else {
|
||||
int ret = 0;
|
||||
do {
|
||||
++ret;
|
||||
len /= 256;
|
||||
} while (len);
|
||||
return ret + 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_integer (const int *data)
|
||||
{
|
||||
return _heim_len_int (*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_unsigned (const unsigned *data)
|
||||
{
|
||||
return _heim_len_unsigned(*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_enumerated (const unsigned *data)
|
||||
{
|
||||
return _heim_len_int (*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_general_string (const heim_general_string *data)
|
||||
{
|
||||
return strlen(*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_utf8string (const heim_utf8_string *data)
|
||||
{
|
||||
return strlen(*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_printable_string (const heim_printable_string *data)
|
||||
{
|
||||
return strlen(*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_ia5_string (const heim_ia5_string *data)
|
||||
{
|
||||
return strlen(*data);
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_bmp_string (const heim_bmp_string *data)
|
||||
{
|
||||
return data->length * 2;
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_universal_string (const heim_universal_string *data)
|
||||
{
|
||||
return data->length * 4;
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_octet_string (const heim_octet_string *k)
|
||||
{
|
||||
return k->length;
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_heim_integer (const heim_integer *k)
|
||||
{
|
||||
if (k->length == 0)
|
||||
return 1;
|
||||
if (k->negative)
|
||||
return k->length + (((~(((unsigned char *)k->data)[0])) & 0x80) ? 0 : 1);
|
||||
else
|
||||
return k->length + ((((unsigned char *)k->data)[0] & 0x80) ? 1 : 0);
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_oid (const heim_oid *k)
|
||||
{
|
||||
return len_oid (k);
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_generalized_time (const time_t *t)
|
||||
{
|
||||
heim_octet_string k;
|
||||
size_t ret;
|
||||
|
||||
_heim_time2generalizedtime (*t, &k, 1);
|
||||
ret = k.length;
|
||||
free(k.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_utctime (const time_t *t)
|
||||
{
|
||||
heim_octet_string k;
|
||||
size_t ret;
|
||||
|
||||
_heim_time2generalizedtime (*t, &k, 0);
|
||||
ret = k.length;
|
||||
free(k.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_boolean (const int *k)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
der_length_bit_string (const heim_bit_string *k)
|
||||
{
|
||||
return (k->length + 7) / 8 + 1;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2002, 2004 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id: der_locl.h,v 1.8 2006/10/19 16:24:02 lha Exp $ */
|
||||
|
||||
#ifndef __DER_LOCL_H__
|
||||
#define __DER_LOCL_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <roken.h>
|
||||
|
||||
#include <asn1-common.h>
|
||||
#include <asn1_err.h>
|
||||
#include <der.h>
|
||||
|
||||
time_t _der_timegm (struct tm *);
|
||||
size_t _heim_len_unsigned (unsigned);
|
||||
size_t _heim_len_int (int);
|
||||
|
||||
#endif /* __DER_LOCL_H__ */
|
||||
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
|
||||
RCSID("$Id: der_put.c,v 1.33 2005/07/12 06:27:23 lha Exp $");
|
||||
|
||||
/*
|
||||
* All encoding functions take a pointer `p' to first position in
|
||||
* which to write, from the right, `len' which means the maximum
|
||||
* number of characters we are able to write. The function returns
|
||||
* the number of characters written in `size' (if non-NULL).
|
||||
* The return value is 0 or an error.
|
||||
*/
|
||||
|
||||
int
|
||||
der_put_unsigned (unsigned char *p, size_t len, const unsigned *v, size_t *size)
|
||||
{
|
||||
unsigned char *base = p;
|
||||
unsigned val = *v;
|
||||
|
||||
if (val) {
|
||||
while (len > 0 && val) {
|
||||
*p-- = val % 256;
|
||||
val /= 256;
|
||||
--len;
|
||||
}
|
||||
if (val != 0)
|
||||
return ASN1_OVERFLOW;
|
||||
else {
|
||||
if(p[1] >= 128) {
|
||||
if(len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 0;
|
||||
}
|
||||
*size = base - p;
|
||||
return 0;
|
||||
}
|
||||
} else if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
else {
|
||||
*p = 0;
|
||||
*size = 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
der_put_integer (unsigned char *p, size_t len, const int *v, size_t *size)
|
||||
{
|
||||
unsigned char *base = p;
|
||||
int val = *v;
|
||||
|
||||
if(val >= 0) {
|
||||
do {
|
||||
if(len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = val % 256;
|
||||
len--;
|
||||
val /= 256;
|
||||
} while(val);
|
||||
if(p[1] >= 128) {
|
||||
if(len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 0;
|
||||
len--;
|
||||
}
|
||||
} else {
|
||||
val = ~val;
|
||||
do {
|
||||
if(len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = ~(val % 256);
|
||||
len--;
|
||||
val /= 256;
|
||||
} while(val);
|
||||
if(p[1] < 128) {
|
||||
if(len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 0xff;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
*size = base - p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
der_put_length (unsigned char *p, size_t len, size_t val, size_t *size)
|
||||
{
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
|
||||
if (val < 128) {
|
||||
*p = val;
|
||||
*size = 1;
|
||||
} else {
|
||||
size_t l = 0;
|
||||
|
||||
while(val > 0) {
|
||||
if(len < 2)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = val % 256;
|
||||
val /= 256;
|
||||
len--;
|
||||
l++;
|
||||
}
|
||||
*p = 0x80 | l;
|
||||
if(size)
|
||||
*size = l + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_boolean(unsigned char *p, size_t len, const int *data, size_t *size)
|
||||
{
|
||||
if(len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
if(*data != 0)
|
||||
*p = 0xff;
|
||||
else
|
||||
*p = 0;
|
||||
*size = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_general_string (unsigned char *p, size_t len,
|
||||
const heim_general_string *str, size_t *size)
|
||||
{
|
||||
size_t slen = strlen(*str);
|
||||
|
||||
if (len < slen)
|
||||
return ASN1_OVERFLOW;
|
||||
p -= slen;
|
||||
len -= slen;
|
||||
memcpy (p+1, *str, slen);
|
||||
*size = slen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_utf8string (unsigned char *p, size_t len,
|
||||
const heim_utf8_string *str, size_t *size)
|
||||
{
|
||||
return der_put_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_put_printable_string (unsigned char *p, size_t len,
|
||||
const heim_printable_string *str, size_t *size)
|
||||
{
|
||||
return der_put_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_put_ia5_string (unsigned char *p, size_t len,
|
||||
const heim_ia5_string *str, size_t *size)
|
||||
{
|
||||
return der_put_general_string(p, len, str, size);
|
||||
}
|
||||
|
||||
int
|
||||
der_put_bmp_string (unsigned char *p, size_t len,
|
||||
const heim_bmp_string *data, size_t *size)
|
||||
{
|
||||
size_t i;
|
||||
if (len / 2 < data->length)
|
||||
return ASN1_OVERFLOW;
|
||||
p -= data->length * 2;
|
||||
len -= data->length * 2;
|
||||
for (i = 0; i < data->length; i++) {
|
||||
p[1] = (data->data[i] >> 8) & 0xff;
|
||||
p[2] = data->data[i] & 0xff;
|
||||
p += 2;
|
||||
}
|
||||
if (size) *size = data->length * 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_universal_string (unsigned char *p, size_t len,
|
||||
const heim_universal_string *data, size_t *size)
|
||||
{
|
||||
size_t i;
|
||||
if (len / 4 < data->length)
|
||||
return ASN1_OVERFLOW;
|
||||
p -= data->length * 4;
|
||||
len -= data->length * 4;
|
||||
for (i = 0; i < data->length; i++) {
|
||||
p[1] = (data->data[i] >> 24) & 0xff;
|
||||
p[2] = (data->data[i] >> 16) & 0xff;
|
||||
p[3] = (data->data[i] >> 8) & 0xff;
|
||||
p[4] = data->data[i] & 0xff;
|
||||
p += 4;
|
||||
}
|
||||
if (size) *size = data->length * 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_octet_string (unsigned char *p, size_t len,
|
||||
const heim_octet_string *data, size_t *size)
|
||||
{
|
||||
if (len < data->length)
|
||||
return ASN1_OVERFLOW;
|
||||
p -= data->length;
|
||||
len -= data->length;
|
||||
memcpy (p+1, data->data, data->length);
|
||||
*size = data->length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_heim_integer (unsigned char *p, size_t len,
|
||||
const heim_integer *data, size_t *size)
|
||||
{
|
||||
unsigned char *buf = data->data;
|
||||
int hibitset = 0;
|
||||
|
||||
if (data->length == 0) {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 0;
|
||||
if (size)
|
||||
*size = 1;
|
||||
return 0;
|
||||
}
|
||||
if (len < data->length)
|
||||
return ASN1_OVERFLOW;
|
||||
|
||||
len -= data->length;
|
||||
|
||||
if (data->negative) {
|
||||
int i, carry;
|
||||
for (i = data->length - 1, carry = 1; i >= 0; i--) {
|
||||
*p = buf[i] ^ 0xff;
|
||||
if (carry)
|
||||
carry = !++*p;
|
||||
p--;
|
||||
}
|
||||
if (p[1] < 128) {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 0xff;
|
||||
len--;
|
||||
hibitset = 1;
|
||||
}
|
||||
} else {
|
||||
p -= data->length;
|
||||
memcpy(p + 1, buf, data->length);
|
||||
|
||||
if (p[1] >= 128) {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
p[0] = 0;
|
||||
len--;
|
||||
hibitset = 1;
|
||||
}
|
||||
}
|
||||
if (size)
|
||||
*size = data->length + hibitset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_generalized_time (unsigned char *p, size_t len,
|
||||
const time_t *data, size_t *size)
|
||||
{
|
||||
heim_octet_string k;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = _heim_time2generalizedtime (*data, &k, 1);
|
||||
if (e)
|
||||
return e;
|
||||
e = der_put_octet_string(p, len, &k, &l);
|
||||
free(k.data);
|
||||
if(e)
|
||||
return e;
|
||||
if(size)
|
||||
*size = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_utctime (unsigned char *p, size_t len,
|
||||
const time_t *data, size_t *size)
|
||||
{
|
||||
heim_octet_string k;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = _heim_time2generalizedtime (*data, &k, 0);
|
||||
if (e)
|
||||
return e;
|
||||
e = der_put_octet_string(p, len, &k, &l);
|
||||
free(k.data);
|
||||
if(e)
|
||||
return e;
|
||||
if(size)
|
||||
*size = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_oid (unsigned char *p, size_t len,
|
||||
const heim_oid *data, size_t *size)
|
||||
{
|
||||
unsigned char *base = p;
|
||||
int n;
|
||||
|
||||
for (n = data->length - 1; n >= 2; --n) {
|
||||
unsigned u = data->components[n];
|
||||
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = u % 128;
|
||||
u /= 128;
|
||||
--len;
|
||||
while (u > 0) {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 128 + u % 128;
|
||||
u /= 128;
|
||||
--len;
|
||||
}
|
||||
}
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = 40 * data->components[0] + data->components[1];
|
||||
*size = base - p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
|
||||
unsigned int tag, size_t *size)
|
||||
{
|
||||
if (tag <= 30) {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p = MAKE_TAG(class, type, tag);
|
||||
*size = 1;
|
||||
} else {
|
||||
size_t ret = 0;
|
||||
unsigned int continuation = 0;
|
||||
|
||||
do {
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = tag % 128 | continuation;
|
||||
len--;
|
||||
ret++;
|
||||
tag /= 128;
|
||||
continuation = 0x80;
|
||||
} while(tag > 0);
|
||||
if (len < 1)
|
||||
return ASN1_OVERFLOW;
|
||||
*p-- = MAKE_TAG(class, type, 0x1f);
|
||||
ret++;
|
||||
*size = ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val,
|
||||
Der_class class, Der_type type,
|
||||
unsigned int tag, size_t *size)
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t l;
|
||||
int e;
|
||||
|
||||
e = der_put_length (p, len, len_val, &l);
|
||||
if(e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
e = der_put_tag (p, len, class, type, tag, &l);
|
||||
if(e)
|
||||
return e;
|
||||
p -= l;
|
||||
len -= l;
|
||||
ret += l;
|
||||
*size = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep)
|
||||
{
|
||||
struct tm *tm;
|
||||
const size_t len = gtimep ? 15 : 13;
|
||||
|
||||
s->data = malloc(len + 1);
|
||||
if (s->data == NULL)
|
||||
return ENOMEM;
|
||||
s->length = len;
|
||||
tm = gmtime (&t);
|
||||
if (gtimep)
|
||||
snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
else
|
||||
snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ",
|
||||
tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
der_put_bit_string (unsigned char *p, size_t len,
|
||||
const heim_bit_string *data, size_t *size)
|
||||
{
|
||||
size_t data_size = (data->length + 7) / 8;
|
||||
if (len < data_size + 1)
|
||||
return ASN1_OVERFLOW;
|
||||
p -= data_size + 1;
|
||||
len -= data_size + 1;
|
||||
memcpy (p+2, data->data, data_size);
|
||||
if (data->length && (data->length % 8) != 0)
|
||||
p[1] = 8 - (data->length % 8);
|
||||
else
|
||||
p[1] = 0;
|
||||
*size = data_size + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_heim_der_set_sort(const void *a1, const void *a2)
|
||||
{
|
||||
const struct heim_octet_string *s1 = a1, *s2 = a2;
|
||||
int ret;
|
||||
|
||||
ret = memcmp(s1->data, s2->data,
|
||||
s1->length < s2->length ? s1->length : s2->length);
|
||||
if(ret)
|
||||
return ret;
|
||||
return s1->length - s2->length;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
-- $Id: digest.asn1,v 1.9 2006/08/25 11:57:54 lha Exp $
|
||||
|
||||
DIGEST DEFINITIONS ::=
|
||||
BEGIN
|
||||
|
||||
IMPORTS EncryptedData, Principal FROM krb5;
|
||||
|
||||
DigestInit ::= SEQUENCE {
|
||||
type UTF8String, -- http, sasl, chap, cram-md5 --
|
||||
channel [0] SEQUENCE {
|
||||
cb-type UTF8String,
|
||||
cb-binding UTF8String
|
||||
} OPTIONAL,
|
||||
hostname [1] UTF8String OPTIONAL -- for chap/cram-md5
|
||||
}
|
||||
|
||||
DigestInitReply ::= SEQUENCE {
|
||||
nonce UTF8String, -- service nonce/challange
|
||||
opaque UTF8String, -- server state
|
||||
identifier [0] UTF8String OPTIONAL
|
||||
}
|
||||
|
||||
|
||||
DigestRequest ::= SEQUENCE {
|
||||
type UTF8String, -- http, sasl-md5, chap, cram-md5 --
|
||||
digest UTF8String, -- http:md5/md5-sess sasl:clear/int/conf --
|
||||
username UTF8String, -- username user used
|
||||
authid [0] UTF8String OPTIONAL,
|
||||
authentication-user [1] Principal OPTIONAL, -- principal to get key from
|
||||
realm [2] UTF8String OPTIONAL,
|
||||
method [3] UTF8String OPTIONAL,
|
||||
uri [4] UTF8String OPTIONAL,
|
||||
serverNonce UTF8String, -- same as "DigestInitReply.nonce"
|
||||
clientNonce [5] UTF8String OPTIONAL,
|
||||
nonceCount [6] UTF8String OPTIONAL,
|
||||
qop [7] UTF8String OPTIONAL,
|
||||
identifier [8] UTF8String OPTIONAL,
|
||||
hostname [9] UTF8String OPTIONAL,
|
||||
opaque UTF8String -- same as "DigestInitReply.opaque"
|
||||
}
|
||||
-- opaque = hex(cksum(type|serverNonce|identifier|hostname,digest-key))
|
||||
-- serverNonce = hex(time[4bytes]random[12bytes])(-cbType:cbBinding)
|
||||
|
||||
|
||||
DigestError ::= SEQUENCE {
|
||||
reason UTF8String,
|
||||
code INTEGER (-2147483648..2147483647)
|
||||
}
|
||||
|
||||
DigestResponse ::= SEQUENCE {
|
||||
responseData UTF8String,
|
||||
rsp [0] UTF8String OPTIONAL,
|
||||
tickets [1] SEQUENCE OF OCTET STRING OPTIONAL,
|
||||
channel [2] SEQUENCE {
|
||||
cb-type UTF8String,
|
||||
cb-binding UTF8String
|
||||
} OPTIONAL,
|
||||
hash-a1 [3] OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
DigestReqInner ::= CHOICE {
|
||||
init [0] DigestInit,
|
||||
digestRequest [1] DigestRequest
|
||||
}
|
||||
|
||||
DigestREQ ::= [APPLICATION 128] SEQUENCE {
|
||||
apReq [0] OCTET STRING,
|
||||
innerReq [1] EncryptedData
|
||||
}
|
||||
|
||||
DigestRepInner ::= CHOICE {
|
||||
error [0] DigestError,
|
||||
initReply [1] DigestInitReply,
|
||||
response [2] DigestResponse
|
||||
}
|
||||
|
||||
DigestREP ::= [APPLICATION 129] SEQUENCE {
|
||||
apRep [0] OCTET STRING,
|
||||
innerRep [1] EncryptedData
|
||||
}
|
||||
|
||||
|
||||
-- HTTP
|
||||
|
||||
-- md5
|
||||
-- A1 = unq(username-value) ":" unq(realm-value) ":" passwd
|
||||
-- md5-sess
|
||||
-- A1 = HEX(H(unq(username-value) ":" unq(realm-value) ":" passwd ) ":" unq(nonce-value) ":" unq(cnonce-value))
|
||||
|
||||
-- qop == auth
|
||||
-- A2 = Method ":" digest-uri-value
|
||||
-- qop == auth-int
|
||||
-- A2 = Method ":" digest-uri-value ":" H(entity-body)
|
||||
|
||||
-- request-digest = HEX(KD(HEX(H(A1)),
|
||||
-- unq(nonce-value) ":" nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":" HEX(H(A2))))
|
||||
-- no "qop"
|
||||
-- request-digest = HEX(KD(HEX(H(A1)), unq(nonce-value) ":" HEX(H(A2))))
|
||||
|
||||
|
||||
-- SASL:
|
||||
-- SS = H( { unq(username-value), ":", unq(realm-value), ":", password } )
|
||||
-- A1 = { SS, ":", unq(nonce-value), ":", unq(cnonce-value) }
|
||||
-- A1 = { SS, ":", unq(nonce-value), ":", unq(cnonce-value), ":", unq(authzid-value) }
|
||||
|
||||
-- A2 = "AUTHENTICATE:", ":", digest-uri-value
|
||||
-- qop == auth-int,auth-conf
|
||||
-- A2 = "AUTHENTICATE:", ":", digest-uri-value, ":00000000000000000000000000000000"
|
||||
|
||||
-- response-value = HEX( KD ( HEX(H(A1)),
|
||||
-- { unq(nonce-value), ":" nc-value, ":",
|
||||
-- unq(cnonce-value), ":", qop-value, ":",
|
||||
-- HEX(H(A2)) }))
|
||||
|
||||
END
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (c) 2003 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
#include "heim_asn1.h"
|
||||
|
||||
RCSID("$Id: extra.c,v 1.6 2006/01/31 09:44:54 lha Exp $");
|
||||
|
||||
int
|
||||
encode_heim_any(unsigned char *p, size_t len,
|
||||
const heim_any *data, size_t *size)
|
||||
{
|
||||
if (data->length > len)
|
||||
return ASN1_OVERFLOW;
|
||||
p -= data->length;
|
||||
len -= data->length;
|
||||
memcpy (p+1, data->data, data->length);
|
||||
*size = data->length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
decode_heim_any(const unsigned char *p, size_t len,
|
||||
heim_any *data, size_t *size)
|
||||
{
|
||||
size_t len_len, length, l;
|
||||
Der_class thisclass;
|
||||
Der_type thistype;
|
||||
unsigned int thistag;
|
||||
int e;
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
|
||||
if (e) return e;
|
||||
if (l > len)
|
||||
return ASN1_OVERFLOW;
|
||||
e = der_get_length(p + l, len - l, &length, &len_len);
|
||||
if (e) return e;
|
||||
if (length + len_len + l > len)
|
||||
return ASN1_OVERFLOW;
|
||||
|
||||
data->data = malloc(length + len_len + l);
|
||||
if (data->data == NULL)
|
||||
return ENOMEM;
|
||||
data->length = length + len_len + l;
|
||||
memcpy(data->data, p, length + len_len + l);
|
||||
|
||||
if (size)
|
||||
*size = length + len_len + l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
free_heim_any(heim_any *data)
|
||||
{
|
||||
free(data->data);
|
||||
data->data = NULL;
|
||||
}
|
||||
|
||||
size_t
|
||||
length_heim_any(const heim_any *data)
|
||||
{
|
||||
return data->length;
|
||||
}
|
||||
|
||||
int
|
||||
copy_heim_any(const heim_any *from, heim_any *to)
|
||||
{
|
||||
to->data = malloc(from->length);
|
||||
if (to->data == NULL && from->length != 0)
|
||||
return ENOMEM;
|
||||
memcpy(to->data, from->data, from->length);
|
||||
to->length = from->length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
encode_heim_any_set(unsigned char *p, size_t len,
|
||||
const heim_any_set *data, size_t *size)
|
||||
{
|
||||
return encode_heim_any(p, len, data, size);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
decode_heim_any_set(const unsigned char *p, size_t len,
|
||||
heim_any_set *data, size_t *size)
|
||||
{
|
||||
memset(data, 0, sizeof(*data));
|
||||
data->data = malloc(len);
|
||||
if (data->data == NULL && len != 0)
|
||||
return ENOMEM;
|
||||
data->length = len;
|
||||
memcpy(data->data, p, len);
|
||||
if (size) *size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
free_heim_any_set(heim_any_set *data)
|
||||
{
|
||||
free_heim_any(data);
|
||||
}
|
||||
|
||||
size_t
|
||||
length_heim_any_set(const heim_any *data)
|
||||
{
|
||||
return length_heim_any(data);
|
||||
}
|
||||
|
||||
int
|
||||
copy_heim_any_set(const heim_any_set *from, heim_any_set *to)
|
||||
{
|
||||
return copy_heim_any(from, to);
|
||||
}
|
||||
|
||||
int
|
||||
heim_any_cmp(const heim_any_set *p, const heim_any_set *q)
|
||||
{
|
||||
if (p->length != q->length)
|
||||
return p->length - q->length;
|
||||
return memcmp(p->data, q->data, p->length);
|
||||
}
|
||||
@@ -0,0 +1,784 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
|
||||
RCSID("$Id: gen.c,v 1.69 2006/10/14 05:11:52 lha Exp $");
|
||||
|
||||
FILE *headerfile, *codefile, *logfile;
|
||||
|
||||
#define STEM "asn1"
|
||||
|
||||
static const char *orig_filename;
|
||||
static char *header;
|
||||
static const char *headerbase = STEM;
|
||||
|
||||
/*
|
||||
* list of all IMPORTs
|
||||
*/
|
||||
|
||||
struct import {
|
||||
const char *module;
|
||||
struct import *next;
|
||||
};
|
||||
|
||||
static struct import *imports = NULL;
|
||||
|
||||
void
|
||||
add_import (const char *module)
|
||||
{
|
||||
struct import *tmp = emalloc (sizeof(*tmp));
|
||||
|
||||
tmp->module = module;
|
||||
tmp->next = imports;
|
||||
imports = tmp;
|
||||
|
||||
fprintf (headerfile, "#include <%s_asn1.h>\n", module);
|
||||
}
|
||||
|
||||
const char *
|
||||
get_filename (void)
|
||||
{
|
||||
return orig_filename;
|
||||
}
|
||||
|
||||
void
|
||||
init_generate (const char *filename, const char *base)
|
||||
{
|
||||
char *fn;
|
||||
|
||||
orig_filename = filename;
|
||||
if (base != NULL) {
|
||||
headerbase = strdup(base);
|
||||
if (headerbase == NULL)
|
||||
errx(1, "strdup");
|
||||
}
|
||||
asprintf(&header, "%s.h", headerbase);
|
||||
if (header == NULL)
|
||||
errx(1, "malloc");
|
||||
headerfile = fopen (header, "w");
|
||||
if (headerfile == NULL)
|
||||
err (1, "open %s", header);
|
||||
fprintf (headerfile,
|
||||
"/* Generated from %s */\n"
|
||||
"/* Do not edit */\n\n",
|
||||
filename);
|
||||
fprintf (headerfile,
|
||||
"#ifndef __%s_h__\n"
|
||||
"#define __%s_h__\n\n", headerbase, headerbase);
|
||||
fprintf (headerfile,
|
||||
"#include <stddef.h>\n"
|
||||
"#include <time.h>\n\n");
|
||||
fprintf (headerfile,
|
||||
"#ifndef __asn1_common_definitions__\n"
|
||||
"#define __asn1_common_definitions__\n\n");
|
||||
fprintf (headerfile,
|
||||
"typedef struct heim_integer {\n"
|
||||
" size_t length;\n"
|
||||
" void *data;\n"
|
||||
" int negative;\n"
|
||||
"} heim_integer;\n\n");
|
||||
fprintf (headerfile,
|
||||
"typedef struct heim_octet_string {\n"
|
||||
" size_t length;\n"
|
||||
" void *data;\n"
|
||||
"} heim_octet_string;\n\n");
|
||||
fprintf (headerfile,
|
||||
"typedef char *heim_general_string;\n\n"
|
||||
);
|
||||
fprintf (headerfile,
|
||||
"typedef char *heim_utf8_string;\n\n"
|
||||
);
|
||||
fprintf (headerfile,
|
||||
"typedef char *heim_printable_string;\n\n"
|
||||
);
|
||||
fprintf (headerfile,
|
||||
"typedef char *heim_ia5_string;\n\n"
|
||||
);
|
||||
fprintf (headerfile,
|
||||
"typedef struct heim_bmp_string {\n"
|
||||
" size_t length;\n"
|
||||
" uint16_t *data;\n"
|
||||
"} heim_bmp_string;\n\n");
|
||||
fprintf (headerfile,
|
||||
"typedef struct heim_universal_string {\n"
|
||||
" size_t length;\n"
|
||||
" uint32_t *data;\n"
|
||||
"} heim_universal_string;\n\n");
|
||||
fprintf (headerfile,
|
||||
"typedef struct heim_oid {\n"
|
||||
" size_t length;\n"
|
||||
" unsigned *components;\n"
|
||||
"} heim_oid;\n\n");
|
||||
fprintf (headerfile,
|
||||
"typedef struct heim_bit_string {\n"
|
||||
" size_t length;\n"
|
||||
" void *data;\n"
|
||||
"} heim_bit_string;\n\n");
|
||||
fprintf (headerfile,
|
||||
"typedef struct heim_octet_string heim_any;\n"
|
||||
"typedef struct heim_octet_string heim_any_set;\n\n");
|
||||
fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \\\n"
|
||||
" do { \\\n"
|
||||
" (BL) = length_##T((S)); \\\n"
|
||||
" (B) = malloc((BL)); \\\n"
|
||||
" if((B) == NULL) { \\\n"
|
||||
" (R) = ENOMEM; \\\n"
|
||||
" } else { \\\n"
|
||||
" (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \\\n"
|
||||
" (S), (L)); \\\n"
|
||||
" if((R) != 0) { \\\n"
|
||||
" free((B)); \\\n"
|
||||
" (B) = NULL; \\\n"
|
||||
" } \\\n"
|
||||
" } \\\n"
|
||||
" } while (0)\n\n",
|
||||
headerfile);
|
||||
fprintf (headerfile, "#endif\n\n");
|
||||
asprintf(&fn, "%s_files", base);
|
||||
if (fn == NULL)
|
||||
errx(1, "malloc");
|
||||
logfile = fopen(fn, "w");
|
||||
if (logfile == NULL)
|
||||
err (1, "open %s", fn);
|
||||
}
|
||||
|
||||
void
|
||||
close_generate (void)
|
||||
{
|
||||
fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase);
|
||||
|
||||
fclose (headerfile);
|
||||
fprintf (logfile, "\n");
|
||||
fclose (logfile);
|
||||
}
|
||||
|
||||
void
|
||||
gen_assign_defval(const char *var, struct value *val)
|
||||
{
|
||||
switch(val->type) {
|
||||
case stringvalue:
|
||||
fprintf(codefile, "if((%s = strdup(\"%s\")) == NULL)\nreturn ENOMEM;\n", var, val->u.stringvalue);
|
||||
break;
|
||||
case integervalue:
|
||||
fprintf(codefile, "%s = %d;\n", var, val->u.integervalue);
|
||||
break;
|
||||
case booleanvalue:
|
||||
if(val->u.booleanvalue)
|
||||
fprintf(codefile, "%s = TRUE;\n", var);
|
||||
else
|
||||
fprintf(codefile, "%s = FALSE;\n", var);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gen_compare_defval(const char *var, struct value *val)
|
||||
{
|
||||
switch(val->type) {
|
||||
case stringvalue:
|
||||
fprintf(codefile, "if(strcmp(%s, \"%s\") != 0)\n", var, val->u.stringvalue);
|
||||
break;
|
||||
case integervalue:
|
||||
fprintf(codefile, "if(%s != %d)\n", var, val->u.integervalue);
|
||||
break;
|
||||
case booleanvalue:
|
||||
if(val->u.booleanvalue)
|
||||
fprintf(codefile, "if(!%s)\n", var);
|
||||
else
|
||||
fprintf(codefile, "if(%s)\n", var);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
generate_header_of_codefile(const char *name)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
if (codefile != NULL)
|
||||
abort();
|
||||
|
||||
asprintf (&filename, "%s_%s.x", STEM, name);
|
||||
if (filename == NULL)
|
||||
errx(1, "malloc");
|
||||
codefile = fopen (filename, "w");
|
||||
if (codefile == NULL)
|
||||
err (1, "fopen %s", filename);
|
||||
fprintf(logfile, "%s ", filename);
|
||||
free(filename);
|
||||
fprintf (codefile,
|
||||
"/* Generated from %s */\n"
|
||||
"/* Do not edit */\n\n"
|
||||
"#include <stdio.h>\n"
|
||||
"#include <stdlib.h>\n"
|
||||
"#include <time.h>\n"
|
||||
"#include <string.h>\n"
|
||||
"#include <errno.h>\n"
|
||||
"#include <krb5-types.h>\n",
|
||||
orig_filename);
|
||||
|
||||
fprintf (codefile,
|
||||
"#include <%s.h>\n",
|
||||
headerbase);
|
||||
fprintf (codefile,
|
||||
"#include <asn1_err.h>\n"
|
||||
"#include <der.h>\n"
|
||||
"#include <parse_units.h>\n\n");
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
close_codefile(void)
|
||||
{
|
||||
if (codefile == NULL)
|
||||
abort();
|
||||
|
||||
fclose(codefile);
|
||||
codefile = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
generate_constant (const Symbol *s)
|
||||
{
|
||||
switch(s->value->type) {
|
||||
case booleanvalue:
|
||||
break;
|
||||
case integervalue:
|
||||
fprintf (headerfile, "enum { %s = %d };\n\n",
|
||||
s->gen_name, s->value->u.integervalue);
|
||||
break;
|
||||
case nullvalue:
|
||||
break;
|
||||
case stringvalue:
|
||||
break;
|
||||
case objectidentifiervalue: {
|
||||
struct objid *o, **list;
|
||||
int i, len;
|
||||
|
||||
generate_header_of_codefile(s->gen_name);
|
||||
|
||||
len = 0;
|
||||
for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
|
||||
len++;
|
||||
list = emalloc(sizeof(*list) * len);
|
||||
|
||||
i = 0;
|
||||
for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
|
||||
list[i++] = o;
|
||||
|
||||
fprintf (headerfile, "/* OBJECT IDENTIFIER %s ::= { ", s->name);
|
||||
for (i = len - 1 ; i >= 0; i--) {
|
||||
o = list[i];
|
||||
fprintf(headerfile, "%s(%d) ",
|
||||
o->label ? o->label : "label-less", o->value);
|
||||
}
|
||||
|
||||
fprintf (headerfile, "} */\n");
|
||||
fprintf (headerfile, "const heim_oid *oid_%s(void);\n\n",
|
||||
s->gen_name);
|
||||
|
||||
fprintf (codefile, "static unsigned oid_%s_variable_num[%d] = {",
|
||||
s->gen_name, len);
|
||||
for (i = len - 1 ; i >= 0; i--) {
|
||||
fprintf(codefile, "%d%s ", list[i]->value, i > 0 ? "," : "");
|
||||
}
|
||||
fprintf(codefile, "};\n");
|
||||
|
||||
fprintf (codefile, "static const heim_oid oid_%s_variable = "
|
||||
"{ %d, oid_%s_variable_num };\n\n",
|
||||
s->gen_name, len, s->gen_name);
|
||||
|
||||
fprintf (codefile, "const heim_oid *oid_%s(void)\n"
|
||||
"{\n"
|
||||
"return &oid_%s_variable;\n"
|
||||
"}\n\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
close_codefile();
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
space(int level)
|
||||
{
|
||||
while(level-- > 0)
|
||||
fprintf(headerfile, " ");
|
||||
}
|
||||
|
||||
static const char *
|
||||
last_member_p(struct member *m)
|
||||
{
|
||||
struct member *n = ASN1_TAILQ_NEXT(m, members);
|
||||
if (n == NULL)
|
||||
return "";
|
||||
if (n->ellipsis && ASN1_TAILQ_NEXT(n, members) == NULL)
|
||||
return "";
|
||||
return ",";
|
||||
}
|
||||
|
||||
static struct member *
|
||||
have_ellipsis(Type *t)
|
||||
{
|
||||
struct member *m;
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
if (m->ellipsis)
|
||||
return m;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
define_asn1 (int level, Type *t)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
fprintf (headerfile, "%s", t->symbol->name);
|
||||
break;
|
||||
case TInteger:
|
||||
if(t->members == NULL) {
|
||||
fprintf (headerfile, "INTEGER");
|
||||
if (t->range)
|
||||
fprintf (headerfile, " (%d..%d)",
|
||||
t->range->min, t->range->max);
|
||||
} else {
|
||||
Member *m;
|
||||
fprintf (headerfile, "INTEGER {\n");
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
space (level + 1);
|
||||
fprintf(headerfile, "%s(%d)%s\n", m->gen_name, m->val,
|
||||
last_member_p(m));
|
||||
}
|
||||
space(level);
|
||||
fprintf (headerfile, "}");
|
||||
}
|
||||
break;
|
||||
case TBoolean:
|
||||
fprintf (headerfile, "BOOLEAN");
|
||||
break;
|
||||
case TOctetString:
|
||||
fprintf (headerfile, "OCTET STRING");
|
||||
break;
|
||||
case TEnumerated :
|
||||
case TBitString: {
|
||||
Member *m;
|
||||
|
||||
space(level);
|
||||
if(t->type == TBitString)
|
||||
fprintf (headerfile, "BIT STRING {\n");
|
||||
else
|
||||
fprintf (headerfile, "ENUMERATED {\n");
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
space(level + 1);
|
||||
fprintf (headerfile, "%s(%d)%s\n", m->name, m->val,
|
||||
last_member_p(m));
|
||||
}
|
||||
space(level);
|
||||
fprintf (headerfile, "}");
|
||||
break;
|
||||
}
|
||||
case TChoice:
|
||||
case TSet:
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
int max_width = 0;
|
||||
|
||||
if(t->type == TChoice)
|
||||
fprintf(headerfile, "CHOICE {\n");
|
||||
else if(t->type == TSet)
|
||||
fprintf(headerfile, "SET {\n");
|
||||
else
|
||||
fprintf(headerfile, "SEQUENCE {\n");
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
if(strlen(m->name) > max_width)
|
||||
max_width = strlen(m->name);
|
||||
}
|
||||
max_width += 3;
|
||||
if(max_width < 16) max_width = 16;
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
int width = max_width;
|
||||
space(level + 1);
|
||||
if (m->ellipsis) {
|
||||
fprintf (headerfile, "...");
|
||||
} else {
|
||||
width -= fprintf(headerfile, "%s", m->name);
|
||||
fprintf(headerfile, "%*s", width, "");
|
||||
define_asn1(level + 1, m->type);
|
||||
if(m->optional)
|
||||
fprintf(headerfile, " OPTIONAL");
|
||||
}
|
||||
if(last_member_p(m))
|
||||
fprintf (headerfile, ",");
|
||||
fprintf (headerfile, "\n");
|
||||
}
|
||||
space(level);
|
||||
fprintf (headerfile, "}");
|
||||
break;
|
||||
}
|
||||
case TSequenceOf:
|
||||
fprintf (headerfile, "SEQUENCE OF ");
|
||||
define_asn1 (0, t->subtype);
|
||||
break;
|
||||
case TSetOf:
|
||||
fprintf (headerfile, "SET OF ");
|
||||
define_asn1 (0, t->subtype);
|
||||
break;
|
||||
case TGeneralizedTime:
|
||||
fprintf (headerfile, "GeneralizedTime");
|
||||
break;
|
||||
case TGeneralString:
|
||||
fprintf (headerfile, "GeneralString");
|
||||
break;
|
||||
case TTag: {
|
||||
const char *classnames[] = { "UNIVERSAL ", "APPLICATION ",
|
||||
"" /* CONTEXT */, "PRIVATE " };
|
||||
if(t->tag.tagclass != ASN1_C_UNIV)
|
||||
fprintf (headerfile, "[%s%d] ",
|
||||
classnames[t->tag.tagclass],
|
||||
t->tag.tagvalue);
|
||||
if(t->tag.tagenv == TE_IMPLICIT)
|
||||
fprintf (headerfile, "IMPLICIT ");
|
||||
define_asn1 (level, t->subtype);
|
||||
break;
|
||||
}
|
||||
case TUTCTime:
|
||||
fprintf (headerfile, "UTCTime");
|
||||
break;
|
||||
case TUTF8String:
|
||||
space(level);
|
||||
fprintf (headerfile, "UTF8String");
|
||||
break;
|
||||
case TPrintableString:
|
||||
space(level);
|
||||
fprintf (headerfile, "PrintableString");
|
||||
break;
|
||||
case TIA5String:
|
||||
space(level);
|
||||
fprintf (headerfile, "IA5String");
|
||||
break;
|
||||
case TBMPString:
|
||||
space(level);
|
||||
fprintf (headerfile, "BMPString");
|
||||
break;
|
||||
case TUniversalString:
|
||||
space(level);
|
||||
fprintf (headerfile, "UniversalString");
|
||||
break;
|
||||
case TOID :
|
||||
space(level);
|
||||
fprintf(headerfile, "OBJECT IDENTIFIER");
|
||||
break;
|
||||
case TNull:
|
||||
space(level);
|
||||
fprintf (headerfile, "NULL");
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
define_type (int level, const char *name, Type *t, int typedefp, int preservep)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
space(level);
|
||||
fprintf (headerfile, "%s %s;\n", t->symbol->gen_name, name);
|
||||
break;
|
||||
case TInteger:
|
||||
space(level);
|
||||
if(t->members) {
|
||||
Member *m;
|
||||
fprintf (headerfile, "enum %s {\n", typedefp ? name : "");
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
space (level + 1);
|
||||
fprintf(headerfile, "%s = %d%s\n", m->gen_name, m->val,
|
||||
last_member_p(m));
|
||||
}
|
||||
fprintf (headerfile, "} %s;\n", name);
|
||||
} else if (t->range == NULL) {
|
||||
fprintf (headerfile, "heim_integer %s;\n", name);
|
||||
} else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
|
||||
fprintf (headerfile, "int %s;\n", name);
|
||||
} else if (t->range->min == 0 && t->range->max == UINT_MAX) {
|
||||
fprintf (headerfile, "unsigned int %s;\n", name);
|
||||
} else if (t->range->min == 0 && t->range->max == INT_MAX) {
|
||||
fprintf (headerfile, "unsigned int %s;\n", name);
|
||||
} else
|
||||
errx(1, "%s: unsupported range %d -> %d",
|
||||
name, t->range->min, t->range->max);
|
||||
break;
|
||||
case TBoolean:
|
||||
space(level);
|
||||
fprintf (headerfile, "int %s;\n", name);
|
||||
break;
|
||||
case TOctetString:
|
||||
space(level);
|
||||
fprintf (headerfile, "heim_octet_string %s;\n", name);
|
||||
break;
|
||||
case TBitString: {
|
||||
Member *m;
|
||||
Type i;
|
||||
struct range range = { 0, INT_MAX };
|
||||
|
||||
i.type = TInteger;
|
||||
i.range = ⦥
|
||||
i.members = NULL;
|
||||
i.constraint = NULL;
|
||||
|
||||
space(level);
|
||||
if(ASN1_TAILQ_EMPTY(t->members))
|
||||
fprintf (headerfile, "heim_bit_string %s;\n", name);
|
||||
else {
|
||||
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *n;
|
||||
|
||||
asprintf (&n, "%s:1", m->gen_name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
define_type (level + 1, n, &i, FALSE, FALSE);
|
||||
free (n);
|
||||
}
|
||||
space(level);
|
||||
fprintf (headerfile, "} %s;\n\n", name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TEnumerated: {
|
||||
Member *m;
|
||||
|
||||
space(level);
|
||||
fprintf (headerfile, "enum %s {\n", typedefp ? name : "");
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
space(level + 1);
|
||||
if (m->ellipsis)
|
||||
fprintf (headerfile, "/* ... */\n");
|
||||
else
|
||||
fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val,
|
||||
last_member_p(m));
|
||||
}
|
||||
space(level);
|
||||
fprintf (headerfile, "} %s;\n\n", name);
|
||||
break;
|
||||
}
|
||||
case TSet:
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
|
||||
space(level);
|
||||
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
|
||||
if (t->type == TSequence && preservep) {
|
||||
space(level + 1);
|
||||
fprintf(headerfile, "heim_octet_string _save;\n");
|
||||
}
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
if (m->ellipsis) {
|
||||
;
|
||||
} else if (m->optional) {
|
||||
char *n;
|
||||
|
||||
asprintf (&n, "*%s", m->gen_name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
define_type (level + 1, n, m->type, FALSE, FALSE);
|
||||
free (n);
|
||||
} else
|
||||
define_type (level + 1, m->gen_name, m->type, FALSE, FALSE);
|
||||
}
|
||||
space(level);
|
||||
fprintf (headerfile, "} %s;\n", name);
|
||||
break;
|
||||
}
|
||||
case TSetOf:
|
||||
case TSequenceOf: {
|
||||
Type i;
|
||||
struct range range = { 0, INT_MAX };
|
||||
|
||||
i.type = TInteger;
|
||||
i.range = ⦥
|
||||
i.members = NULL;
|
||||
i.constraint = NULL;
|
||||
|
||||
space(level);
|
||||
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
|
||||
define_type (level + 1, "len", &i, FALSE, FALSE);
|
||||
define_type (level + 1, "*val", t->subtype, FALSE, FALSE);
|
||||
space(level);
|
||||
fprintf (headerfile, "} %s;\n", name);
|
||||
break;
|
||||
}
|
||||
case TGeneralizedTime:
|
||||
space(level);
|
||||
fprintf (headerfile, "time_t %s;\n", name);
|
||||
break;
|
||||
case TGeneralString:
|
||||
space(level);
|
||||
fprintf (headerfile, "heim_general_string %s;\n", name);
|
||||
break;
|
||||
case TTag:
|
||||
define_type (level, name, t->subtype, typedefp, preservep);
|
||||
break;
|
||||
case TChoice: {
|
||||
int first = 1;
|
||||
Member *m;
|
||||
|
||||
space(level);
|
||||
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
|
||||
if (preservep) {
|
||||
space(level + 1);
|
||||
fprintf(headerfile, "heim_octet_string _save;\n");
|
||||
}
|
||||
space(level + 1);
|
||||
fprintf (headerfile, "enum {\n");
|
||||
m = have_ellipsis(t);
|
||||
if (m) {
|
||||
space(level + 2);
|
||||
fprintf (headerfile, "%s = 0,\n", m->label);
|
||||
first = 0;
|
||||
}
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
space(level + 2);
|
||||
if (m->ellipsis)
|
||||
fprintf (headerfile, "/* ... */\n");
|
||||
else
|
||||
fprintf (headerfile, "%s%s%s\n", m->label,
|
||||
first ? " = 1" : "",
|
||||
last_member_p(m));
|
||||
first = 0;
|
||||
}
|
||||
space(level + 1);
|
||||
fprintf (headerfile, "} element;\n");
|
||||
space(level + 1);
|
||||
fprintf (headerfile, "union {\n");
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
if (m->ellipsis) {
|
||||
space(level + 2);
|
||||
fprintf(headerfile, "heim_octet_string asn1_ellipsis;\n");
|
||||
} else if (m->optional) {
|
||||
char *n;
|
||||
|
||||
asprintf (&n, "*%s", m->gen_name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
define_type (level + 2, n, m->type, FALSE, FALSE);
|
||||
free (n);
|
||||
} else
|
||||
define_type (level + 2, m->gen_name, m->type, FALSE, FALSE);
|
||||
}
|
||||
space(level + 1);
|
||||
fprintf (headerfile, "} u;\n");
|
||||
space(level);
|
||||
fprintf (headerfile, "} %s;\n", name);
|
||||
break;
|
||||
}
|
||||
case TUTCTime:
|
||||
space(level);
|
||||
fprintf (headerfile, "time_t %s;\n", name);
|
||||
break;
|
||||
case TUTF8String:
|
||||
space(level);
|
||||
fprintf (headerfile, "heim_utf8_string %s;\n", name);
|
||||
break;
|
||||
case TPrintableString:
|
||||
space(level);
|
||||
fprintf (headerfile, "heim_printable_string %s;\n", name);
|
||||
break;
|
||||
case TIA5String:
|
||||
space(level);
|
||||
fprintf (headerfile, "heim_ia5_string %s;\n", name);
|
||||
break;
|
||||
case TBMPString:
|
||||
space(level);
|
||||
fprintf (headerfile, "heim_bmp_string %s;\n", name);
|
||||
break;
|
||||
case TUniversalString:
|
||||
space(level);
|
||||
fprintf (headerfile, "heim_universal_string %s;\n", name);
|
||||
break;
|
||||
case TOID :
|
||||
space(level);
|
||||
fprintf (headerfile, "heim_oid %s;\n", name);
|
||||
break;
|
||||
case TNull:
|
||||
space(level);
|
||||
fprintf (headerfile, "int %s;\n", name);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
generate_type_header (const Symbol *s)
|
||||
{
|
||||
int preservep = preserve_type(s->name) ? TRUE : FALSE;
|
||||
|
||||
fprintf (headerfile, "/*\n");
|
||||
fprintf (headerfile, "%s ::= ", s->name);
|
||||
define_asn1 (0, s->type);
|
||||
fprintf (headerfile, "\n*/\n\n");
|
||||
|
||||
fprintf (headerfile, "typedef ");
|
||||
define_type (0, s->gen_name, s->type, TRUE, preservep);
|
||||
|
||||
fprintf (headerfile, "\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
generate_type (const Symbol *s)
|
||||
{
|
||||
generate_header_of_codefile(s->gen_name);
|
||||
|
||||
generate_type_header (s);
|
||||
generate_type_encode (s);
|
||||
generate_type_decode (s);
|
||||
generate_type_free (s);
|
||||
generate_type_length (s);
|
||||
generate_type_copy (s);
|
||||
generate_type_seq (s);
|
||||
generate_glue (s->type, s->gen_name);
|
||||
fprintf(headerfile, "\n\n");
|
||||
close_codefile();
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
|
||||
RCSID("$Id: gen_copy.c,v 1.18 2006/10/14 05:34:19 lha Exp $");
|
||||
|
||||
static int used_fail;
|
||||
|
||||
static void
|
||||
copy_primitive (const char *typename, const char *from, const char *to)
|
||||
{
|
||||
fprintf (codefile, "if(der_copy_%s(%s, %s)) goto fail;\n",
|
||||
typename, from, to);
|
||||
used_fail++;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_type (const char *from, const char *to, const Type *t, int preserve)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
#if 0
|
||||
copy_type (from, to, t->symbol->type, preserve);
|
||||
#endif
|
||||
fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n",
|
||||
t->symbol->gen_name, from, to);
|
||||
used_fail++;
|
||||
break;
|
||||
case TInteger:
|
||||
if (t->range == NULL && t->members == NULL) {
|
||||
copy_primitive ("heim_integer", from, to);
|
||||
break;
|
||||
}
|
||||
case TBoolean:
|
||||
case TEnumerated :
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
case TOctetString:
|
||||
copy_primitive ("octet_string", from, to);
|
||||
break;
|
||||
case TBitString:
|
||||
if (ASN1_TAILQ_EMPTY(t->members))
|
||||
copy_primitive ("bit_string", from, to);
|
||||
else
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
case TSet:
|
||||
case TSequence:
|
||||
case TChoice: {
|
||||
Member *m, *have_ellipsis = NULL;
|
||||
|
||||
if(t->members == NULL)
|
||||
break;
|
||||
|
||||
if ((t->type == TSequence || t->type == TChoice) && preserve) {
|
||||
fprintf(codefile,
|
||||
"{ int ret;\n"
|
||||
"ret = der_copy_octet_string(&(%s)->_save, &(%s)->_save);\n"
|
||||
"if (ret) goto fail;\n"
|
||||
"}\n",
|
||||
from, to);
|
||||
used_fail++;
|
||||
}
|
||||
|
||||
if(t->type == TChoice) {
|
||||
fprintf(codefile, "(%s)->element = (%s)->element;\n", to, from);
|
||||
fprintf(codefile, "switch((%s)->element) {\n", from);
|
||||
}
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *fs;
|
||||
char *ts;
|
||||
|
||||
if (m->ellipsis) {
|
||||
have_ellipsis = m;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "case %s:\n", m->label);
|
||||
|
||||
asprintf (&fs, "%s(%s)->%s%s",
|
||||
m->optional ? "" : "&", from,
|
||||
t->type == TChoice ? "u." : "", m->gen_name);
|
||||
if (fs == NULL)
|
||||
errx(1, "malloc");
|
||||
asprintf (&ts, "%s(%s)->%s%s",
|
||||
m->optional ? "" : "&", to,
|
||||
t->type == TChoice ? "u." : "", m->gen_name);
|
||||
if (ts == NULL)
|
||||
errx(1, "malloc");
|
||||
if(m->optional){
|
||||
fprintf(codefile, "if(%s) {\n", fs);
|
||||
fprintf(codefile, "%s = malloc(sizeof(*%s));\n", ts, ts);
|
||||
fprintf(codefile, "if(%s == NULL) goto fail;\n", ts);
|
||||
used_fail++;
|
||||
}
|
||||
copy_type (fs, ts, m->type, FALSE);
|
||||
if(m->optional){
|
||||
fprintf(codefile, "}else\n");
|
||||
fprintf(codefile, "%s = NULL;\n", ts);
|
||||
}
|
||||
free (fs);
|
||||
free (ts);
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "break;\n");
|
||||
}
|
||||
if(t->type == TChoice) {
|
||||
if (have_ellipsis) {
|
||||
fprintf(codefile, "case %s: {\n"
|
||||
"int ret;\n"
|
||||
"ret=der_copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n"
|
||||
"if (ret) goto fail;\n"
|
||||
"break;\n"
|
||||
"}\n",
|
||||
have_ellipsis->label,
|
||||
from, have_ellipsis->gen_name,
|
||||
to, have_ellipsis->gen_name);
|
||||
used_fail++;
|
||||
}
|
||||
fprintf(codefile, "}\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSetOf:
|
||||
case TSequenceOf: {
|
||||
char *f;
|
||||
char *T;
|
||||
|
||||
fprintf (codefile, "if(((%s)->val = "
|
||||
"malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n",
|
||||
to, from, to, from);
|
||||
fprintf (codefile, "goto fail;\n");
|
||||
used_fail++;
|
||||
fprintf(codefile,
|
||||
"for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
|
||||
to, to, from, to);
|
||||
asprintf(&f, "&(%s)->val[(%s)->len]", from, to);
|
||||
if (f == NULL)
|
||||
errx(1, "malloc");
|
||||
asprintf(&T, "&(%s)->val[(%s)->len]", to, to);
|
||||
if (T == NULL)
|
||||
errx(1, "malloc");
|
||||
copy_type(f, T, t->subtype, FALSE);
|
||||
fprintf(codefile, "}\n");
|
||||
free(f);
|
||||
free(T);
|
||||
break;
|
||||
}
|
||||
case TGeneralizedTime:
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
case TGeneralString:
|
||||
copy_primitive ("general_string", from, to);
|
||||
break;
|
||||
case TUTCTime:
|
||||
fprintf(codefile, "*(%s) = *(%s);\n", to, from);
|
||||
break;
|
||||
case TUTF8String:
|
||||
copy_primitive ("utf8string", from, to);
|
||||
break;
|
||||
case TPrintableString:
|
||||
copy_primitive ("printable_string", from, to);
|
||||
break;
|
||||
case TIA5String:
|
||||
copy_primitive ("ia5_string", from, to);
|
||||
break;
|
||||
case TBMPString:
|
||||
copy_primitive ("bmp_string", from, to);
|
||||
break;
|
||||
case TUniversalString:
|
||||
copy_primitive ("universal_string", from, to);
|
||||
break;
|
||||
case TTag:
|
||||
copy_type (from, to, t->subtype, preserve);
|
||||
break;
|
||||
case TOID:
|
||||
copy_primitive ("oid", from, to);
|
||||
break;
|
||||
case TNull:
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
generate_type_copy (const Symbol *s)
|
||||
{
|
||||
int preserve = preserve_type(s->name) ? TRUE : FALSE;
|
||||
|
||||
used_fail = 0;
|
||||
|
||||
fprintf (headerfile,
|
||||
"int copy_%s (const %s *, %s *);\n",
|
||||
s->gen_name, s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"copy_%s(const %s *from, %s *to)\n"
|
||||
"{\n"
|
||||
"memset(to, 0, sizeof(*to));\n",
|
||||
s->gen_name, s->gen_name, s->gen_name);
|
||||
copy_type ("from", "to", s->type, preserve);
|
||||
fprintf (codefile, "return 0;\n");
|
||||
|
||||
if (used_fail)
|
||||
fprintf (codefile, "fail:\n"
|
||||
"free_%s(to);\n"
|
||||
"return ENOMEM;\n",
|
||||
s->gen_name);
|
||||
|
||||
fprintf(codefile,
|
||||
"}\n\n");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,666 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
#include "lex.h"
|
||||
|
||||
RCSID("$Id: gen_decode.c,v 1.30 2006/09/24 09:13:12 lha Exp $");
|
||||
|
||||
static void
|
||||
decode_primitive (const char *typename, const char *name, const char *forwstr)
|
||||
{
|
||||
#if 0
|
||||
fprintf (codefile,
|
||||
"e = decode_%s(p, len, %s, &l);\n"
|
||||
"%s;\n",
|
||||
typename,
|
||||
name,
|
||||
forwstr);
|
||||
#else
|
||||
fprintf (codefile,
|
||||
"e = der_get_%s(p, len, %s, &l);\n"
|
||||
"if(e) %s;\np += l; len -= l; ret += l;\n",
|
||||
typename,
|
||||
name,
|
||||
forwstr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
is_primitive_type(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case TInteger:
|
||||
case TBoolean:
|
||||
case TOctetString:
|
||||
case TBitString:
|
||||
case TEnumerated:
|
||||
case TGeneralizedTime:
|
||||
case TGeneralString:
|
||||
case TOID:
|
||||
case TUTCTime:
|
||||
case TUTF8String:
|
||||
case TPrintableString:
|
||||
case TIA5String:
|
||||
case TBMPString:
|
||||
case TUniversalString:
|
||||
case TNull:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
find_tag (const Type *t,
|
||||
Der_class *cl, Der_type *ty, unsigned *tag)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TBitString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_BitString;
|
||||
break;
|
||||
case TBoolean:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_Boolean;
|
||||
break;
|
||||
case TChoice:
|
||||
errx(1, "Cannot have recursive CHOICE");
|
||||
case TEnumerated:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_Enumerated;
|
||||
break;
|
||||
case TGeneralString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_GeneralString;
|
||||
break;
|
||||
case TGeneralizedTime:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_GeneralizedTime;
|
||||
break;
|
||||
case TIA5String:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_IA5String;
|
||||
break;
|
||||
case TInteger:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_Integer;
|
||||
break;
|
||||
case TNull:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_Null;
|
||||
break;
|
||||
case TOID:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_OID;
|
||||
break;
|
||||
case TOctetString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_OctetString;
|
||||
break;
|
||||
case TPrintableString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_PrintableString;
|
||||
break;
|
||||
case TSequence:
|
||||
case TSequenceOf:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = CONS;
|
||||
*tag = UT_Sequence;
|
||||
break;
|
||||
case TSet:
|
||||
case TSetOf:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = CONS;
|
||||
*tag = UT_Set;
|
||||
break;
|
||||
case TTag:
|
||||
*cl = t->tag.tagclass;
|
||||
*ty = is_primitive_type(t->subtype->type) ? PRIM : CONS;
|
||||
*tag = t->tag.tagvalue;
|
||||
break;
|
||||
case TType:
|
||||
if ((t->symbol->stype == Stype && t->symbol->type == NULL)
|
||||
|| t->symbol->stype == SUndefined) {
|
||||
error_message("%s is imported or still undefined, "
|
||||
" can't generate tag checking data in CHOICE "
|
||||
"without this information",
|
||||
t->symbol->name);
|
||||
exit(1);
|
||||
}
|
||||
find_tag(t->symbol->type, cl, ty, tag);
|
||||
return;
|
||||
case TUTCTime:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_UTCTime;
|
||||
break;
|
||||
case TUTF8String:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_UTF8String;
|
||||
break;
|
||||
case TBMPString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_BMPString;
|
||||
break;
|
||||
case TUniversalString:
|
||||
*cl = ASN1_C_UNIV;
|
||||
*ty = PRIM;
|
||||
*tag = UT_UniversalString;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
decode_type (const char *name, const Type *t, int optional,
|
||||
const char *forwstr, const char *tmpstr)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TType: {
|
||||
if (optional)
|
||||
fprintf(codefile,
|
||||
"%s = calloc(1, sizeof(*%s));\n"
|
||||
"if (%s == NULL) %s;\n",
|
||||
name, name, name, forwstr);
|
||||
fprintf (codefile,
|
||||
"e = decode_%s(p, len, %s, &l);\n",
|
||||
t->symbol->gen_name, name);
|
||||
if (optional) {
|
||||
fprintf (codefile,
|
||||
"if(e) {\n"
|
||||
"free(%s);\n"
|
||||
"%s = NULL;\n"
|
||||
"} else {\n"
|
||||
"p += l; len -= l; ret += l;\n"
|
||||
"}\n",
|
||||
name, name);
|
||||
} else {
|
||||
fprintf (codefile,
|
||||
"if(e) %s;\n",
|
||||
forwstr);
|
||||
fprintf (codefile,
|
||||
"p += l; len -= l; ret += l;\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TInteger:
|
||||
if(t->members) {
|
||||
char *s;
|
||||
asprintf(&s, "(int*)%s", name);
|
||||
if (s == NULL)
|
||||
errx (1, "out of memory");
|
||||
decode_primitive ("integer", s, forwstr);
|
||||
free(s);
|
||||
} else if (t->range == NULL) {
|
||||
decode_primitive ("heim_integer", name, forwstr);
|
||||
} else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
|
||||
decode_primitive ("integer", name, forwstr);
|
||||
} else if (t->range->min == 0 && t->range->max == UINT_MAX) {
|
||||
decode_primitive ("unsigned", name, forwstr);
|
||||
} else if (t->range->min == 0 && t->range->max == INT_MAX) {
|
||||
decode_primitive ("unsigned", name, forwstr);
|
||||
} else
|
||||
errx(1, "%s: unsupported range %d -> %d",
|
||||
name, t->range->min, t->range->max);
|
||||
break;
|
||||
case TBoolean:
|
||||
decode_primitive ("boolean", name, forwstr);
|
||||
break;
|
||||
case TEnumerated:
|
||||
decode_primitive ("enumerated", name, forwstr);
|
||||
break;
|
||||
case TOctetString:
|
||||
decode_primitive ("octet_string", name, forwstr);
|
||||
break;
|
||||
case TBitString: {
|
||||
Member *m;
|
||||
int pos = 0;
|
||||
|
||||
if (ASN1_TAILQ_EMPTY(t->members)) {
|
||||
decode_primitive ("bit_string", name, forwstr);
|
||||
break;
|
||||
}
|
||||
fprintf(codefile,
|
||||
"if (len < 1) return ASN1_OVERRUN;\n"
|
||||
"p++; len--; ret++;\n");
|
||||
fprintf(codefile,
|
||||
"do {\n"
|
||||
"if (len < 1) break;\n");
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
while (m->val / 8 > pos / 8) {
|
||||
fprintf (codefile,
|
||||
"p++; len--; ret++;\n"
|
||||
"if (len < 1) break;\n");
|
||||
pos += 8;
|
||||
}
|
||||
fprintf (codefile,
|
||||
"(%s)->%s = (*p >> %d) & 1;\n",
|
||||
name, m->gen_name, 7 - m->val % 8);
|
||||
}
|
||||
fprintf(codefile,
|
||||
"} while(0);\n");
|
||||
fprintf (codefile,
|
||||
"p += len; ret += len;\n");
|
||||
break;
|
||||
}
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *s;
|
||||
|
||||
if (m->ellipsis)
|
||||
continue;
|
||||
|
||||
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&",
|
||||
name, m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
decode_type (s, m->type, m->optional, forwstr, m->gen_name);
|
||||
free (s);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case TSet: {
|
||||
Member *m;
|
||||
unsigned int memno;
|
||||
|
||||
if(t->members == NULL)
|
||||
break;
|
||||
|
||||
fprintf(codefile, "{\n");
|
||||
fprintf(codefile, "unsigned int members = 0;\n");
|
||||
fprintf(codefile, "while(len > 0) {\n");
|
||||
fprintf(codefile,
|
||||
"Der_class class;\n"
|
||||
"Der_type type;\n"
|
||||
"int tag;\n"
|
||||
"e = der_get_tag (p, len, &class, &type, &tag, NULL);\n"
|
||||
"if(e) %s;\n", forwstr);
|
||||
fprintf(codefile, "switch (MAKE_TAG(class, type, tag)) {\n");
|
||||
memno = 0;
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *s;
|
||||
|
||||
assert(m->type->type == TTag);
|
||||
|
||||
fprintf(codefile, "case MAKE_TAG(%s, %s, %s):\n",
|
||||
classname(m->type->tag.tagclass),
|
||||
is_primitive_type(m->type->subtype->type) ? "PRIM" : "CONS",
|
||||
valuename(m->type->tag.tagclass, m->type->tag.tagvalue));
|
||||
|
||||
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
if(m->optional)
|
||||
fprintf(codefile,
|
||||
"%s = calloc(1, sizeof(*%s));\n"
|
||||
"if (%s == NULL) { e = ENOMEM; %s; }\n",
|
||||
s, s, s, forwstr);
|
||||
decode_type (s, m->type, 0, forwstr, m->gen_name);
|
||||
free (s);
|
||||
|
||||
fprintf(codefile, "members |= (1 << %d);\n", memno);
|
||||
memno++;
|
||||
fprintf(codefile, "break;\n");
|
||||
}
|
||||
fprintf(codefile,
|
||||
"default:\n"
|
||||
"return ASN1_MISPLACED_FIELD;\n"
|
||||
"break;\n");
|
||||
fprintf(codefile, "}\n");
|
||||
fprintf(codefile, "}\n");
|
||||
memno = 0;
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *s;
|
||||
|
||||
asprintf (&s, "%s->%s", name, m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
fprintf(codefile, "if((members & (1 << %d)) == 0)\n", memno);
|
||||
if(m->optional)
|
||||
fprintf(codefile, "%s = NULL;\n", s);
|
||||
else if(m->defval)
|
||||
gen_assign_defval(s, m->defval);
|
||||
else
|
||||
fprintf(codefile, "return ASN1_MISSING_FIELD;\n");
|
||||
free(s);
|
||||
memno++;
|
||||
}
|
||||
fprintf(codefile, "}\n");
|
||||
break;
|
||||
}
|
||||
case TSetOf:
|
||||
case TSequenceOf: {
|
||||
char *n;
|
||||
char *sname;
|
||||
|
||||
fprintf (codefile,
|
||||
"{\n"
|
||||
"size_t %s_origlen = len;\n"
|
||||
"size_t %s_oldret = ret;\n"
|
||||
"void *%s_tmp;\n"
|
||||
"ret = 0;\n"
|
||||
"(%s)->len = 0;\n"
|
||||
"(%s)->val = NULL;\n"
|
||||
"while(ret < %s_origlen) {\n"
|
||||
"%s_tmp = realloc((%s)->val, "
|
||||
" sizeof(*((%s)->val)) * ((%s)->len + 1));\n"
|
||||
"if (%s_tmp == NULL) { %s; }\n"
|
||||
"(%s)->val = %s_tmp;\n",
|
||||
tmpstr, tmpstr, tmpstr,
|
||||
name, name,
|
||||
tmpstr, tmpstr,
|
||||
name, name, name,
|
||||
tmpstr, forwstr,
|
||||
name, tmpstr);
|
||||
|
||||
asprintf (&n, "&(%s)->val[(%s)->len]", name, name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
asprintf (&sname, "%s_s_of", tmpstr);
|
||||
if (sname == NULL)
|
||||
errx(1, "malloc");
|
||||
decode_type (n, t->subtype, 0, forwstr, sname);
|
||||
fprintf (codefile,
|
||||
"(%s)->len++;\n"
|
||||
"len = %s_origlen - ret;\n"
|
||||
"}\n"
|
||||
"ret += %s_oldret;\n"
|
||||
"}\n",
|
||||
name,
|
||||
tmpstr, tmpstr);
|
||||
free (n);
|
||||
free (sname);
|
||||
break;
|
||||
}
|
||||
case TGeneralizedTime:
|
||||
decode_primitive ("generalized_time", name, forwstr);
|
||||
break;
|
||||
case TGeneralString:
|
||||
decode_primitive ("general_string", name, forwstr);
|
||||
break;
|
||||
case TTag:{
|
||||
char *tname;
|
||||
|
||||
fprintf(codefile,
|
||||
"{\n"
|
||||
"size_t %s_datalen, %s_oldlen;\n",
|
||||
tmpstr, tmpstr);
|
||||
if(dce_fix)
|
||||
fprintf(codefile,
|
||||
"int dce_fix;\n");
|
||||
fprintf(codefile, "e = der_match_tag_and_length(p, len, %s, %s, %s, "
|
||||
"&%s_datalen, &l);\n",
|
||||
classname(t->tag.tagclass),
|
||||
is_primitive_type(t->subtype->type) ? "PRIM" : "CONS",
|
||||
valuename(t->tag.tagclass, t->tag.tagvalue),
|
||||
tmpstr);
|
||||
if(optional) {
|
||||
fprintf(codefile,
|
||||
"if(e) {\n"
|
||||
"%s = NULL;\n"
|
||||
"} else {\n"
|
||||
"%s = calloc(1, sizeof(*%s));\n"
|
||||
"if (%s == NULL) { e = ENOMEM; %s; }\n",
|
||||
name, name, name, name, forwstr);
|
||||
} else {
|
||||
fprintf(codefile, "if(e) %s;\n", forwstr);
|
||||
}
|
||||
fprintf (codefile,
|
||||
"p += l; len -= l; ret += l;\n"
|
||||
"%s_oldlen = len;\n",
|
||||
tmpstr);
|
||||
if(dce_fix)
|
||||
fprintf (codefile,
|
||||
"if((dce_fix = _heim_fix_dce(%s_datalen, &len)) < 0)\n"
|
||||
"{ e = ASN1_BAD_FORMAT; %s; }\n",
|
||||
tmpstr, forwstr);
|
||||
else
|
||||
fprintf(codefile,
|
||||
"if (%s_datalen > len) { e = ASN1_OVERRUN; %s; }\n"
|
||||
"len = %s_datalen;\n", tmpstr, forwstr, tmpstr);
|
||||
asprintf (&tname, "%s_Tag", tmpstr);
|
||||
if (tname == NULL)
|
||||
errx(1, "malloc");
|
||||
decode_type (name, t->subtype, 0, forwstr, tname);
|
||||
if(dce_fix)
|
||||
fprintf(codefile,
|
||||
"if(dce_fix){\n"
|
||||
"e = der_match_tag_and_length (p, len, "
|
||||
"(Der_class)0,(Der_type)0, UT_EndOfContent, "
|
||||
"&%s_datalen, &l);\n"
|
||||
"if(e) %s;\np += l; len -= l; ret += l;\n"
|
||||
"} else \n", tmpstr, forwstr);
|
||||
fprintf(codefile,
|
||||
"len = %s_oldlen - %s_datalen;\n",
|
||||
tmpstr, tmpstr);
|
||||
if(optional)
|
||||
fprintf(codefile,
|
||||
"}\n");
|
||||
fprintf(codefile,
|
||||
"}\n");
|
||||
free(tname);
|
||||
break;
|
||||
}
|
||||
case TChoice: {
|
||||
Member *m, *have_ellipsis = NULL;
|
||||
const char *els = "";
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
const Type *tt = m->type;
|
||||
char *s;
|
||||
Der_class cl;
|
||||
Der_type ty;
|
||||
unsigned tag;
|
||||
|
||||
if (m->ellipsis) {
|
||||
have_ellipsis = m;
|
||||
continue;
|
||||
}
|
||||
|
||||
find_tag(tt, &cl, &ty, &tag);
|
||||
|
||||
fprintf(codefile,
|
||||
"%sif (der_match_tag(p, len, %s, %s, %s, NULL) == 0) {\n",
|
||||
els,
|
||||
classname(cl),
|
||||
ty ? "CONS" : "PRIM",
|
||||
valuename(cl, tag));
|
||||
asprintf (&s, "%s(%s)->u.%s", m->optional ? "" : "&",
|
||||
name, m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
decode_type (s, m->type, m->optional, forwstr, m->gen_name);
|
||||
fprintf(codefile,
|
||||
"(%s)->element = %s;\n",
|
||||
name, m->label);
|
||||
free(s);
|
||||
fprintf(codefile,
|
||||
"}\n");
|
||||
els = "else ";
|
||||
}
|
||||
if (have_ellipsis) {
|
||||
fprintf(codefile,
|
||||
"else {\n"
|
||||
"(%s)->u.%s.data = calloc(1, len);\n"
|
||||
"if ((%s)->u.%s.data == NULL) {\n"
|
||||
"e = ENOMEM; %s;\n"
|
||||
"}\n"
|
||||
"(%s)->u.%s.length = len;\n"
|
||||
"memcpy((%s)->u.%s.data, p, len);\n"
|
||||
"(%s)->element = %s;\n"
|
||||
"p += len;\n"
|
||||
"ret += len;\n"
|
||||
"len -= len;\n"
|
||||
"}\n",
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name,
|
||||
forwstr,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->label);
|
||||
} else {
|
||||
fprintf(codefile,
|
||||
"else {\n"
|
||||
"e = ASN1_PARSE_ERROR;\n"
|
||||
"%s;\n"
|
||||
"}\n",
|
||||
forwstr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TUTCTime:
|
||||
decode_primitive ("utctime", name, forwstr);
|
||||
break;
|
||||
case TUTF8String:
|
||||
decode_primitive ("utf8string", name, forwstr);
|
||||
break;
|
||||
case TPrintableString:
|
||||
decode_primitive ("printable_string", name, forwstr);
|
||||
break;
|
||||
case TIA5String:
|
||||
decode_primitive ("ia5_string", name, forwstr);
|
||||
break;
|
||||
case TBMPString:
|
||||
decode_primitive ("bmp_string", name, forwstr);
|
||||
break;
|
||||
case TUniversalString:
|
||||
decode_primitive ("universal_string", name, forwstr);
|
||||
break;
|
||||
case TNull:
|
||||
fprintf (codefile, "/* NULL */\n");
|
||||
break;
|
||||
case TOID:
|
||||
decode_primitive ("oid", name, forwstr);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
generate_type_decode (const Symbol *s)
|
||||
{
|
||||
int preserve = preserve_type(s->name) ? TRUE : FALSE;
|
||||
|
||||
fprintf (headerfile,
|
||||
"int "
|
||||
"decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"decode_%s(const unsigned char *p,"
|
||||
" size_t len, %s *data, size_t *size)\n"
|
||||
"{\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
switch (s->type->type) {
|
||||
case TInteger:
|
||||
case TBoolean:
|
||||
case TOctetString:
|
||||
case TOID:
|
||||
case TGeneralizedTime:
|
||||
case TGeneralString:
|
||||
case TUTF8String:
|
||||
case TPrintableString:
|
||||
case TIA5String:
|
||||
case TBMPString:
|
||||
case TUniversalString:
|
||||
case TUTCTime:
|
||||
case TNull:
|
||||
case TEnumerated:
|
||||
case TBitString:
|
||||
case TSequence:
|
||||
case TSequenceOf:
|
||||
case TSet:
|
||||
case TSetOf:
|
||||
case TTag:
|
||||
case TType:
|
||||
case TChoice:
|
||||
fprintf (codefile,
|
||||
"size_t ret = 0;\n"
|
||||
"size_t l;\n"
|
||||
"int e;\n");
|
||||
if (preserve)
|
||||
fprintf (codefile, "const unsigned char *begin = p;\n");
|
||||
|
||||
fprintf (codefile, "\n");
|
||||
fprintf (codefile, "memset(data, 0, sizeof(*data));\n"); /* hack to avoid `unused variable' */
|
||||
|
||||
decode_type ("data", s->type, 0, "goto fail", "Top");
|
||||
if (preserve)
|
||||
fprintf (codefile,
|
||||
"data->_save.data = calloc(1, ret);\n"
|
||||
"if (data->_save.data == NULL) { \n"
|
||||
"e = ENOMEM; goto fail; \n"
|
||||
"}\n"
|
||||
"data->_save.length = ret;\n"
|
||||
"memcpy(data->_save.data, begin, ret);\n");
|
||||
fprintf (codefile,
|
||||
"if(size) *size = ret;\n"
|
||||
"return 0;\n");
|
||||
fprintf (codefile,
|
||||
"fail:\n"
|
||||
"free_%s(data);\n"
|
||||
"return e;\n",
|
||||
s->gen_name);
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
fprintf (codefile, "}\n\n");
|
||||
}
|
||||
@@ -0,0 +1,532 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
|
||||
RCSID("$Id: gen_encode.c,v 1.19 2005/08/23 11:52:16 lha Exp $");
|
||||
|
||||
static void
|
||||
encode_primitive (const char *typename, const char *name)
|
||||
{
|
||||
fprintf (codefile,
|
||||
"e = der_put_%s(p, len, %s, &l);\n"
|
||||
"if (e) return e;\np -= l; len -= l; ret += l;\n\n",
|
||||
typename,
|
||||
name);
|
||||
}
|
||||
|
||||
const char *
|
||||
classname(Der_class class)
|
||||
{
|
||||
const char *cn[] = { "ASN1_C_UNIV", "ASN1_C_APPL",
|
||||
"ASN1_C_CONTEXT", "ASN1_C_PRIV" };
|
||||
if(class < ASN1_C_UNIV || class > ASN1_C_PRIVATE)
|
||||
return "???";
|
||||
return cn[class];
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
valuename(Der_class class, int value)
|
||||
{
|
||||
static char s[32];
|
||||
struct {
|
||||
int value;
|
||||
const char *s;
|
||||
} *p, values[] = {
|
||||
#define X(Y) { Y, #Y }
|
||||
X(UT_BMPString),
|
||||
X(UT_BitString),
|
||||
X(UT_Boolean),
|
||||
X(UT_EmbeddedPDV),
|
||||
X(UT_Enumerated),
|
||||
X(UT_External),
|
||||
X(UT_GeneralString),
|
||||
X(UT_GeneralizedTime),
|
||||
X(UT_GraphicString),
|
||||
X(UT_IA5String),
|
||||
X(UT_Integer),
|
||||
X(UT_Null),
|
||||
X(UT_NumericString),
|
||||
X(UT_OID),
|
||||
X(UT_ObjectDescriptor),
|
||||
X(UT_OctetString),
|
||||
X(UT_PrintableString),
|
||||
X(UT_Real),
|
||||
X(UT_RelativeOID),
|
||||
X(UT_Sequence),
|
||||
X(UT_Set),
|
||||
X(UT_TeletexString),
|
||||
X(UT_UTCTime),
|
||||
X(UT_UTF8String),
|
||||
X(UT_UniversalString),
|
||||
X(UT_VideotexString),
|
||||
X(UT_VisibleString),
|
||||
#undef X
|
||||
{ -1, NULL }
|
||||
};
|
||||
if(class == ASN1_C_UNIV) {
|
||||
for(p = values; p->value != -1; p++)
|
||||
if(p->value == value)
|
||||
return p->s;
|
||||
}
|
||||
snprintf(s, sizeof(s), "%d", value);
|
||||
return s;
|
||||
}
|
||||
|
||||
static int
|
||||
encode_type (const char *name, const Type *t, const char *tmpstr)
|
||||
{
|
||||
int constructed = 1;
|
||||
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
#if 0
|
||||
encode_type (name, t->symbol->type);
|
||||
#endif
|
||||
fprintf (codefile,
|
||||
"e = encode_%s(p, len, %s, &l);\n"
|
||||
"if (e) return e;\np -= l; len -= l; ret += l;\n\n",
|
||||
t->symbol->gen_name, name);
|
||||
break;
|
||||
case TInteger:
|
||||
if(t->members) {
|
||||
char *s;
|
||||
asprintf(&s, "(const int*)%s", name);
|
||||
if(s == NULL)
|
||||
errx(1, "out of memory");
|
||||
encode_primitive ("integer", s);
|
||||
free(s);
|
||||
} else if (t->range == NULL) {
|
||||
encode_primitive ("heim_integer", name);
|
||||
} else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
|
||||
encode_primitive ("integer", name);
|
||||
} else if (t->range->min == 0 && t->range->max == UINT_MAX) {
|
||||
encode_primitive ("unsigned", name);
|
||||
} else if (t->range->min == 0 && t->range->max == INT_MAX) {
|
||||
encode_primitive ("unsigned", name);
|
||||
} else
|
||||
errx(1, "%s: unsupported range %d -> %d",
|
||||
name, t->range->min, t->range->max);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TBoolean:
|
||||
encode_primitive ("boolean", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TOctetString:
|
||||
encode_primitive ("octet_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TBitString: {
|
||||
Member *m;
|
||||
int pos;
|
||||
int rest;
|
||||
|
||||
if (ASN1_TAILQ_EMPTY(t->members)) {
|
||||
encode_primitive("bit_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf (codefile, "{\n"
|
||||
"unsigned char c = 0;\n");
|
||||
if (!rfc1510_bitstring)
|
||||
fprintf (codefile,
|
||||
"int bit_set = 0;\n");
|
||||
#if 0
|
||||
pos = t->members->prev->val;
|
||||
/* fix for buggy MIT (and OSF?) code */
|
||||
if (pos > 31)
|
||||
abort ();
|
||||
#endif
|
||||
/*
|
||||
* It seems that if we do not always set pos to 31 here, the MIT
|
||||
* code will do the wrong thing.
|
||||
*
|
||||
* I hate ASN.1 (and DER), but I hate it even more when everybody
|
||||
* has to screw it up differently.
|
||||
*/
|
||||
pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
|
||||
if (rfc1510_bitstring) {
|
||||
if (pos < 31)
|
||||
pos = 31;
|
||||
rest = 7 - (pos % 8);
|
||||
} else
|
||||
rest = 0;
|
||||
|
||||
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
|
||||
while (m->val / 8 < pos / 8) {
|
||||
if (!rfc1510_bitstring)
|
||||
fprintf (codefile,
|
||||
"if (c != 0 || bit_set) {\n");
|
||||
fprintf (codefile,
|
||||
"if (len < 1) return ASN1_OVERFLOW;\n"
|
||||
"*p-- = c; len--; ret++;\n"
|
||||
"c = 0;\n");
|
||||
if (!rfc1510_bitstring)
|
||||
fprintf (codefile,
|
||||
"bit_set = 1;\n"
|
||||
"}\n");
|
||||
pos -= 8;
|
||||
}
|
||||
fprintf (codefile,
|
||||
"if((%s)->%s) {\n"
|
||||
"c |= 1<<%d;\n",
|
||||
name, m->gen_name, 7 - m->val % 8);
|
||||
if (!rfc1510_bitstring)
|
||||
rest = 7 - m->val % 8;
|
||||
fprintf (codefile,
|
||||
"}\n");
|
||||
}
|
||||
|
||||
if (!rfc1510_bitstring)
|
||||
fprintf (codefile,
|
||||
"if (c != 0 || bit_set) {\n");
|
||||
fprintf (codefile,
|
||||
"if (len < 1) return ASN1_OVERFLOW;\n"
|
||||
"*p-- = c; len--; ret++;\n");
|
||||
if (!rfc1510_bitstring)
|
||||
fprintf (codefile,
|
||||
"}\n");
|
||||
|
||||
fprintf (codefile,
|
||||
"if (len < 1) return ASN1_OVERFLOW;\n"
|
||||
"*p-- = %d;\n"
|
||||
"len -= 1;\n"
|
||||
"ret += 1;\n"
|
||||
"}\n\n",
|
||||
rest);
|
||||
constructed = 0;
|
||||
break;
|
||||
}
|
||||
case TEnumerated : {
|
||||
encode_primitive ("enumerated", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case TSet:
|
||||
case TSequence: {
|
||||
Member *m;
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
|
||||
char *s;
|
||||
|
||||
if (m->ellipsis)
|
||||
continue;
|
||||
|
||||
asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
fprintf(codefile, "/* %s */\n", m->name);
|
||||
if (m->optional)
|
||||
fprintf (codefile,
|
||||
"if(%s) ",
|
||||
s);
|
||||
else if(m->defval)
|
||||
gen_compare_defval(s + 1, m->defval);
|
||||
fprintf (codefile, "{\n");
|
||||
fprintf (codefile, "size_t %s_oldret = ret;\n", tmpstr);
|
||||
fprintf (codefile, "ret = 0;\n");
|
||||
encode_type (s, m->type, m->gen_name);
|
||||
fprintf (codefile, "ret += %s_oldret;\n", tmpstr);
|
||||
fprintf (codefile, "}\n");
|
||||
free (s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSetOf: {
|
||||
|
||||
fprintf(codefile,
|
||||
"{\n"
|
||||
"struct heim_octet_string *val;\n"
|
||||
"size_t elen, totallen = 0;\n"
|
||||
"int eret;\n");
|
||||
|
||||
fprintf(codefile,
|
||||
"val = malloc(sizeof(val[0]) * (%s)->len);\n"
|
||||
"if (val == NULL && (%s)->len != 0) return ENOMEM;\n",
|
||||
name, name);
|
||||
|
||||
fprintf(codefile,
|
||||
"for(i = 0; i < (%s)->len; i++) {\n",
|
||||
name);
|
||||
|
||||
fprintf(codefile,
|
||||
"ASN1_MALLOC_ENCODE(%s, val[i].data, "
|
||||
"val[i].length, &(%s)->val[i], &elen, eret);\n",
|
||||
t->subtype->symbol->gen_name,
|
||||
name);
|
||||
|
||||
fprintf(codefile,
|
||||
"if(eret) {\n"
|
||||
"i--;\n"
|
||||
"while (i >= 0) {\n"
|
||||
"free(val[i].data);\n"
|
||||
"i--;\n"
|
||||
"}\n"
|
||||
"free(val);\n"
|
||||
"return eret;\n"
|
||||
"}\n"
|
||||
"totallen += elen;\n"
|
||||
"}\n");
|
||||
|
||||
fprintf(codefile,
|
||||
"if (totallen > len) {\n"
|
||||
"for (i = 0; i < (%s)->len; i++) {\n"
|
||||
"free(val[i].data);\n"
|
||||
"}\n"
|
||||
"free(val);\n"
|
||||
"return ASN1_OVERFLOW;\n"
|
||||
"}\n",
|
||||
name);
|
||||
|
||||
fprintf(codefile,
|
||||
"qsort(val, (%s)->len, sizeof(val[0]), _heim_der_set_sort);\n",
|
||||
name);
|
||||
|
||||
fprintf (codefile,
|
||||
"for(i = (%s)->len - 1; i >= 0; --i) {\n"
|
||||
"p -= val[i].length;\n"
|
||||
"ret += val[i].length;\n"
|
||||
"memcpy(p + 1, val[i].data, val[i].length);\n"
|
||||
"free(val[i].data);\n"
|
||||
"}\n"
|
||||
"free(val);\n"
|
||||
"}\n",
|
||||
name);
|
||||
break;
|
||||
}
|
||||
case TSequenceOf: {
|
||||
char *n;
|
||||
char *sname;
|
||||
|
||||
fprintf (codefile,
|
||||
"for(i = (%s)->len - 1; i >= 0; --i) {\n"
|
||||
"size_t %s_for_oldret = ret;\n"
|
||||
"ret = 0;\n",
|
||||
name, tmpstr);
|
||||
asprintf (&n, "&(%s)->val[i]", name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
asprintf (&sname, "%s_S_Of", tmpstr);
|
||||
if (sname == NULL)
|
||||
errx(1, "malloc");
|
||||
encode_type (n, t->subtype, sname);
|
||||
fprintf (codefile,
|
||||
"ret += %s_for_oldret;\n"
|
||||
"}\n",
|
||||
tmpstr);
|
||||
free (n);
|
||||
free (sname);
|
||||
break;
|
||||
}
|
||||
case TGeneralizedTime:
|
||||
encode_primitive ("generalized_time", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TGeneralString:
|
||||
encode_primitive ("general_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TTag: {
|
||||
char *tname;
|
||||
int c;
|
||||
asprintf (&tname, "%s_tag", tmpstr);
|
||||
if (tname == NULL)
|
||||
errx(1, "malloc");
|
||||
c = encode_type (name, t->subtype, tname);
|
||||
fprintf (codefile,
|
||||
"e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n"
|
||||
"if (e) return e;\np -= l; len -= l; ret += l;\n\n",
|
||||
classname(t->tag.tagclass),
|
||||
c ? "CONS" : "PRIM",
|
||||
valuename(t->tag.tagclass, t->tag.tagvalue));
|
||||
free (tname);
|
||||
break;
|
||||
}
|
||||
case TChoice:{
|
||||
Member *m, *have_ellipsis = NULL;
|
||||
char *s;
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
fprintf(codefile, "\n");
|
||||
|
||||
asprintf (&s, "(%s)", name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
fprintf(codefile, "switch(%s->element) {\n", s);
|
||||
|
||||
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
|
||||
char *s2;
|
||||
|
||||
if (m->ellipsis) {
|
||||
have_ellipsis = m;
|
||||
continue;
|
||||
}
|
||||
|
||||
fprintf (codefile, "case %s: {", m->label);
|
||||
asprintf(&s2, "%s(%s)->u.%s", m->optional ? "" : "&",
|
||||
s, m->gen_name);
|
||||
if (s2 == NULL)
|
||||
errx(1, "malloc");
|
||||
if (m->optional)
|
||||
fprintf (codefile, "if(%s) {\n", s2);
|
||||
fprintf (codefile, "size_t %s_oldret = ret;\n", tmpstr);
|
||||
fprintf (codefile, "ret = 0;\n");
|
||||
constructed = encode_type (s2, m->type, m->gen_name);
|
||||
fprintf (codefile, "ret += %s_oldret;\n", tmpstr);
|
||||
if(m->optional)
|
||||
fprintf (codefile, "}\n");
|
||||
fprintf(codefile, "break;\n");
|
||||
fprintf(codefile, "}\n");
|
||||
free (s2);
|
||||
}
|
||||
free (s);
|
||||
if (have_ellipsis) {
|
||||
fprintf(codefile,
|
||||
"case %s: {\n"
|
||||
"if (len < (%s)->u.%s.length)\n"
|
||||
"return ASN1_OVERFLOW;\n"
|
||||
"p -= (%s)->u.%s.length;\n"
|
||||
"ret += (%s)->u.%s.length;\n"
|
||||
"memcpy(p + 1, (%s)->u.%s.data, (%s)->u.%s.length);\n"
|
||||
"break;\n"
|
||||
"}\n",
|
||||
have_ellipsis->label,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name,
|
||||
name, have_ellipsis->gen_name);
|
||||
}
|
||||
fprintf(codefile, "};\n");
|
||||
break;
|
||||
}
|
||||
case TOID:
|
||||
encode_primitive ("oid", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TUTCTime:
|
||||
encode_primitive ("utctime", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TUTF8String:
|
||||
encode_primitive ("utf8string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TPrintableString:
|
||||
encode_primitive ("printable_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TIA5String:
|
||||
encode_primitive ("ia5_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TBMPString:
|
||||
encode_primitive ("bmp_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TUniversalString:
|
||||
encode_primitive ("universal_string", name);
|
||||
constructed = 0;
|
||||
break;
|
||||
case TNull:
|
||||
fprintf (codefile, "/* NULL */\n");
|
||||
constructed = 0;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
return constructed;
|
||||
}
|
||||
|
||||
void
|
||||
generate_type_encode (const Symbol *s)
|
||||
{
|
||||
fprintf (headerfile,
|
||||
"int "
|
||||
"encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"encode_%s(unsigned char *p, size_t len,"
|
||||
" const %s *data, size_t *size)\n"
|
||||
"{\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
switch (s->type->type) {
|
||||
case TInteger:
|
||||
case TBoolean:
|
||||
case TOctetString:
|
||||
case TGeneralizedTime:
|
||||
case TGeneralString:
|
||||
case TUTCTime:
|
||||
case TUTF8String:
|
||||
case TPrintableString:
|
||||
case TIA5String:
|
||||
case TBMPString:
|
||||
case TUniversalString:
|
||||
case TNull:
|
||||
case TBitString:
|
||||
case TEnumerated:
|
||||
case TOID:
|
||||
case TSequence:
|
||||
case TSequenceOf:
|
||||
case TSet:
|
||||
case TSetOf:
|
||||
case TTag:
|
||||
case TType:
|
||||
case TChoice:
|
||||
fprintf (codefile,
|
||||
"size_t ret = 0;\n"
|
||||
"size_t l;\n"
|
||||
"int i, e;\n\n");
|
||||
fprintf(codefile, "i = 0;\n"); /* hack to avoid `unused variable' */
|
||||
|
||||
encode_type("data", s->type, "Top");
|
||||
|
||||
fprintf (codefile, "*size = ret;\n"
|
||||
"return 0;\n");
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
fprintf (codefile, "}\n\n");
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
|
||||
RCSID("$Id: gen_free.c,v 1.16 2006/10/14 05:33:58 lha Exp $");
|
||||
|
||||
static void
|
||||
free_primitive (const char *typename, const char *name)
|
||||
{
|
||||
fprintf (codefile, "der_free_%s(%s);\n", typename, name);
|
||||
}
|
||||
|
||||
static void
|
||||
free_type (const char *name, const Type *t, int preserve)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
#if 0
|
||||
free_type (name, t->symbol->type, preserve);
|
||||
#endif
|
||||
fprintf (codefile, "free_%s(%s);\n", t->symbol->gen_name, name);
|
||||
break;
|
||||
case TInteger:
|
||||
if (t->range == NULL && t->members == NULL) {
|
||||
free_primitive ("heim_integer", name);
|
||||
break;
|
||||
}
|
||||
case TBoolean:
|
||||
case TEnumerated :
|
||||
case TNull:
|
||||
case TGeneralizedTime:
|
||||
case TUTCTime:
|
||||
break;
|
||||
case TBitString:
|
||||
if (ASN1_TAILQ_EMPTY(t->members))
|
||||
free_primitive("bit_string", name);
|
||||
break;
|
||||
case TOctetString:
|
||||
free_primitive ("octet_string", name);
|
||||
break;
|
||||
case TChoice:
|
||||
case TSet:
|
||||
case TSequence: {
|
||||
Member *m, *have_ellipsis = NULL;
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
if ((t->type == TSequence || t->type == TChoice) && preserve)
|
||||
fprintf(codefile, "der_free_octet_string(&data->_save);\n");
|
||||
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "switch((%s)->element) {\n", name);
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *s;
|
||||
|
||||
if (m->ellipsis){
|
||||
have_ellipsis = m;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "case %s:\n", m->label);
|
||||
asprintf (&s, "%s(%s)->%s%s",
|
||||
m->optional ? "" : "&", name,
|
||||
t->type == TChoice ? "u." : "", m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
if(m->optional)
|
||||
fprintf(codefile, "if(%s) {\n", s);
|
||||
free_type (s, m->type, FALSE);
|
||||
if(m->optional)
|
||||
fprintf(codefile,
|
||||
"free(%s);\n"
|
||||
"%s = NULL;\n"
|
||||
"}\n",s, s);
|
||||
free (s);
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "break;\n");
|
||||
}
|
||||
|
||||
if(t->type == TChoice) {
|
||||
if (have_ellipsis)
|
||||
fprintf(codefile,
|
||||
"case %s:\n"
|
||||
"der_free_octet_string(&(%s)->u.%s);\n"
|
||||
"break;",
|
||||
have_ellipsis->label,
|
||||
name, have_ellipsis->gen_name);
|
||||
fprintf(codefile, "}\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSetOf:
|
||||
case TSequenceOf: {
|
||||
char *n;
|
||||
|
||||
fprintf (codefile, "while((%s)->len){\n", name);
|
||||
asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
free_type(n, t->subtype, FALSE);
|
||||
fprintf(codefile,
|
||||
"(%s)->len--;\n"
|
||||
"}\n",
|
||||
name);
|
||||
fprintf(codefile,
|
||||
"free((%s)->val);\n"
|
||||
"(%s)->val = NULL;\n", name, name);
|
||||
free(n);
|
||||
break;
|
||||
}
|
||||
case TGeneralString:
|
||||
free_primitive ("general_string", name);
|
||||
break;
|
||||
case TUTF8String:
|
||||
free_primitive ("utf8string", name);
|
||||
break;
|
||||
case TPrintableString:
|
||||
free_primitive ("printable_string", name);
|
||||
break;
|
||||
case TIA5String:
|
||||
free_primitive ("ia5_string", name);
|
||||
break;
|
||||
case TBMPString:
|
||||
free_primitive ("bmp_string", name);
|
||||
break;
|
||||
case TUniversalString:
|
||||
free_primitive ("universal_string", name);
|
||||
break;
|
||||
case TTag:
|
||||
free_type (name, t->subtype, preserve);
|
||||
break;
|
||||
case TOID :
|
||||
free_primitive ("oid", name);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
generate_type_free (const Symbol *s)
|
||||
{
|
||||
int preserve = preserve_type(s->name) ? TRUE : FALSE;
|
||||
|
||||
fprintf (headerfile,
|
||||
"void free_%s (%s *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "void\n"
|
||||
"free_%s(%s *data)\n"
|
||||
"{\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
free_type ("data", s->type, preserve);
|
||||
fprintf (codefile, "}\n\n");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1999, 2000, 2003 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
|
||||
RCSID("$Id: gen_glue.c,v 1.9 2005/07/12 06:27:29 lha Exp $");
|
||||
|
||||
static void
|
||||
generate_2int (const Type *t, const char *gen_name)
|
||||
{
|
||||
Member *m;
|
||||
|
||||
fprintf (headerfile,
|
||||
"unsigned %s2int(%s);\n",
|
||||
gen_name, gen_name);
|
||||
|
||||
fprintf (codefile,
|
||||
"unsigned %s2int(%s f)\n"
|
||||
"{\n"
|
||||
"unsigned r = 0;\n",
|
||||
gen_name, gen_name);
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
fprintf (codefile, "if(f.%s) r |= (1U << %d);\n",
|
||||
m->gen_name, m->val);
|
||||
}
|
||||
fprintf (codefile, "return r;\n"
|
||||
"}\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
generate_int2 (const Type *t, const char *gen_name)
|
||||
{
|
||||
Member *m;
|
||||
|
||||
fprintf (headerfile,
|
||||
"%s int2%s(unsigned);\n",
|
||||
gen_name, gen_name);
|
||||
|
||||
fprintf (codefile,
|
||||
"%s int2%s(unsigned n)\n"
|
||||
"{\n"
|
||||
"\t%s flags;\n\n",
|
||||
gen_name, gen_name, gen_name);
|
||||
|
||||
if(t->members) {
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
fprintf (codefile, "\tflags.%s = (n >> %d) & 1;\n",
|
||||
m->gen_name, m->val);
|
||||
}
|
||||
}
|
||||
fprintf (codefile, "\treturn flags;\n"
|
||||
"}\n\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This depends on the bit string being declared in increasing order
|
||||
*/
|
||||
|
||||
static void
|
||||
generate_units (const Type *t, const char *gen_name)
|
||||
{
|
||||
Member *m;
|
||||
|
||||
fprintf (headerfile,
|
||||
"const struct units * asn1_%s_units(void);",
|
||||
gen_name);
|
||||
|
||||
fprintf (codefile,
|
||||
"static struct units %s_units[] = {\n",
|
||||
gen_name);
|
||||
|
||||
if(t->members) {
|
||||
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
|
||||
fprintf (codefile,
|
||||
"\t{\"%s\",\t1U << %d},\n", m->gen_name, m->val);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf (codefile,
|
||||
"\t{NULL,\t0}\n"
|
||||
"};\n\n");
|
||||
|
||||
fprintf (codefile,
|
||||
"const struct units * asn1_%s_units(void){\n"
|
||||
"return %s_units;\n"
|
||||
"}\n\n",
|
||||
gen_name, gen_name);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
generate_glue (const Type *t, const char *gen_name)
|
||||
{
|
||||
switch(t->type) {
|
||||
case TTag:
|
||||
generate_glue(t->subtype, gen_name);
|
||||
break;
|
||||
case TBitString :
|
||||
if (!ASN1_TAILQ_EMPTY(t->members)) {
|
||||
generate_2int (t, gen_name);
|
||||
generate_int2 (t, gen_name);
|
||||
generate_units (t, gen_name);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
|
||||
RCSID("$Id: gen_length.c,v 1.21 2006/10/14 05:28:28 lha Exp $");
|
||||
|
||||
static void
|
||||
length_primitive (const char *typename,
|
||||
const char *name,
|
||||
const char *variable)
|
||||
{
|
||||
fprintf (codefile, "%s += der_length_%s(%s);\n", variable, typename, name);
|
||||
}
|
||||
|
||||
static size_t
|
||||
length_tag(unsigned int tag)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
if(tag <= 30)
|
||||
return 1;
|
||||
while(tag) {
|
||||
tag /= 128;
|
||||
len++;
|
||||
}
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
length_type (const char *name, const Type *t,
|
||||
const char *variable, const char *tmpstr)
|
||||
{
|
||||
switch (t->type) {
|
||||
case TType:
|
||||
#if 0
|
||||
length_type (name, t->symbol->type);
|
||||
#endif
|
||||
fprintf (codefile, "%s += length_%s(%s);\n",
|
||||
variable, t->symbol->gen_name, name);
|
||||
break;
|
||||
case TInteger:
|
||||
if(t->members) {
|
||||
char *s;
|
||||
asprintf(&s, "(const int*)%s", name);
|
||||
if(s == NULL)
|
||||
errx (1, "out of memory");
|
||||
length_primitive ("integer", s, variable);
|
||||
free(s);
|
||||
} else if (t->range == NULL) {
|
||||
length_primitive ("heim_integer", name, variable);
|
||||
} else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
|
||||
length_primitive ("integer", name, variable);
|
||||
} else if (t->range->min == 0 && t->range->max == UINT_MAX) {
|
||||
length_primitive ("unsigned", name, variable);
|
||||
} else if (t->range->min == 0 && t->range->max == INT_MAX) {
|
||||
length_primitive ("unsigned", name, variable);
|
||||
} else
|
||||
errx(1, "%s: unsupported range %d -> %d",
|
||||
name, t->range->min, t->range->max);
|
||||
|
||||
break;
|
||||
case TBoolean:
|
||||
fprintf (codefile, "%s += 1;\n", variable);
|
||||
break;
|
||||
case TEnumerated :
|
||||
length_primitive ("enumerated", name, variable);
|
||||
break;
|
||||
case TOctetString:
|
||||
length_primitive ("octet_string", name, variable);
|
||||
break;
|
||||
case TBitString: {
|
||||
if (ASN1_TAILQ_EMPTY(t->members))
|
||||
length_primitive("bit_string", name, variable);
|
||||
else {
|
||||
if (!rfc1510_bitstring) {
|
||||
Member *m;
|
||||
int pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
|
||||
|
||||
fprintf(codefile,
|
||||
"do {\n");
|
||||
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
|
||||
while (m->val / 8 < pos / 8) {
|
||||
pos -= 8;
|
||||
}
|
||||
fprintf (codefile,
|
||||
"if((%s)->%s) { %s += %d; break; }\n",
|
||||
name, m->gen_name, variable, (pos + 8) / 8);
|
||||
}
|
||||
fprintf(codefile,
|
||||
"} while(0);\n");
|
||||
fprintf (codefile, "%s += 1;\n", variable);
|
||||
} else {
|
||||
fprintf (codefile, "%s += 5;\n", variable);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSet:
|
||||
case TSequence:
|
||||
case TChoice: {
|
||||
Member *m, *have_ellipsis = NULL;
|
||||
|
||||
if (t->members == NULL)
|
||||
break;
|
||||
|
||||
if(t->type == TChoice)
|
||||
fprintf (codefile, "switch((%s)->element) {\n", name);
|
||||
|
||||
ASN1_TAILQ_FOREACH(m, t->members, members) {
|
||||
char *s;
|
||||
|
||||
if (m->ellipsis) {
|
||||
have_ellipsis = m;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "case %s:\n", m->label);
|
||||
|
||||
asprintf (&s, "%s(%s)->%s%s",
|
||||
m->optional ? "" : "&", name,
|
||||
t->type == TChoice ? "u." : "", m->gen_name);
|
||||
if (s == NULL)
|
||||
errx(1, "malloc");
|
||||
if (m->optional)
|
||||
fprintf (codefile, "if(%s)", s);
|
||||
else if(m->defval)
|
||||
gen_compare_defval(s + 1, m->defval);
|
||||
fprintf (codefile, "{\n"
|
||||
"size_t %s_oldret = %s;\n"
|
||||
"%s = 0;\n", tmpstr, variable, variable);
|
||||
length_type (s, m->type, "ret", m->gen_name);
|
||||
fprintf (codefile, "ret += %s_oldret;\n", tmpstr);
|
||||
fprintf (codefile, "}\n");
|
||||
free (s);
|
||||
if(t->type == TChoice)
|
||||
fprintf(codefile, "break;\n");
|
||||
}
|
||||
if(t->type == TChoice) {
|
||||
if (have_ellipsis)
|
||||
fprintf(codefile,
|
||||
"case %s:\n"
|
||||
"ret += (%s)->u.%s.length;\n"
|
||||
"break;\n",
|
||||
have_ellipsis->label,
|
||||
name,
|
||||
have_ellipsis->gen_name);
|
||||
fprintf (codefile, "}\n"); /* switch */
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSetOf:
|
||||
case TSequenceOf: {
|
||||
char *n;
|
||||
char *sname;
|
||||
|
||||
fprintf (codefile,
|
||||
"{\n"
|
||||
"int %s_oldret = %s;\n"
|
||||
"int i;\n"
|
||||
"%s = 0;\n",
|
||||
tmpstr, variable, variable);
|
||||
|
||||
fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
|
||||
fprintf (codefile, "int %s_for_oldret = %s;\n"
|
||||
"%s = 0;\n", tmpstr, variable, variable);
|
||||
asprintf (&n, "&(%s)->val[i]", name);
|
||||
if (n == NULL)
|
||||
errx(1, "malloc");
|
||||
asprintf (&sname, "%s_S_Of", tmpstr);
|
||||
if (sname == NULL)
|
||||
errx(1, "malloc");
|
||||
length_type(n, t->subtype, variable, sname);
|
||||
fprintf (codefile, "%s += %s_for_oldret;\n",
|
||||
variable, tmpstr);
|
||||
fprintf (codefile, "}\n");
|
||||
|
||||
fprintf (codefile,
|
||||
"%s += %s_oldret;\n"
|
||||
"}\n", variable, tmpstr);
|
||||
free(n);
|
||||
free(sname);
|
||||
break;
|
||||
}
|
||||
case TGeneralizedTime:
|
||||
length_primitive ("generalized_time", name, variable);
|
||||
break;
|
||||
case TGeneralString:
|
||||
length_primitive ("general_string", name, variable);
|
||||
break;
|
||||
case TUTCTime:
|
||||
length_primitive ("utctime", name, variable);
|
||||
break;
|
||||
case TUTF8String:
|
||||
length_primitive ("utf8string", name, variable);
|
||||
break;
|
||||
case TPrintableString:
|
||||
length_primitive ("printable_string", name, variable);
|
||||
break;
|
||||
case TIA5String:
|
||||
length_primitive ("ia5_string", name, variable);
|
||||
break;
|
||||
case TBMPString:
|
||||
length_primitive ("bmp_string", name, variable);
|
||||
break;
|
||||
case TUniversalString:
|
||||
length_primitive ("universal_string", name, variable);
|
||||
break;
|
||||
case TNull:
|
||||
fprintf (codefile, "/* NULL */\n");
|
||||
break;
|
||||
case TTag:{
|
||||
char *tname;
|
||||
asprintf(&tname, "%s_tag", tmpstr);
|
||||
if (tname == NULL)
|
||||
errx(1, "malloc");
|
||||
length_type (name, t->subtype, variable, tname);
|
||||
fprintf (codefile, "ret += %lu + der_length_len (ret);\n",
|
||||
(unsigned long)length_tag(t->tag.tagvalue));
|
||||
free(tname);
|
||||
break;
|
||||
}
|
||||
case TOID:
|
||||
length_primitive ("oid", name, variable);
|
||||
break;
|
||||
default :
|
||||
abort ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
generate_type_length (const Symbol *s)
|
||||
{
|
||||
fprintf (headerfile,
|
||||
"size_t length_%s(const %s *);\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile,
|
||||
"size_t\n"
|
||||
"length_%s(const %s *data)\n"
|
||||
"{\n"
|
||||
"size_t ret = 0;\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
length_type ("data", s->type, "ret", "Top");
|
||||
fprintf (codefile, "return ret;\n}\n\n");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id: gen_locl.h,v 1.14 2006/09/05 12:29:18 lha Exp $ */
|
||||
|
||||
#ifndef __GEN_LOCL_H__
|
||||
#define __GEN_LOCL_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <roken.h>
|
||||
#include "hash.h"
|
||||
#include "symbol.h"
|
||||
#include "asn1-common.h"
|
||||
#include "der.h"
|
||||
|
||||
void generate_type (const Symbol *);
|
||||
void generate_constant (const Symbol *);
|
||||
void generate_type_encode (const Symbol *);
|
||||
void generate_type_decode (const Symbol *);
|
||||
void generate_type_free (const Symbol *);
|
||||
void generate_type_length (const Symbol *);
|
||||
void generate_type_copy (const Symbol *);
|
||||
void generate_type_seq (const Symbol *);
|
||||
void generate_glue (const Type *, const char*);
|
||||
|
||||
const char *classname(Der_class);
|
||||
const char *valuename(Der_class, int);
|
||||
|
||||
void gen_compare_defval(const char *, struct value *);
|
||||
void gen_assign_defval(const char *, struct value *);
|
||||
|
||||
|
||||
void init_generate (const char *, const char *);
|
||||
const char *get_filename (void);
|
||||
void close_generate(void);
|
||||
void add_import(const char *);
|
||||
int yyparse(void);
|
||||
|
||||
int preserve_type(const char *);
|
||||
int seq_type(const char *);
|
||||
|
||||
extern FILE *headerfile, *codefile, *logfile;
|
||||
extern int dce_fix;
|
||||
extern int rfc1510_bitstring;
|
||||
|
||||
extern int error_flag;
|
||||
|
||||
#endif /* __GEN_LOCL_H__ */
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 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.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
|
||||
RCSID("$Id: gen_seq.c,v 1.4 2006/10/04 10:18:10 lha Exp $");
|
||||
|
||||
void
|
||||
generate_type_seq (const Symbol *s)
|
||||
{
|
||||
char *subname;
|
||||
Type *type;
|
||||
|
||||
if (!seq_type(s->name))
|
||||
return;
|
||||
type = s->type;
|
||||
while(type->type == TTag)
|
||||
type = type->subtype;
|
||||
|
||||
if (type->type != TSequenceOf) {
|
||||
printf("%s not seq of %d\n", s->name, (int)type->type);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Require the subtype to be a type so we can name it and use
|
||||
* copy_/free_
|
||||
*/
|
||||
|
||||
if (type->subtype->type != TType) {
|
||||
fprintf(stderr, "%s subtype is not a type, can't generate "
|
||||
"sequence code for this case: %d\n",
|
||||
s->name, (int)type->subtype->type);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
subname = type->subtype->symbol->gen_name;
|
||||
|
||||
fprintf (headerfile,
|
||||
"int add_%s (%s *, const %s *);\n"
|
||||
"int remove_%s (%s *, unsigned int);\n",
|
||||
s->gen_name, s->gen_name, subname,
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"add_%s(%s *data, const %s *element)\n"
|
||||
"{\n",
|
||||
s->gen_name, s->gen_name, subname);
|
||||
|
||||
fprintf (codefile,
|
||||
"int ret;\n"
|
||||
"void *ptr;\n"
|
||||
"\n"
|
||||
"ptr = realloc(data->val, \n"
|
||||
"\t(data->len + 1) * sizeof(data->val[0]));\n"
|
||||
"if (ptr == NULL) return ENOMEM;\n"
|
||||
"data->val = ptr;\n\n"
|
||||
"ret = copy_%s(element, &data->val[data->len]);\n"
|
||||
"if (ret) return ret;\n"
|
||||
"data->len++;\n"
|
||||
"return 0;\n",
|
||||
subname);
|
||||
|
||||
fprintf (codefile, "}\n\n");
|
||||
|
||||
fprintf (codefile, "int\n"
|
||||
"remove_%s(%s *data, unsigned int element)\n"
|
||||
"{\n",
|
||||
s->gen_name, s->gen_name);
|
||||
|
||||
fprintf (codefile,
|
||||
"void *ptr;\n"
|
||||
"\n"
|
||||
"if (data->len == 0 || element >= data->len)\n"
|
||||
"\treturn ASN1_OVERRUN;\n"
|
||||
"free_%s(&data->val[element]);\n"
|
||||
"data->len--;\n"
|
||||
/* don't move if its the last element */
|
||||
"if (element < data->len)\n"
|
||||
"\tmemmove(&data->val[element], &data->val[element + 1], \n"
|
||||
"\t\tsizeof(data->val[0]) * data->len);\n"
|
||||
/* resize but don't care about failures since it doesn't matter */
|
||||
"ptr = realloc(data->val, data->len * sizeof(data->val[0]));\n"
|
||||
"if (ptr) data->val = ptr;\n"
|
||||
"return 0;\n",
|
||||
subname);
|
||||
|
||||
fprintf (codefile, "}\n\n");
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 1997 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Hash table functions
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
|
||||
RCSID("$Id: hash.c,v 1.11 2006/04/07 22:16:00 lha Exp $");
|
||||
|
||||
static Hashentry *_search(Hashtab * htab, /* The hash table */
|
||||
void *ptr); /* And key */
|
||||
|
||||
Hashtab *
|
||||
hashtabnew(int sz,
|
||||
int (*cmp) (void *, void *),
|
||||
unsigned (*hash) (void *))
|
||||
{
|
||||
Hashtab *htab;
|
||||
int i;
|
||||
|
||||
assert(sz > 0);
|
||||
|
||||
htab = (Hashtab *) malloc(sizeof(Hashtab) + (sz - 1) * sizeof(Hashentry *));
|
||||
if (htab == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < sz; ++i)
|
||||
htab->tab[i] = NULL;
|
||||
|
||||
htab->cmp = cmp;
|
||||
htab->hash = hash;
|
||||
htab->sz = sz;
|
||||
return htab;
|
||||
}
|
||||
|
||||
/* Intern search function */
|
||||
|
||||
static Hashentry *
|
||||
_search(Hashtab * htab, void *ptr)
|
||||
{
|
||||
Hashentry *hptr;
|
||||
|
||||
assert(htab && ptr);
|
||||
|
||||
for (hptr = htab->tab[(*htab->hash) (ptr) % htab->sz];
|
||||
hptr;
|
||||
hptr = hptr->next)
|
||||
if ((*htab->cmp) (ptr, hptr->ptr) == 0)
|
||||
break;
|
||||
return hptr;
|
||||
}
|
||||
|
||||
/* Search for element in hash table */
|
||||
|
||||
void *
|
||||
hashtabsearch(Hashtab * htab, void *ptr)
|
||||
{
|
||||
Hashentry *tmp;
|
||||
|
||||
tmp = _search(htab, ptr);
|
||||
return tmp ? tmp->ptr : tmp;
|
||||
}
|
||||
|
||||
/* add element to hash table */
|
||||
/* if already there, set new value */
|
||||
/* !NULL if succesful */
|
||||
|
||||
void *
|
||||
hashtabadd(Hashtab * htab, void *ptr)
|
||||
{
|
||||
Hashentry *h = _search(htab, ptr);
|
||||
Hashentry **tabptr;
|
||||
|
||||
assert(htab && ptr);
|
||||
|
||||
if (h)
|
||||
free((void *) h->ptr);
|
||||
else {
|
||||
h = (Hashentry *) malloc(sizeof(Hashentry));
|
||||
if (h == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
tabptr = &htab->tab[(*htab->hash) (ptr) % htab->sz];
|
||||
h->next = *tabptr;
|
||||
*tabptr = h;
|
||||
h->prev = tabptr;
|
||||
if (h->next)
|
||||
h->next->prev = &h->next;
|
||||
}
|
||||
h->ptr = ptr;
|
||||
return h;
|
||||
}
|
||||
|
||||
/* delete element with key key. Iff freep, free Hashentry->ptr */
|
||||
|
||||
int
|
||||
_hashtabdel(Hashtab * htab, void *ptr, int freep)
|
||||
{
|
||||
Hashentry *h;
|
||||
|
||||
assert(htab && ptr);
|
||||
|
||||
h = _search(htab, ptr);
|
||||
if (h) {
|
||||
if (freep)
|
||||
free(h->ptr);
|
||||
if ((*(h->prev) = h->next))
|
||||
h->next->prev = h->prev;
|
||||
free(h);
|
||||
return 0;
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Do something for each element */
|
||||
|
||||
void
|
||||
hashtabforeach(Hashtab * htab, int (*func) (void *ptr, void *arg),
|
||||
void *arg)
|
||||
{
|
||||
Hashentry **h, *g;
|
||||
|
||||
assert(htab);
|
||||
|
||||
for (h = htab->tab; h < &htab->tab[htab->sz]; ++h)
|
||||
for (g = *h; g; g = g->next)
|
||||
if ((*func) (g->ptr, arg))
|
||||
return;
|
||||
}
|
||||
|
||||
/* standard hash-functions for strings */
|
||||
|
||||
unsigned
|
||||
hashadd(const char *s)
|
||||
{ /* Standard hash function */
|
||||
unsigned i;
|
||||
|
||||
assert(s);
|
||||
|
||||
for (i = 0; *s; ++s)
|
||||
i += *s;
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned
|
||||
hashcaseadd(const char *s)
|
||||
{ /* Standard hash function */
|
||||
unsigned i;
|
||||
|
||||
assert(s);
|
||||
|
||||
for (i = 0; *s; ++s)
|
||||
i += toupper((unsigned char)*s);
|
||||
return i;
|
||||
}
|
||||
|
||||
#define TWELVE (sizeof(unsigned))
|
||||
#define SEVENTYFIVE (6*sizeof(unsigned))
|
||||
#define HIGH_BITS (~((unsigned)(~0) >> TWELVE))
|
||||
|
||||
unsigned
|
||||
hashjpw(const char *ss)
|
||||
{ /* another hash function */
|
||||
unsigned h = 0;
|
||||
unsigned g;
|
||||
const unsigned char *s = (const unsigned char *)ss;
|
||||
|
||||
for (; *s; ++s) {
|
||||
h = (h << TWELVE) + *s;
|
||||
if ((g = h & HIGH_BITS))
|
||||
h = (h ^ (g >> SEVENTYFIVE)) & ~HIGH_BITS;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 1997 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* hash.h. Header file for hash table functions
|
||||
*/
|
||||
|
||||
/* $Id: hash.h,v 1.3 1999/12/02 17:05:02 joda Exp $ */
|
||||
|
||||
struct hashentry { /* Entry in bucket */
|
||||
struct hashentry **prev;
|
||||
struct hashentry *next;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
typedef struct hashentry Hashentry;
|
||||
|
||||
struct hashtab { /* Hash table */
|
||||
int (*cmp)(void *, void *); /* Compare function */
|
||||
unsigned (*hash)(void *); /* hash function */
|
||||
int sz; /* Size */
|
||||
Hashentry *tab[1]; /* The table */
|
||||
};
|
||||
|
||||
typedef struct hashtab Hashtab;
|
||||
|
||||
/* prototypes */
|
||||
|
||||
Hashtab *hashtabnew(int sz,
|
||||
int (*cmp)(void *, void *),
|
||||
unsigned (*hash)(void *)); /* Make new hash table */
|
||||
|
||||
void *hashtabsearch(Hashtab *htab, /* The hash table */
|
||||
void *ptr); /* The key */
|
||||
|
||||
|
||||
void *hashtabadd(Hashtab *htab, /* The hash table */
|
||||
void *ptr); /* The element */
|
||||
|
||||
int _hashtabdel(Hashtab *htab, /* The table */
|
||||
void *ptr, /* Key */
|
||||
int freep); /* Free data part? */
|
||||
|
||||
void hashtabforeach(Hashtab *htab,
|
||||
int (*func)(void *ptr, void *arg),
|
||||
void *arg);
|
||||
|
||||
unsigned hashadd(const char *s); /* Standard hash function */
|
||||
unsigned hashcaseadd(const char *s); /* Standard hash function */
|
||||
unsigned hashjpw(const char *s); /* another hash function */
|
||||
|
||||
/* macros */
|
||||
|
||||
/* Don't free space */
|
||||
#define hashtabdel(htab,key) _hashtabdel(htab,key,FALSE)
|
||||
|
||||
#define hashtabfree(htab,key) _hashtabdel(htab,key,TRUE) /* Do! */
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __HEIM_ANY_H__
|
||||
#define __HEIM_ANY_H__ 1
|
||||
|
||||
int encode_heim_any(unsigned char *, size_t, const heim_any *, size_t *);
|
||||
int decode_heim_any(const unsigned char *, size_t, heim_any *, size_t *);
|
||||
void free_heim_any(heim_any *);
|
||||
size_t length_heim_any(const heim_any *);
|
||||
int copy_heim_any(const heim_any *, heim_any *);
|
||||
|
||||
int encode_heim_any_set(unsigned char *, size_t,
|
||||
const heim_any_set *, size_t *);
|
||||
int decode_heim_any_set(const unsigned char *, size_t,
|
||||
heim_any_set *,size_t *);
|
||||
void free_heim_any_set(heim_any_set *);
|
||||
size_t length_heim_any_set(const heim_any_set *);
|
||||
int copy_heim_any_set(const heim_any_set *, heim_any_set *);
|
||||
int heim_any_cmp(const heim_any_set *, const heim_any_set *);
|
||||
|
||||
#endif /* __HEIM_ANY_H__ */
|
||||
@@ -0,0 +1,629 @@
|
||||
-- $Id: k5.asn1,v 1.50 2006/09/11 13:28:59 lha Exp $
|
||||
|
||||
KERBEROS5 DEFINITIONS ::=
|
||||
BEGIN
|
||||
|
||||
NAME-TYPE ::= INTEGER {
|
||||
KRB5_NT_UNKNOWN(0), -- Name type not known
|
||||
KRB5_NT_PRINCIPAL(1), -- Just the name of the principal as in
|
||||
KRB5_NT_SRV_INST(2), -- Service and other unique instance (krbtgt)
|
||||
KRB5_NT_SRV_HST(3), -- Service with host name as instance
|
||||
KRB5_NT_SRV_XHST(4), -- Service with host as remaining components
|
||||
KRB5_NT_UID(5), -- Unique ID
|
||||
KRB5_NT_X500_PRINCIPAL(6), -- PKINIT
|
||||
KRB5_NT_SMTP_NAME(7), -- Name in form of SMTP email name
|
||||
KRB5_NT_ENTERPRISE_PRINCIPAL(10), -- Windows 2000 UPN
|
||||
KRB5_NT_ENT_PRINCIPAL_AND_ID(-130), -- Windows 2000 UPN and SID
|
||||
KRB5_NT_MS_PRINCIPAL(-128), -- NT 4 style name
|
||||
KRB5_NT_MS_PRINCIPAL_AND_ID(-129) -- NT style name and SID
|
||||
}
|
||||
|
||||
-- message types
|
||||
|
||||
MESSAGE-TYPE ::= INTEGER {
|
||||
krb-as-req(10), -- Request for initial authentication
|
||||
krb-as-rep(11), -- Response to KRB_AS_REQ request
|
||||
krb-tgs-req(12), -- Request for authentication based on TGT
|
||||
krb-tgs-rep(13), -- Response to KRB_TGS_REQ request
|
||||
krb-ap-req(14), -- application request to server
|
||||
krb-ap-rep(15), -- Response to KRB_AP_REQ_MUTUAL
|
||||
krb-safe(20), -- Safe (checksummed) application message
|
||||
krb-priv(21), -- Private (encrypted) application message
|
||||
krb-cred(22), -- Private (encrypted) message to forward credentials
|
||||
krb-error(30) -- Error response
|
||||
}
|
||||
|
||||
|
||||
-- pa-data types
|
||||
|
||||
PADATA-TYPE ::= INTEGER {
|
||||
KRB5-PADATA-NONE(0),
|
||||
KRB5-PADATA-TGS-REQ(1),
|
||||
KRB5-PADATA-AP-REQ(1),
|
||||
KRB5-PADATA-ENC-TIMESTAMP(2),
|
||||
KRB5-PADATA-PW-SALT(3),
|
||||
KRB5-PADATA-ENC-UNIX-TIME(5),
|
||||
KRB5-PADATA-SANDIA-SECUREID(6),
|
||||
KRB5-PADATA-SESAME(7),
|
||||
KRB5-PADATA-OSF-DCE(8),
|
||||
KRB5-PADATA-CYBERSAFE-SECUREID(9),
|
||||
KRB5-PADATA-AFS3-SALT(10),
|
||||
KRB5-PADATA-ETYPE-INFO(11),
|
||||
KRB5-PADATA-SAM-CHALLENGE(12), -- (sam/otp)
|
||||
KRB5-PADATA-SAM-RESPONSE(13), -- (sam/otp)
|
||||
KRB5-PADATA-PK-AS-REQ-19(14), -- (PKINIT-19)
|
||||
KRB5-PADATA-PK-AS-REP-19(15), -- (PKINIT-19)
|
||||
KRB5-PADATA-PK-AS-REQ-WIN(15), -- (PKINIT - old number)
|
||||
KRB5-PADATA-PK-AS-REQ(16), -- (PKINIT-25)
|
||||
KRB5-PADATA-PK-AS-REP(17), -- (PKINIT-25)
|
||||
KRB5-PADATA-PA-PK-OCSP-RESPONSE(18),
|
||||
KRB5-PADATA-ETYPE-INFO2(19),
|
||||
KRB5-PADATA-USE-SPECIFIED-KVNO(20),
|
||||
KRB5-PADATA-SAM-REDIRECT(21), -- (sam/otp)
|
||||
KRB5-PADATA-GET-FROM-TYPED-DATA(22),
|
||||
KRB5-PADATA-SAM-ETYPE-INFO(23),
|
||||
KRB5-PADATA-SERVER-REFERRAL(25),
|
||||
KRB5-PADATA-TD-KRB-PRINCIPAL(102), -- PrincipalName
|
||||
KRB5-PADATA-PK-TD-TRUSTED-CERTIFIERS(104), -- PKINIT
|
||||
KRB5-PADATA-PK-TD-CERTIFICATE-INDEX(105), -- PKINIT
|
||||
KRB5-PADATA-TD-APP-DEFINED-ERROR(106), -- application specific
|
||||
KRB5-PADATA-TD-REQ-NONCE(107), -- INTEGER
|
||||
KRB5-PADATA-TD-REQ-SEQ(108), -- INTEGER
|
||||
KRB5-PADATA-PA-PAC-REQUEST(128), -- jbrezak@exchange.microsoft.com
|
||||
KRB5-PADATA-PK-AS-09-BINDING(132), -- client send this to
|
||||
-- tell KDC that is supports
|
||||
-- the asCheckSum in the
|
||||
-- PK-AS-REP
|
||||
KRB5-PADATA-S4U2SELF(-17)
|
||||
}
|
||||
|
||||
AUTHDATA-TYPE ::= INTEGER {
|
||||
KRB5-AUTHDATA-IF-RELEVANT(1),
|
||||
KRB5-AUTHDATA-INTENDED-FOR_SERVER(2),
|
||||
KRB5-AUTHDATA-INTENDED-FOR-APPLICATION-CLASS(3),
|
||||
KRB5-AUTHDATA-KDC-ISSUED(4),
|
||||
KRB5-AUTHDATA-AND-OR(5),
|
||||
KRB5-AUTHDATA-MANDATORY-TICKET-EXTENSIONS(6),
|
||||
KRB5-AUTHDATA-IN-TICKET-EXTENSIONS(7),
|
||||
KRB5-AUTHDATA-MANDATORY-FOR-KDC(8),
|
||||
KRB5-AUTHDATA-OSF-DCE(64),
|
||||
KRB5-AUTHDATA-SESAME(65),
|
||||
KRB5-AUTHDATA-OSF-DCE-PKI-CERTID(66),
|
||||
KRB5-AUTHDATA-WIN2K-PAC(128),
|
||||
KRB5-AUTHDATA-GSS-API-ETYPE-NEGOTIATION(129), -- Authenticator only
|
||||
KRB5-AUTHDATA-SIGNTICKET(-17)
|
||||
}
|
||||
|
||||
-- checksumtypes
|
||||
|
||||
CKSUMTYPE ::= INTEGER {
|
||||
CKSUMTYPE_NONE(0),
|
||||
CKSUMTYPE_CRC32(1),
|
||||
CKSUMTYPE_RSA_MD4(2),
|
||||
CKSUMTYPE_RSA_MD4_DES(3),
|
||||
CKSUMTYPE_DES_MAC(4),
|
||||
CKSUMTYPE_DES_MAC_K(5),
|
||||
CKSUMTYPE_RSA_MD4_DES_K(6),
|
||||
CKSUMTYPE_RSA_MD5(7),
|
||||
CKSUMTYPE_RSA_MD5_DES(8),
|
||||
CKSUMTYPE_RSA_MD5_DES3(9),
|
||||
CKSUMTYPE_SHA1_OTHER(10),
|
||||
CKSUMTYPE_HMAC_SHA1_DES3(12),
|
||||
CKSUMTYPE_SHA1(14),
|
||||
CKSUMTYPE_HMAC_SHA1_96_AES_128(15),
|
||||
CKSUMTYPE_HMAC_SHA1_96_AES_256(16),
|
||||
CKSUMTYPE_GSSAPI(0x8003),
|
||||
CKSUMTYPE_HMAC_MD5(-138), -- unofficial microsoft number
|
||||
CKSUMTYPE_HMAC_MD5_ENC(-1138) -- even more unofficial
|
||||
}
|
||||
|
||||
--enctypes
|
||||
ENCTYPE ::= INTEGER {
|
||||
ETYPE_NULL(0),
|
||||
ETYPE_DES_CBC_CRC(1),
|
||||
ETYPE_DES_CBC_MD4(2),
|
||||
ETYPE_DES_CBC_MD5(3),
|
||||
ETYPE_DES3_CBC_MD5(5),
|
||||
ETYPE_OLD_DES3_CBC_SHA1(7),
|
||||
ETYPE_SIGN_DSA_GENERATE(8),
|
||||
ETYPE_ENCRYPT_RSA_PRIV(9),
|
||||
ETYPE_ENCRYPT_RSA_PUB(10),
|
||||
ETYPE_DES3_CBC_SHA1(16), -- with key derivation
|
||||
ETYPE_AES128_CTS_HMAC_SHA1_96(17),
|
||||
ETYPE_AES256_CTS_HMAC_SHA1_96(18),
|
||||
ETYPE_ARCFOUR_HMAC_MD5(23),
|
||||
ETYPE_ARCFOUR_HMAC_MD5_56(24),
|
||||
ETYPE_ENCTYPE_PK_CROSS(48),
|
||||
-- these are for Heimdal internal use
|
||||
ETYPE_DES_CBC_NONE(-0x1000),
|
||||
ETYPE_DES3_CBC_NONE(-0x1001),
|
||||
ETYPE_DES_CFB64_NONE(-0x1002),
|
||||
ETYPE_DES_PCBC_NONE(-0x1003),
|
||||
ETYPE_DIGEST_MD5_NONE(-0x1004), -- private use, lukeh@padl.com
|
||||
ETYPE_CRAM_MD5_NONE(-0x1005) -- private use, lukeh@padl.com
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-- this is sugar to make something ASN1 does not have: unsigned
|
||||
|
||||
krb5uint32 ::= INTEGER (0..4294967295)
|
||||
krb5int32 ::= INTEGER (-2147483648..2147483647)
|
||||
|
||||
KerberosString ::= GeneralString
|
||||
|
||||
Realm ::= GeneralString
|
||||
PrincipalName ::= SEQUENCE {
|
||||
name-type[0] NAME-TYPE,
|
||||
name-string[1] SEQUENCE OF GeneralString
|
||||
}
|
||||
|
||||
-- this is not part of RFC1510
|
||||
Principal ::= SEQUENCE {
|
||||
name[0] PrincipalName,
|
||||
realm[1] Realm
|
||||
}
|
||||
|
||||
HostAddress ::= SEQUENCE {
|
||||
addr-type[0] krb5int32,
|
||||
address[1] OCTET STRING
|
||||
}
|
||||
|
||||
-- This is from RFC1510.
|
||||
--
|
||||
-- HostAddresses ::= SEQUENCE OF SEQUENCE {
|
||||
-- addr-type[0] krb5int32,
|
||||
-- address[1] OCTET STRING
|
||||
-- }
|
||||
|
||||
-- This seems much better.
|
||||
HostAddresses ::= SEQUENCE OF HostAddress
|
||||
|
||||
|
||||
KerberosTime ::= GeneralizedTime -- Specifying UTC time zone (Z)
|
||||
|
||||
AuthorizationDataElement ::= SEQUENCE {
|
||||
ad-type[0] krb5int32,
|
||||
ad-data[1] OCTET STRING
|
||||
}
|
||||
|
||||
AuthorizationData ::= SEQUENCE OF AuthorizationDataElement
|
||||
|
||||
APOptions ::= BIT STRING {
|
||||
reserved(0),
|
||||
use-session-key(1),
|
||||
mutual-required(2)
|
||||
}
|
||||
|
||||
TicketFlags ::= BIT STRING {
|
||||
reserved(0),
|
||||
forwardable(1),
|
||||
forwarded(2),
|
||||
proxiable(3),
|
||||
proxy(4),
|
||||
may-postdate(5),
|
||||
postdated(6),
|
||||
invalid(7),
|
||||
renewable(8),
|
||||
initial(9),
|
||||
pre-authent(10),
|
||||
hw-authent(11),
|
||||
transited-policy-checked(12),
|
||||
ok-as-delegate(13),
|
||||
anonymous(14)
|
||||
}
|
||||
|
||||
KDCOptions ::= BIT STRING {
|
||||
reserved(0),
|
||||
forwardable(1),
|
||||
forwarded(2),
|
||||
proxiable(3),
|
||||
proxy(4),
|
||||
allow-postdate(5),
|
||||
postdated(6),
|
||||
unused7(7),
|
||||
renewable(8),
|
||||
unused9(9),
|
||||
unused10(10),
|
||||
unused11(11),
|
||||
request-anonymous(14),
|
||||
canonicalize(15),
|
||||
disable-transited-check(26),
|
||||
renewable-ok(27),
|
||||
enc-tkt-in-skey(28),
|
||||
renew(30),
|
||||
validate(31)
|
||||
}
|
||||
|
||||
LR-TYPE ::= INTEGER {
|
||||
LR_NONE(0), -- no information
|
||||
LR_INITIAL_TGT(1), -- last initial TGT request
|
||||
LR_INITIAL(2), -- last initial request
|
||||
LR_ISSUE_USE_TGT(3), -- time of newest TGT used
|
||||
LR_RENEWAL(4), -- time of last renewal
|
||||
LR_REQUEST(5), -- time of last request (of any type)
|
||||
LR_PW_EXPTIME(6), -- expiration time of password
|
||||
LR_ACCT_EXPTIME(7) -- expiration time of account
|
||||
}
|
||||
|
||||
LastReq ::= SEQUENCE OF SEQUENCE {
|
||||
lr-type[0] LR-TYPE,
|
||||
lr-value[1] KerberosTime
|
||||
}
|
||||
|
||||
|
||||
EncryptedData ::= SEQUENCE {
|
||||
etype[0] ENCTYPE, -- EncryptionType
|
||||
kvno[1] krb5int32 OPTIONAL,
|
||||
cipher[2] OCTET STRING -- ciphertext
|
||||
}
|
||||
|
||||
EncryptionKey ::= SEQUENCE {
|
||||
keytype[0] krb5int32,
|
||||
keyvalue[1] OCTET STRING
|
||||
}
|
||||
|
||||
-- encoded Transited field
|
||||
TransitedEncoding ::= SEQUENCE {
|
||||
tr-type[0] krb5int32, -- must be registered
|
||||
contents[1] OCTET STRING
|
||||
}
|
||||
|
||||
Ticket ::= [APPLICATION 1] SEQUENCE {
|
||||
tkt-vno[0] krb5int32,
|
||||
realm[1] Realm,
|
||||
sname[2] PrincipalName,
|
||||
enc-part[3] EncryptedData
|
||||
}
|
||||
-- Encrypted part of ticket
|
||||
EncTicketPart ::= [APPLICATION 3] SEQUENCE {
|
||||
flags[0] TicketFlags,
|
||||
key[1] EncryptionKey,
|
||||
crealm[2] Realm,
|
||||
cname[3] PrincipalName,
|
||||
transited[4] TransitedEncoding,
|
||||
authtime[5] KerberosTime,
|
||||
starttime[6] KerberosTime OPTIONAL,
|
||||
endtime[7] KerberosTime,
|
||||
renew-till[8] KerberosTime OPTIONAL,
|
||||
caddr[9] HostAddresses OPTIONAL,
|
||||
authorization-data[10] AuthorizationData OPTIONAL
|
||||
}
|
||||
|
||||
Checksum ::= SEQUENCE {
|
||||
cksumtype[0] CKSUMTYPE,
|
||||
checksum[1] OCTET STRING
|
||||
}
|
||||
|
||||
Authenticator ::= [APPLICATION 2] SEQUENCE {
|
||||
authenticator-vno[0] krb5int32,
|
||||
crealm[1] Realm,
|
||||
cname[2] PrincipalName,
|
||||
cksum[3] Checksum OPTIONAL,
|
||||
cusec[4] krb5int32,
|
||||
ctime[5] KerberosTime,
|
||||
subkey[6] EncryptionKey OPTIONAL,
|
||||
seq-number[7] krb5uint32 OPTIONAL,
|
||||
authorization-data[8] AuthorizationData OPTIONAL
|
||||
}
|
||||
|
||||
PA-DATA ::= SEQUENCE {
|
||||
-- might be encoded AP-REQ
|
||||
padata-type[1] PADATA-TYPE,
|
||||
padata-value[2] OCTET STRING
|
||||
}
|
||||
|
||||
ETYPE-INFO-ENTRY ::= SEQUENCE {
|
||||
etype[0] ENCTYPE,
|
||||
salt[1] OCTET STRING OPTIONAL,
|
||||
salttype[2] krb5int32 OPTIONAL
|
||||
}
|
||||
|
||||
ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY
|
||||
|
||||
ETYPE-INFO2-ENTRY ::= SEQUENCE {
|
||||
etype[0] ENCTYPE,
|
||||
salt[1] KerberosString OPTIONAL,
|
||||
s2kparams[2] OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
ETYPE-INFO2 ::= SEQUENCE OF ETYPE-INFO2-ENTRY
|
||||
|
||||
METHOD-DATA ::= SEQUENCE OF PA-DATA
|
||||
|
||||
TypedData ::= SEQUENCE {
|
||||
data-type[0] krb5int32,
|
||||
data-value[1] OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
TYPED-DATA ::= SEQUENCE OF TypedData
|
||||
|
||||
KDC-REQ-BODY ::= SEQUENCE {
|
||||
kdc-options[0] KDCOptions,
|
||||
cname[1] PrincipalName OPTIONAL, -- Used only in AS-REQ
|
||||
realm[2] Realm, -- Server's realm
|
||||
-- Also client's in AS-REQ
|
||||
sname[3] PrincipalName OPTIONAL,
|
||||
from[4] KerberosTime OPTIONAL,
|
||||
till[5] KerberosTime OPTIONAL,
|
||||
rtime[6] KerberosTime OPTIONAL,
|
||||
nonce[7] krb5int32,
|
||||
etype[8] SEQUENCE OF ENCTYPE, -- EncryptionType,
|
||||
-- in preference order
|
||||
addresses[9] HostAddresses OPTIONAL,
|
||||
enc-authorization-data[10] EncryptedData OPTIONAL,
|
||||
-- Encrypted AuthorizationData encoding
|
||||
additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
|
||||
}
|
||||
|
||||
KDC-REQ ::= SEQUENCE {
|
||||
pvno[1] krb5int32,
|
||||
msg-type[2] MESSAGE-TYPE,
|
||||
padata[3] METHOD-DATA OPTIONAL,
|
||||
req-body[4] KDC-REQ-BODY
|
||||
}
|
||||
|
||||
AS-REQ ::= [APPLICATION 10] KDC-REQ
|
||||
TGS-REQ ::= [APPLICATION 12] KDC-REQ
|
||||
|
||||
-- padata-type ::= PA-ENC-TIMESTAMP
|
||||
-- padata-value ::= EncryptedData - PA-ENC-TS-ENC
|
||||
|
||||
PA-ENC-TS-ENC ::= SEQUENCE {
|
||||
patimestamp[0] KerberosTime, -- client's time
|
||||
pausec[1] krb5int32 OPTIONAL
|
||||
}
|
||||
|
||||
-- draft-brezak-win2k-krb-authz-01
|
||||
PA-PAC-REQUEST ::= SEQUENCE {
|
||||
include-pac[0] BOOLEAN -- Indicates whether a PAC
|
||||
-- should be included or not
|
||||
}
|
||||
|
||||
-- PacketCable provisioning server location, PKT-SP-SEC-I09-030728.pdf
|
||||
PROV-SRV-LOCATION ::= GeneralString
|
||||
|
||||
KDC-REP ::= SEQUENCE {
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
padata[2] METHOD-DATA OPTIONAL,
|
||||
crealm[3] Realm,
|
||||
cname[4] PrincipalName,
|
||||
ticket[5] Ticket,
|
||||
enc-part[6] EncryptedData
|
||||
}
|
||||
|
||||
AS-REP ::= [APPLICATION 11] KDC-REP
|
||||
TGS-REP ::= [APPLICATION 13] KDC-REP
|
||||
|
||||
EncKDCRepPart ::= SEQUENCE {
|
||||
key[0] EncryptionKey,
|
||||
last-req[1] LastReq,
|
||||
nonce[2] krb5int32,
|
||||
key-expiration[3] KerberosTime OPTIONAL,
|
||||
flags[4] TicketFlags,
|
||||
authtime[5] KerberosTime,
|
||||
starttime[6] KerberosTime OPTIONAL,
|
||||
endtime[7] KerberosTime,
|
||||
renew-till[8] KerberosTime OPTIONAL,
|
||||
srealm[9] Realm,
|
||||
sname[10] PrincipalName,
|
||||
caddr[11] HostAddresses OPTIONAL
|
||||
}
|
||||
|
||||
EncASRepPart ::= [APPLICATION 25] EncKDCRepPart
|
||||
EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
|
||||
|
||||
AP-REQ ::= [APPLICATION 14] SEQUENCE {
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
ap-options[2] APOptions,
|
||||
ticket[3] Ticket,
|
||||
authenticator[4] EncryptedData
|
||||
}
|
||||
|
||||
AP-REP ::= [APPLICATION 15] SEQUENCE {
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
enc-part[2] EncryptedData
|
||||
}
|
||||
|
||||
EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
|
||||
ctime[0] KerberosTime,
|
||||
cusec[1] krb5int32,
|
||||
subkey[2] EncryptionKey OPTIONAL,
|
||||
seq-number[3] krb5uint32 OPTIONAL
|
||||
}
|
||||
|
||||
KRB-SAFE-BODY ::= SEQUENCE {
|
||||
user-data[0] OCTET STRING,
|
||||
timestamp[1] KerberosTime OPTIONAL,
|
||||
usec[2] krb5int32 OPTIONAL,
|
||||
seq-number[3] krb5uint32 OPTIONAL,
|
||||
s-address[4] HostAddress OPTIONAL,
|
||||
r-address[5] HostAddress OPTIONAL
|
||||
}
|
||||
|
||||
KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
safe-body[2] KRB-SAFE-BODY,
|
||||
cksum[3] Checksum
|
||||
}
|
||||
|
||||
KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
enc-part[3] EncryptedData
|
||||
}
|
||||
EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
|
||||
user-data[0] OCTET STRING,
|
||||
timestamp[1] KerberosTime OPTIONAL,
|
||||
usec[2] krb5int32 OPTIONAL,
|
||||
seq-number[3] krb5uint32 OPTIONAL,
|
||||
s-address[4] HostAddress OPTIONAL, -- sender's addr
|
||||
r-address[5] HostAddress OPTIONAL -- recip's addr
|
||||
}
|
||||
|
||||
KRB-CRED ::= [APPLICATION 22] SEQUENCE {
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE, -- KRB_CRED
|
||||
tickets[2] SEQUENCE OF Ticket,
|
||||
enc-part[3] EncryptedData
|
||||
}
|
||||
|
||||
KrbCredInfo ::= SEQUENCE {
|
||||
key[0] EncryptionKey,
|
||||
prealm[1] Realm OPTIONAL,
|
||||
pname[2] PrincipalName OPTIONAL,
|
||||
flags[3] TicketFlags OPTIONAL,
|
||||
authtime[4] KerberosTime OPTIONAL,
|
||||
starttime[5] KerberosTime OPTIONAL,
|
||||
endtime[6] KerberosTime OPTIONAL,
|
||||
renew-till[7] KerberosTime OPTIONAL,
|
||||
srealm[8] Realm OPTIONAL,
|
||||
sname[9] PrincipalName OPTIONAL,
|
||||
caddr[10] HostAddresses OPTIONAL
|
||||
}
|
||||
|
||||
EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
|
||||
ticket-info[0] SEQUENCE OF KrbCredInfo,
|
||||
nonce[1] krb5int32 OPTIONAL,
|
||||
timestamp[2] KerberosTime OPTIONAL,
|
||||
usec[3] krb5int32 OPTIONAL,
|
||||
s-address[4] HostAddress OPTIONAL,
|
||||
r-address[5] HostAddress OPTIONAL
|
||||
}
|
||||
|
||||
KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
|
||||
pvno[0] krb5int32,
|
||||
msg-type[1] MESSAGE-TYPE,
|
||||
ctime[2] KerberosTime OPTIONAL,
|
||||
cusec[3] krb5int32 OPTIONAL,
|
||||
stime[4] KerberosTime,
|
||||
susec[5] krb5int32,
|
||||
error-code[6] krb5int32,
|
||||
crealm[7] Realm OPTIONAL,
|
||||
cname[8] PrincipalName OPTIONAL,
|
||||
realm[9] Realm, -- Correct realm
|
||||
sname[10] PrincipalName, -- Correct name
|
||||
e-text[11] GeneralString OPTIONAL,
|
||||
e-data[12] OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
ChangePasswdDataMS ::= SEQUENCE {
|
||||
newpasswd[0] OCTET STRING,
|
||||
targname[1] PrincipalName OPTIONAL,
|
||||
targrealm[2] Realm OPTIONAL
|
||||
}
|
||||
|
||||
EtypeList ::= SEQUENCE OF krb5int32
|
||||
-- the client's proposed enctype list in
|
||||
-- decreasing preference order, favorite choice first
|
||||
|
||||
krb5-pvno krb5int32 ::= 5 -- current Kerberos protocol version number
|
||||
|
||||
-- transited encodings
|
||||
|
||||
DOMAIN-X500-COMPRESS krb5int32 ::= 1
|
||||
|
||||
-- authorization data primitives
|
||||
|
||||
AD-IF-RELEVANT ::= AuthorizationData
|
||||
|
||||
AD-KDCIssued ::= SEQUENCE {
|
||||
ad-checksum[0] Checksum,
|
||||
i-realm[1] Realm OPTIONAL,
|
||||
i-sname[2] PrincipalName OPTIONAL,
|
||||
elements[3] AuthorizationData
|
||||
}
|
||||
|
||||
AD-AND-OR ::= SEQUENCE {
|
||||
condition-count[0] INTEGER,
|
||||
elements[1] AuthorizationData
|
||||
}
|
||||
|
||||
AD-MANDATORY-FOR-KDC ::= AuthorizationData
|
||||
|
||||
-- PA-SAM-RESPONSE-2/PA-SAM-RESPONSE-2
|
||||
|
||||
PA-SAM-TYPE ::= INTEGER {
|
||||
PA_SAM_TYPE_ENIGMA(1), -- Enigma Logic
|
||||
PA_SAM_TYPE_DIGI_PATH(2), -- Digital Pathways
|
||||
PA_SAM_TYPE_SKEY_K0(3), -- S/key where KDC has key 0
|
||||
PA_SAM_TYPE_SKEY(4), -- Traditional S/Key
|
||||
PA_SAM_TYPE_SECURID(5), -- Security Dynamics
|
||||
PA_SAM_TYPE_CRYPTOCARD(6) -- CRYPTOCard
|
||||
}
|
||||
|
||||
PA-SAM-REDIRECT ::= HostAddresses
|
||||
|
||||
SAMFlags ::= BIT STRING {
|
||||
use-sad-as-key(0),
|
||||
send-encrypted-sad(1),
|
||||
must-pk-encrypt-sad(2)
|
||||
}
|
||||
|
||||
PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE {
|
||||
sam-type[0] krb5int32,
|
||||
sam-flags[1] SAMFlags,
|
||||
sam-type-name[2] GeneralString OPTIONAL,
|
||||
sam-track-id[3] GeneralString OPTIONAL,
|
||||
sam-challenge-label[4] GeneralString OPTIONAL,
|
||||
sam-challenge[5] GeneralString OPTIONAL,
|
||||
sam-response-prompt[6] GeneralString OPTIONAL,
|
||||
sam-pk-for-sad[7] EncryptionKey OPTIONAL,
|
||||
sam-nonce[8] krb5int32,
|
||||
sam-etype[9] krb5int32,
|
||||
...
|
||||
}
|
||||
|
||||
PA-SAM-CHALLENGE-2 ::= SEQUENCE {
|
||||
sam-body[0] PA-SAM-CHALLENGE-2-BODY,
|
||||
sam-cksum[1] SEQUENCE OF Checksum, -- (1..MAX)
|
||||
...
|
||||
}
|
||||
|
||||
PA-SAM-RESPONSE-2 ::= SEQUENCE {
|
||||
sam-type[0] krb5int32,
|
||||
sam-flags[1] SAMFlags,
|
||||
sam-track-id[2] GeneralString OPTIONAL,
|
||||
sam-enc-nonce-or-sad[3] EncryptedData, -- PA-ENC-SAM-RESPONSE-ENC
|
||||
sam-nonce[4] krb5int32,
|
||||
...
|
||||
}
|
||||
|
||||
PA-ENC-SAM-RESPONSE-ENC ::= SEQUENCE {
|
||||
sam-nonce[0] krb5int32,
|
||||
sam-sad[1] GeneralString OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
PA-S4U2Self ::= SEQUENCE {
|
||||
name[0] PrincipalName,
|
||||
realm[1] Realm,
|
||||
cksum[2] Checksum,
|
||||
auth[3] GeneralString
|
||||
}
|
||||
|
||||
KRB5SignedPathPrincipals ::= SEQUENCE OF Principal
|
||||
|
||||
-- never encoded on the wire, just used to checksum over
|
||||
KRB5SignedPathData ::= SEQUENCE {
|
||||
encticket[0] EncTicketPart,
|
||||
delegated[1] KRB5SignedPathPrincipals OPTIONAL
|
||||
}
|
||||
|
||||
KRB5SignedPath ::= SEQUENCE {
|
||||
-- DERcoded KRB5SignedPathData
|
||||
-- krbtgt key (etype), KeyUsage = XXX
|
||||
etype[0] ENCTYPE,
|
||||
cksum[1] Checksum,
|
||||
-- srvs delegated though
|
||||
delegated[2] KRB5SignedPathPrincipals OPTIONAL
|
||||
}
|
||||
|
||||
END
|
||||
|
||||
-- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2000 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: lex.h,v 1.6 2005/07/12 06:27:33 lha Exp $ */
|
||||
|
||||
#include <roken.h>
|
||||
|
||||
void error_message (const char *, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
extern int error_flag;
|
||||
|
||||
int yylex(void);
|
||||
@@ -0,0 +1,294 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id: lex.l,v 1.27 2005/09/13 18:17:16 lha Exp $ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#undef ECHO
|
||||
#include "symbol.h"
|
||||
#include "parse.h"
|
||||
#include "lex.h"
|
||||
#include "gen_locl.h"
|
||||
|
||||
static unsigned lineno = 1;
|
||||
|
||||
#undef ECHO
|
||||
|
||||
static void unterminated(const char *, unsigned);
|
||||
|
||||
%}
|
||||
|
||||
|
||||
%%
|
||||
ABSENT { return kw_ABSENT; }
|
||||
ABSTRACT-SYNTAX { return kw_ABSTRACT_SYNTAX; }
|
||||
ALL { return kw_ALL; }
|
||||
APPLICATION { return kw_APPLICATION; }
|
||||
AUTOMATIC { return kw_AUTOMATIC; }
|
||||
BEGIN { return kw_BEGIN; }
|
||||
BIT { return kw_BIT; }
|
||||
BMPString { return kw_BMPString; }
|
||||
BOOLEAN { return kw_BOOLEAN; }
|
||||
BY { return kw_BY; }
|
||||
CHARACTER { return kw_CHARACTER; }
|
||||
CHOICE { return kw_CHOICE; }
|
||||
CLASS { return kw_CLASS; }
|
||||
COMPONENT { return kw_COMPONENT; }
|
||||
COMPONENTS { return kw_COMPONENTS; }
|
||||
CONSTRAINED { return kw_CONSTRAINED; }
|
||||
CONTAINING { return kw_CONTAINING; }
|
||||
DEFAULT { return kw_DEFAULT; }
|
||||
DEFINITIONS { return kw_DEFINITIONS; }
|
||||
EMBEDDED { return kw_EMBEDDED; }
|
||||
ENCODED { return kw_ENCODED; }
|
||||
END { return kw_END; }
|
||||
ENUMERATED { return kw_ENUMERATED; }
|
||||
EXCEPT { return kw_EXCEPT; }
|
||||
EXPLICIT { return kw_EXPLICIT; }
|
||||
EXPORTS { return kw_EXPORTS; }
|
||||
EXTENSIBILITY { return kw_EXTENSIBILITY; }
|
||||
EXTERNAL { return kw_EXTERNAL; }
|
||||
FALSE { return kw_FALSE; }
|
||||
FROM { return kw_FROM; }
|
||||
GeneralString { return kw_GeneralString; }
|
||||
GeneralizedTime { return kw_GeneralizedTime; }
|
||||
GraphicString { return kw_GraphicString; }
|
||||
IA5String { return kw_IA5String; }
|
||||
IDENTIFIER { return kw_IDENTIFIER; }
|
||||
IMPLICIT { return kw_IMPLICIT; }
|
||||
IMPLIED { return kw_IMPLIED; }
|
||||
IMPORTS { return kw_IMPORTS; }
|
||||
INCLUDES { return kw_INCLUDES; }
|
||||
INSTANCE { return kw_INSTANCE; }
|
||||
INTEGER { return kw_INTEGER; }
|
||||
INTERSECTION { return kw_INTERSECTION; }
|
||||
ISO646String { return kw_ISO646String; }
|
||||
MAX { return kw_MAX; }
|
||||
MIN { return kw_MIN; }
|
||||
MINUS-INFINITY { return kw_MINUS_INFINITY; }
|
||||
NULL { return kw_NULL; }
|
||||
NumericString { return kw_NumericString; }
|
||||
OBJECT { return kw_OBJECT; }
|
||||
OCTET { return kw_OCTET; }
|
||||
OF { return kw_OF; }
|
||||
OPTIONAL { return kw_OPTIONAL; }
|
||||
ObjectDescriptor { return kw_ObjectDescriptor; }
|
||||
PATTERN { return kw_PATTERN; }
|
||||
PDV { return kw_PDV; }
|
||||
PLUS-INFINITY { return kw_PLUS_INFINITY; }
|
||||
PRESENT { return kw_PRESENT; }
|
||||
PRIVATE { return kw_PRIVATE; }
|
||||
PrintableString { return kw_PrintableString; }
|
||||
REAL { return kw_REAL; }
|
||||
RELATIVE_OID { return kw_RELATIVE_OID; }
|
||||
SEQUENCE { return kw_SEQUENCE; }
|
||||
SET { return kw_SET; }
|
||||
SIZE { return kw_SIZE; }
|
||||
STRING { return kw_STRING; }
|
||||
SYNTAX { return kw_SYNTAX; }
|
||||
T61String { return kw_T61String; }
|
||||
TAGS { return kw_TAGS; }
|
||||
TRUE { return kw_TRUE; }
|
||||
TYPE-IDENTIFIER { return kw_TYPE_IDENTIFIER; }
|
||||
TeletexString { return kw_TeletexString; }
|
||||
UNION { return kw_UNION; }
|
||||
UNIQUE { return kw_UNIQUE; }
|
||||
UNIVERSAL { return kw_UNIVERSAL; }
|
||||
UTCTime { return kw_UTCTime; }
|
||||
UTF8String { return kw_UTF8String; }
|
||||
UniversalString { return kw_UniversalString; }
|
||||
VideotexString { return kw_VideotexString; }
|
||||
VisibleString { return kw_VisibleString; }
|
||||
WITH { return kw_WITH; }
|
||||
[-,;{}()|] { return *yytext; }
|
||||
"[" { return *yytext; }
|
||||
"]" { return *yytext; }
|
||||
::= { return EEQUAL; }
|
||||
-- {
|
||||
int c, start_lineno = lineno;
|
||||
int f = 0;
|
||||
while((c = input()) != EOF) {
|
||||
if(f && c == '-')
|
||||
break;
|
||||
if(c == '-') {
|
||||
f = 1;
|
||||
continue;
|
||||
}
|
||||
if(c == '\n') {
|
||||
lineno++;
|
||||
break;
|
||||
}
|
||||
f = 0;
|
||||
}
|
||||
if(c == EOF)
|
||||
unterminated("comment", start_lineno);
|
||||
}
|
||||
\/\* {
|
||||
int c, start_lineno = lineno;
|
||||
int level = 1;
|
||||
int seen_star = 0;
|
||||
int seen_slash = 0;
|
||||
while((c = input()) != EOF) {
|
||||
if(c == '/') {
|
||||
if(seen_star) {
|
||||
if(--level == 0)
|
||||
break;
|
||||
seen_star = 0;
|
||||
continue;
|
||||
}
|
||||
seen_slash = 1;
|
||||
continue;
|
||||
}
|
||||
if(seen_star && c == '/') {
|
||||
if(--level == 0)
|
||||
break;
|
||||
seen_star = 0;
|
||||
continue;
|
||||
}
|
||||
if(c == '*') {
|
||||
if(seen_slash) {
|
||||
level++;
|
||||
seen_star = seen_slash = 0;
|
||||
continue;
|
||||
}
|
||||
seen_star = 1;
|
||||
continue;
|
||||
}
|
||||
seen_star = seen_slash = 0;
|
||||
if(c == '\n') {
|
||||
lineno++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(c == EOF)
|
||||
unterminated("comment", start_lineno);
|
||||
}
|
||||
"\"" {
|
||||
int start_lineno = lineno;
|
||||
int c;
|
||||
char buf[1024];
|
||||
char *p = buf;
|
||||
int f = 0;
|
||||
int skip_ws = 0;
|
||||
|
||||
while((c = input()) != EOF) {
|
||||
if(isspace(c) && skip_ws) {
|
||||
if(c == '\n')
|
||||
lineno++;
|
||||
continue;
|
||||
}
|
||||
skip_ws = 0;
|
||||
|
||||
if(c == '"') {
|
||||
if(f) {
|
||||
*p++ = '"';
|
||||
f = 0;
|
||||
} else
|
||||
f = 1;
|
||||
continue;
|
||||
}
|
||||
if(f == 1) {
|
||||
unput(c);
|
||||
break;
|
||||
}
|
||||
if(c == '\n') {
|
||||
lineno++;
|
||||
while(p > buf && isspace((unsigned char)p[-1]))
|
||||
p--;
|
||||
skip_ws = 1;
|
||||
continue;
|
||||
}
|
||||
*p++ = c;
|
||||
}
|
||||
if(c == EOF)
|
||||
unterminated("string", start_lineno);
|
||||
*p++ = '\0';
|
||||
fprintf(stderr, "string -- %s\n", buf);
|
||||
yylval.name = estrdup(buf);
|
||||
return STRING;
|
||||
}
|
||||
|
||||
-?0x[0-9A-Fa-f]+|-?[0-9]+ { char *e, *y = yytext;
|
||||
yylval.constant = strtol((const char *)yytext,
|
||||
&e, 0);
|
||||
if(e == y)
|
||||
error_message("malformed constant (%s)", yytext);
|
||||
else
|
||||
return NUMBER;
|
||||
}
|
||||
[A-Za-z][-A-Za-z0-9_]* {
|
||||
yylval.name = estrdup ((const char *)yytext);
|
||||
return IDENTIFIER;
|
||||
}
|
||||
[ \t] ;
|
||||
\n { ++lineno; }
|
||||
\.\.\. { return ELLIPSIS; }
|
||||
\.\. { return RANGE; }
|
||||
. { error_message("Ignoring char(%c)\n", *yytext); }
|
||||
%%
|
||||
|
||||
#ifndef yywrap /* XXX */
|
||||
int
|
||||
yywrap ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
error_message (const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
fprintf (stderr, "%s:%d: ", get_filename(), lineno);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
error_flag++;
|
||||
}
|
||||
|
||||
static void
|
||||
unterminated(const char *type, unsigned start_lineno)
|
||||
{
|
||||
error_message("unterminated %s, possibly started on line %d\n", type, start_lineno);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id: libasn1.h,v 1.11 2005/07/12 06:27:34 lha Exp $ */
|
||||
|
||||
#ifndef __LIBASN1_H__
|
||||
#define __LIBASN1_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "krb5_asn1.h"
|
||||
#include "der.h"
|
||||
#include "asn1_err.h"
|
||||
#include <parse_units.h>
|
||||
|
||||
#endif /* __LIBASN1_H__ */
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
#include <getarg.h>
|
||||
#include "lex.h"
|
||||
|
||||
RCSID("$Id: main.c,v 1.16 2006/09/05 12:27:29 lha Exp $");
|
||||
|
||||
extern FILE *yyin;
|
||||
|
||||
static getarg_strings preserve;
|
||||
static getarg_strings seq;
|
||||
|
||||
int
|
||||
preserve_type(const char *p)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < preserve.num_strings; i++)
|
||||
if (strcmp(preserve.strings[i], p) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
seq_type(const char *p)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < seq.num_strings; i++)
|
||||
if (strcmp(seq.strings[i], p) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dce_fix;
|
||||
int rfc1510_bitstring;
|
||||
int version_flag;
|
||||
int help_flag;
|
||||
struct getargs args[] = {
|
||||
{ "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring },
|
||||
{ "decode-dce-ber", 0, arg_flag, &dce_fix },
|
||||
{ "preserve-binary", 0, arg_strings, &preserve },
|
||||
{ "sequence", 0, arg_strings, &seq },
|
||||
{ "version", 0, arg_flag, &version_flag },
|
||||
{ "help", 0, arg_flag, &help_flag }
|
||||
};
|
||||
int num_args = sizeof(args) / sizeof(args[0]);
|
||||
|
||||
static void
|
||||
usage(int code)
|
||||
{
|
||||
arg_printusage(args, num_args, NULL, "[asn1-file [name]]");
|
||||
exit(code);
|
||||
}
|
||||
|
||||
int error_flag;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
const char *file;
|
||||
const char *name = NULL;
|
||||
int 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);
|
||||
}
|
||||
if (argc == optidx) {
|
||||
file = "stdin";
|
||||
name = "stdin";
|
||||
yyin = stdin;
|
||||
} else {
|
||||
file = argv[optidx];
|
||||
yyin = fopen (file, "r");
|
||||
if (yyin == NULL)
|
||||
err (1, "open %s", file);
|
||||
if (argc == optidx + 1) {
|
||||
char *p;
|
||||
name = estrdup(file);
|
||||
p = strrchr(name, '.');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
} else
|
||||
name = argv[optidx + 1];
|
||||
}
|
||||
|
||||
init_generate (file, name);
|
||||
initsym ();
|
||||
ret = yyparse ();
|
||||
if(ret != 0 || error_flag != 0)
|
||||
exit(1);
|
||||
close_generate ();
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,239 @@
|
||||
/* A Bison parser, made by GNU Bison 2.1. */
|
||||
|
||||
/* Skeleton parser for Yacc-like parsing with Bison,
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, when this file is copied by Bison into a
|
||||
Bison output file, you may use that output file without restriction.
|
||||
This special exception was added by the Free Software Foundation
|
||||
in version 1.24 of Bison. */
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
kw_ABSENT = 258,
|
||||
kw_ABSTRACT_SYNTAX = 259,
|
||||
kw_ALL = 260,
|
||||
kw_APPLICATION = 261,
|
||||
kw_AUTOMATIC = 262,
|
||||
kw_BEGIN = 263,
|
||||
kw_BIT = 264,
|
||||
kw_BMPString = 265,
|
||||
kw_BOOLEAN = 266,
|
||||
kw_BY = 267,
|
||||
kw_CHARACTER = 268,
|
||||
kw_CHOICE = 269,
|
||||
kw_CLASS = 270,
|
||||
kw_COMPONENT = 271,
|
||||
kw_COMPONENTS = 272,
|
||||
kw_CONSTRAINED = 273,
|
||||
kw_CONTAINING = 274,
|
||||
kw_DEFAULT = 275,
|
||||
kw_DEFINITIONS = 276,
|
||||
kw_EMBEDDED = 277,
|
||||
kw_ENCODED = 278,
|
||||
kw_END = 279,
|
||||
kw_ENUMERATED = 280,
|
||||
kw_EXCEPT = 281,
|
||||
kw_EXPLICIT = 282,
|
||||
kw_EXPORTS = 283,
|
||||
kw_EXTENSIBILITY = 284,
|
||||
kw_EXTERNAL = 285,
|
||||
kw_FALSE = 286,
|
||||
kw_FROM = 287,
|
||||
kw_GeneralString = 288,
|
||||
kw_GeneralizedTime = 289,
|
||||
kw_GraphicString = 290,
|
||||
kw_IA5String = 291,
|
||||
kw_IDENTIFIER = 292,
|
||||
kw_IMPLICIT = 293,
|
||||
kw_IMPLIED = 294,
|
||||
kw_IMPORTS = 295,
|
||||
kw_INCLUDES = 296,
|
||||
kw_INSTANCE = 297,
|
||||
kw_INTEGER = 298,
|
||||
kw_INTERSECTION = 299,
|
||||
kw_ISO646String = 300,
|
||||
kw_MAX = 301,
|
||||
kw_MIN = 302,
|
||||
kw_MINUS_INFINITY = 303,
|
||||
kw_NULL = 304,
|
||||
kw_NumericString = 305,
|
||||
kw_OBJECT = 306,
|
||||
kw_OCTET = 307,
|
||||
kw_OF = 308,
|
||||
kw_OPTIONAL = 309,
|
||||
kw_ObjectDescriptor = 310,
|
||||
kw_PATTERN = 311,
|
||||
kw_PDV = 312,
|
||||
kw_PLUS_INFINITY = 313,
|
||||
kw_PRESENT = 314,
|
||||
kw_PRIVATE = 315,
|
||||
kw_PrintableString = 316,
|
||||
kw_REAL = 317,
|
||||
kw_RELATIVE_OID = 318,
|
||||
kw_SEQUENCE = 319,
|
||||
kw_SET = 320,
|
||||
kw_SIZE = 321,
|
||||
kw_STRING = 322,
|
||||
kw_SYNTAX = 323,
|
||||
kw_T61String = 324,
|
||||
kw_TAGS = 325,
|
||||
kw_TRUE = 326,
|
||||
kw_TYPE_IDENTIFIER = 327,
|
||||
kw_TeletexString = 328,
|
||||
kw_UNION = 329,
|
||||
kw_UNIQUE = 330,
|
||||
kw_UNIVERSAL = 331,
|
||||
kw_UTCTime = 332,
|
||||
kw_UTF8String = 333,
|
||||
kw_UniversalString = 334,
|
||||
kw_VideotexString = 335,
|
||||
kw_VisibleString = 336,
|
||||
kw_WITH = 337,
|
||||
RANGE = 338,
|
||||
EEQUAL = 339,
|
||||
ELLIPSIS = 340,
|
||||
IDENTIFIER = 341,
|
||||
referencename = 342,
|
||||
STRING = 343,
|
||||
NUMBER = 344
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define kw_ABSENT 258
|
||||
#define kw_ABSTRACT_SYNTAX 259
|
||||
#define kw_ALL 260
|
||||
#define kw_APPLICATION 261
|
||||
#define kw_AUTOMATIC 262
|
||||
#define kw_BEGIN 263
|
||||
#define kw_BIT 264
|
||||
#define kw_BMPString 265
|
||||
#define kw_BOOLEAN 266
|
||||
#define kw_BY 267
|
||||
#define kw_CHARACTER 268
|
||||
#define kw_CHOICE 269
|
||||
#define kw_CLASS 270
|
||||
#define kw_COMPONENT 271
|
||||
#define kw_COMPONENTS 272
|
||||
#define kw_CONSTRAINED 273
|
||||
#define kw_CONTAINING 274
|
||||
#define kw_DEFAULT 275
|
||||
#define kw_DEFINITIONS 276
|
||||
#define kw_EMBEDDED 277
|
||||
#define kw_ENCODED 278
|
||||
#define kw_END 279
|
||||
#define kw_ENUMERATED 280
|
||||
#define kw_EXCEPT 281
|
||||
#define kw_EXPLICIT 282
|
||||
#define kw_EXPORTS 283
|
||||
#define kw_EXTENSIBILITY 284
|
||||
#define kw_EXTERNAL 285
|
||||
#define kw_FALSE 286
|
||||
#define kw_FROM 287
|
||||
#define kw_GeneralString 288
|
||||
#define kw_GeneralizedTime 289
|
||||
#define kw_GraphicString 290
|
||||
#define kw_IA5String 291
|
||||
#define kw_IDENTIFIER 292
|
||||
#define kw_IMPLICIT 293
|
||||
#define kw_IMPLIED 294
|
||||
#define kw_IMPORTS 295
|
||||
#define kw_INCLUDES 296
|
||||
#define kw_INSTANCE 297
|
||||
#define kw_INTEGER 298
|
||||
#define kw_INTERSECTION 299
|
||||
#define kw_ISO646String 300
|
||||
#define kw_MAX 301
|
||||
#define kw_MIN 302
|
||||
#define kw_MINUS_INFINITY 303
|
||||
#define kw_NULL 304
|
||||
#define kw_NumericString 305
|
||||
#define kw_OBJECT 306
|
||||
#define kw_OCTET 307
|
||||
#define kw_OF 308
|
||||
#define kw_OPTIONAL 309
|
||||
#define kw_ObjectDescriptor 310
|
||||
#define kw_PATTERN 311
|
||||
#define kw_PDV 312
|
||||
#define kw_PLUS_INFINITY 313
|
||||
#define kw_PRESENT 314
|
||||
#define kw_PRIVATE 315
|
||||
#define kw_PrintableString 316
|
||||
#define kw_REAL 317
|
||||
#define kw_RELATIVE_OID 318
|
||||
#define kw_SEQUENCE 319
|
||||
#define kw_SET 320
|
||||
#define kw_SIZE 321
|
||||
#define kw_STRING 322
|
||||
#define kw_SYNTAX 323
|
||||
#define kw_T61String 324
|
||||
#define kw_TAGS 325
|
||||
#define kw_TRUE 326
|
||||
#define kw_TYPE_IDENTIFIER 327
|
||||
#define kw_TeletexString 328
|
||||
#define kw_UNION 329
|
||||
#define kw_UNIQUE 330
|
||||
#define kw_UNIVERSAL 331
|
||||
#define kw_UTCTime 332
|
||||
#define kw_UTF8String 333
|
||||
#define kw_UniversalString 334
|
||||
#define kw_VideotexString 335
|
||||
#define kw_VisibleString 336
|
||||
#define kw_WITH 337
|
||||
#define RANGE 338
|
||||
#define EEQUAL 339
|
||||
#define ELLIPSIS 340
|
||||
#define IDENTIFIER 341
|
||||
#define referencename 342
|
||||
#define STRING 343
|
||||
#define NUMBER 344
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
||||
#line 65 "parse.y"
|
||||
typedef union YYSTYPE {
|
||||
int constant;
|
||||
struct value *value;
|
||||
struct range range;
|
||||
char *name;
|
||||
Type *type;
|
||||
Member *member;
|
||||
struct objid *objid;
|
||||
char *defval;
|
||||
struct string_list *sl;
|
||||
struct tagtype tag;
|
||||
struct memhead *members;
|
||||
struct constraint_spec *constraint_spec;
|
||||
} YYSTYPE;
|
||||
/* Line 1447 of yacc.c. */
|
||||
#line 231 "parse.h"
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,970 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id: parse.y,v 1.27 2005/12/14 09:44:36 lha Exp $ */
|
||||
|
||||
%{
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "symbol.h"
|
||||
#include "lex.h"
|
||||
#include "gen_locl.h"
|
||||
#include "der.h"
|
||||
|
||||
RCSID("$Id: parse.y,v 1.27 2005/12/14 09:44:36 lha Exp $");
|
||||
|
||||
static Type *new_type (Typetype t);
|
||||
static struct constraint_spec *new_constraint_spec(enum ctype);
|
||||
static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype);
|
||||
void yyerror (const char *);
|
||||
static struct objid *new_objid(const char *label, int value);
|
||||
static void add_oid_to_tail(struct objid *, struct objid *);
|
||||
static void fix_labels(Symbol *s);
|
||||
|
||||
struct string_list {
|
||||
char *string;
|
||||
struct string_list *next;
|
||||
};
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
int constant;
|
||||
struct value *value;
|
||||
struct range range;
|
||||
char *name;
|
||||
Type *type;
|
||||
Member *member;
|
||||
struct objid *objid;
|
||||
char *defval;
|
||||
struct string_list *sl;
|
||||
struct tagtype tag;
|
||||
struct memhead *members;
|
||||
struct constraint_spec *constraint_spec;
|
||||
}
|
||||
|
||||
%token kw_ABSENT
|
||||
%token kw_ABSTRACT_SYNTAX
|
||||
%token kw_ALL
|
||||
%token kw_APPLICATION
|
||||
%token kw_AUTOMATIC
|
||||
%token kw_BEGIN
|
||||
%token kw_BIT
|
||||
%token kw_BMPString
|
||||
%token kw_BOOLEAN
|
||||
%token kw_BY
|
||||
%token kw_CHARACTER
|
||||
%token kw_CHOICE
|
||||
%token kw_CLASS
|
||||
%token kw_COMPONENT
|
||||
%token kw_COMPONENTS
|
||||
%token kw_CONSTRAINED
|
||||
%token kw_CONTAINING
|
||||
%token kw_DEFAULT
|
||||
%token kw_DEFINITIONS
|
||||
%token kw_EMBEDDED
|
||||
%token kw_ENCODED
|
||||
%token kw_END
|
||||
%token kw_ENUMERATED
|
||||
%token kw_EXCEPT
|
||||
%token kw_EXPLICIT
|
||||
%token kw_EXPORTS
|
||||
%token kw_EXTENSIBILITY
|
||||
%token kw_EXTERNAL
|
||||
%token kw_FALSE
|
||||
%token kw_FROM
|
||||
%token kw_GeneralString
|
||||
%token kw_GeneralizedTime
|
||||
%token kw_GraphicString
|
||||
%token kw_IA5String
|
||||
%token kw_IDENTIFIER
|
||||
%token kw_IMPLICIT
|
||||
%token kw_IMPLIED
|
||||
%token kw_IMPORTS
|
||||
%token kw_INCLUDES
|
||||
%token kw_INSTANCE
|
||||
%token kw_INTEGER
|
||||
%token kw_INTERSECTION
|
||||
%token kw_ISO646String
|
||||
%token kw_MAX
|
||||
%token kw_MIN
|
||||
%token kw_MINUS_INFINITY
|
||||
%token kw_NULL
|
||||
%token kw_NumericString
|
||||
%token kw_OBJECT
|
||||
%token kw_OCTET
|
||||
%token kw_OF
|
||||
%token kw_OPTIONAL
|
||||
%token kw_ObjectDescriptor
|
||||
%token kw_PATTERN
|
||||
%token kw_PDV
|
||||
%token kw_PLUS_INFINITY
|
||||
%token kw_PRESENT
|
||||
%token kw_PRIVATE
|
||||
%token kw_PrintableString
|
||||
%token kw_REAL
|
||||
%token kw_RELATIVE_OID
|
||||
%token kw_SEQUENCE
|
||||
%token kw_SET
|
||||
%token kw_SIZE
|
||||
%token kw_STRING
|
||||
%token kw_SYNTAX
|
||||
%token kw_T61String
|
||||
%token kw_TAGS
|
||||
%token kw_TRUE
|
||||
%token kw_TYPE_IDENTIFIER
|
||||
%token kw_TeletexString
|
||||
%token kw_UNION
|
||||
%token kw_UNIQUE
|
||||
%token kw_UNIVERSAL
|
||||
%token kw_UTCTime
|
||||
%token kw_UTF8String
|
||||
%token kw_UniversalString
|
||||
%token kw_VideotexString
|
||||
%token kw_VisibleString
|
||||
%token kw_WITH
|
||||
|
||||
%token RANGE
|
||||
%token EEQUAL
|
||||
%token ELLIPSIS
|
||||
|
||||
%token <name> IDENTIFIER referencename
|
||||
%token <name> STRING
|
||||
|
||||
%token <constant> NUMBER
|
||||
%type <constant> SignedNumber
|
||||
%type <constant> Class tagenv
|
||||
|
||||
%type <value> Value
|
||||
%type <value> BuiltinValue
|
||||
%type <value> IntegerValue
|
||||
%type <value> BooleanValue
|
||||
%type <value> ObjectIdentifierValue
|
||||
%type <value> CharacterStringValue
|
||||
%type <value> NullValue
|
||||
%type <value> DefinedValue
|
||||
%type <value> ReferencedValue
|
||||
%type <value> Valuereference
|
||||
|
||||
%type <type> Type
|
||||
%type <type> BuiltinType
|
||||
%type <type> BitStringType
|
||||
%type <type> BooleanType
|
||||
%type <type> ChoiceType
|
||||
%type <type> ConstrainedType
|
||||
%type <type> EnumeratedType
|
||||
%type <type> IntegerType
|
||||
%type <type> NullType
|
||||
%type <type> OctetStringType
|
||||
%type <type> SequenceType
|
||||
%type <type> SequenceOfType
|
||||
%type <type> SetType
|
||||
%type <type> SetOfType
|
||||
%type <type> TaggedType
|
||||
%type <type> ReferencedType
|
||||
%type <type> DefinedType
|
||||
%type <type> UsefulType
|
||||
%type <type> ObjectIdentifierType
|
||||
%type <type> CharacterStringType
|
||||
%type <type> RestrictedCharactedStringType
|
||||
|
||||
%type <tag> Tag
|
||||
|
||||
%type <member> ComponentType
|
||||
%type <member> NamedBit
|
||||
%type <member> NamedNumber
|
||||
%type <member> NamedType
|
||||
%type <members> ComponentTypeList
|
||||
%type <members> Enumerations
|
||||
%type <members> NamedBitList
|
||||
%type <members> NamedNumberList
|
||||
|
||||
%type <objid> objid objid_list objid_element objid_opt
|
||||
%type <range> range
|
||||
|
||||
%type <sl> referencenames
|
||||
|
||||
%type <constraint_spec> Constraint
|
||||
%type <constraint_spec> ConstraintSpec
|
||||
%type <constraint_spec> GeneralConstraint
|
||||
%type <constraint_spec> ContentsConstraint
|
||||
%type <constraint_spec> UserDefinedConstraint
|
||||
|
||||
%start ModuleDefinition
|
||||
|
||||
%%
|
||||
|
||||
ModuleDefinition: IDENTIFIER kw_DEFINITIONS TagDefault ExtensionDefault
|
||||
EEQUAL kw_BEGIN ModuleBody kw_END
|
||||
{
|
||||
checkundefined();
|
||||
}
|
||||
;
|
||||
|
||||
TagDefault : kw_EXPLICIT kw_TAGS
|
||||
| kw_IMPLICIT kw_TAGS
|
||||
{ error_message("implicit tagging is not supported"); }
|
||||
| kw_AUTOMATIC kw_TAGS
|
||||
{ error_message("automatic tagging is not supported"); }
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
|
||||
{ error_message("no extensibility options supported"); }
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
ModuleBody : /* Exports */ Imports AssignmentList
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
Imports : kw_IMPORTS SymbolsImported ';'
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
SymbolsImported : SymbolsFromModuleList
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
SymbolsFromModuleList: SymbolsFromModule
|
||||
| SymbolsFromModuleList SymbolsFromModule
|
||||
;
|
||||
|
||||
SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
|
||||
{
|
||||
struct string_list *sl;
|
||||
for(sl = $1; sl != NULL; sl = sl->next) {
|
||||
Symbol *s = addsym(sl->string);
|
||||
s->stype = Stype;
|
||||
}
|
||||
add_import($3);
|
||||
}
|
||||
;
|
||||
|
||||
AssignmentList : Assignment
|
||||
| Assignment AssignmentList
|
||||
;
|
||||
|
||||
Assignment : TypeAssignment
|
||||
| ValueAssignment
|
||||
;
|
||||
|
||||
referencenames : IDENTIFIER ',' referencenames
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
$$->string = $1;
|
||||
$$->next = $3;
|
||||
}
|
||||
| IDENTIFIER
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
$$->string = $1;
|
||||
$$->next = NULL;
|
||||
}
|
||||
;
|
||||
|
||||
TypeAssignment : IDENTIFIER EEQUAL Type
|
||||
{
|
||||
Symbol *s = addsym ($1);
|
||||
s->stype = Stype;
|
||||
s->type = $3;
|
||||
fix_labels(s);
|
||||
generate_type (s);
|
||||
}
|
||||
;
|
||||
|
||||
Type : BuiltinType
|
||||
| ReferencedType
|
||||
| ConstrainedType
|
||||
;
|
||||
|
||||
BuiltinType : BitStringType
|
||||
| BooleanType
|
||||
| CharacterStringType
|
||||
| ChoiceType
|
||||
| EnumeratedType
|
||||
| IntegerType
|
||||
| NullType
|
||||
| ObjectIdentifierType
|
||||
| OctetStringType
|
||||
| SequenceType
|
||||
| SequenceOfType
|
||||
| SetType
|
||||
| SetOfType
|
||||
| TaggedType
|
||||
;
|
||||
|
||||
BooleanType : kw_BOOLEAN
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Boolean,
|
||||
TE_EXPLICIT, new_type(TBoolean));
|
||||
}
|
||||
;
|
||||
|
||||
range : '(' Value RANGE Value ')'
|
||||
{
|
||||
if($2->type != integervalue ||
|
||||
$4->type != integervalue)
|
||||
error_message("Non-integer value used in range");
|
||||
$$.min = $2->u.integervalue;
|
||||
$$.max = $4->u.integervalue;
|
||||
}
|
||||
;
|
||||
|
||||
IntegerType : kw_INTEGER
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Integer,
|
||||
TE_EXPLICIT, new_type(TInteger));
|
||||
}
|
||||
| kw_INTEGER range
|
||||
{
|
||||
$$ = new_type(TInteger);
|
||||
$$->range = emalloc(sizeof(*$$->range));
|
||||
*($$->range) = $2;
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
|
||||
}
|
||||
| kw_INTEGER '{' NamedNumberList '}'
|
||||
{
|
||||
$$ = new_type(TInteger);
|
||||
$$->members = $3;
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
|
||||
}
|
||||
;
|
||||
|
||||
NamedNumberList : NamedNumber
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
ASN1_TAILQ_INIT($$);
|
||||
ASN1_TAILQ_INSERT_HEAD($$, $1, members);
|
||||
}
|
||||
| NamedNumberList ',' NamedNumber
|
||||
{
|
||||
ASN1_TAILQ_INSERT_TAIL($1, $3, members);
|
||||
$$ = $1;
|
||||
}
|
||||
| NamedNumberList ',' ELLIPSIS
|
||||
{ $$ = $1; } /* XXX used for Enumerations */
|
||||
;
|
||||
|
||||
NamedNumber : IDENTIFIER '(' SignedNumber ')'
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
$$->name = $1;
|
||||
$$->gen_name = estrdup($1);
|
||||
output_name ($$->gen_name);
|
||||
$$->val = $3;
|
||||
$$->optional = 0;
|
||||
$$->ellipsis = 0;
|
||||
$$->type = NULL;
|
||||
}
|
||||
;
|
||||
|
||||
EnumeratedType : kw_ENUMERATED '{' Enumerations '}'
|
||||
{
|
||||
$$ = new_type(TInteger);
|
||||
$$->members = $3;
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, $$);
|
||||
}
|
||||
;
|
||||
|
||||
Enumerations : NamedNumberList /* XXX */
|
||||
;
|
||||
|
||||
BitStringType : kw_BIT kw_STRING
|
||||
{
|
||||
$$ = new_type(TBitString);
|
||||
$$->members = emalloc(sizeof(*$$->members));
|
||||
ASN1_TAILQ_INIT($$->members);
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
|
||||
}
|
||||
| kw_BIT kw_STRING '{' NamedBitList '}'
|
||||
{
|
||||
$$ = new_type(TBitString);
|
||||
$$->members = $4;
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
|
||||
}
|
||||
;
|
||||
|
||||
ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_OID,
|
||||
TE_EXPLICIT, new_type(TOID));
|
||||
}
|
||||
;
|
||||
OctetStringType : kw_OCTET kw_STRING
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_OctetString,
|
||||
TE_EXPLICIT, new_type(TOctetString));
|
||||
}
|
||||
;
|
||||
|
||||
NullType : kw_NULL
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Null,
|
||||
TE_EXPLICIT, new_type(TNull));
|
||||
}
|
||||
;
|
||||
|
||||
SequenceType : kw_SEQUENCE '{' /* ComponentTypeLists */ ComponentTypeList '}'
|
||||
{
|
||||
$$ = new_type(TSequence);
|
||||
$$->members = $3;
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
|
||||
}
|
||||
| kw_SEQUENCE '{' '}'
|
||||
{
|
||||
$$ = new_type(TSequence);
|
||||
$$->members = NULL;
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
|
||||
}
|
||||
;
|
||||
|
||||
SequenceOfType : kw_SEQUENCE kw_OF Type
|
||||
{
|
||||
$$ = new_type(TSequenceOf);
|
||||
$$->subtype = $3;
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
|
||||
}
|
||||
;
|
||||
|
||||
SetType : kw_SET '{' /* ComponentTypeLists */ ComponentTypeList '}'
|
||||
{
|
||||
$$ = new_type(TSet);
|
||||
$$->members = $3;
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
|
||||
}
|
||||
| kw_SET '{' '}'
|
||||
{
|
||||
$$ = new_type(TSet);
|
||||
$$->members = NULL;
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
|
||||
}
|
||||
;
|
||||
|
||||
SetOfType : kw_SET kw_OF Type
|
||||
{
|
||||
$$ = new_type(TSetOf);
|
||||
$$->subtype = $3;
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
|
||||
}
|
||||
;
|
||||
|
||||
ChoiceType : kw_CHOICE '{' /* AlternativeTypeLists */ ComponentTypeList '}'
|
||||
{
|
||||
$$ = new_type(TChoice);
|
||||
$$->members = $3;
|
||||
}
|
||||
;
|
||||
|
||||
ReferencedType : DefinedType
|
||||
| UsefulType
|
||||
;
|
||||
|
||||
DefinedType : IDENTIFIER
|
||||
{
|
||||
Symbol *s = addsym($1);
|
||||
$$ = new_type(TType);
|
||||
if(s->stype != Stype && s->stype != SUndefined)
|
||||
error_message ("%s is not a type\n", $1);
|
||||
else
|
||||
$$->symbol = s;
|
||||
}
|
||||
;
|
||||
|
||||
UsefulType : kw_GeneralizedTime
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_GeneralizedTime,
|
||||
TE_EXPLICIT, new_type(TGeneralizedTime));
|
||||
}
|
||||
| kw_UTCTime
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_UTCTime,
|
||||
TE_EXPLICIT, new_type(TUTCTime));
|
||||
}
|
||||
;
|
||||
|
||||
ConstrainedType : Type Constraint
|
||||
{
|
||||
/* if (Constraint.type == contentConstrant) {
|
||||
assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
|
||||
if (Constraint.u.constraint.type) {
|
||||
assert((Constraint.u.constraint.type.length % 8) == 0);
|
||||
}
|
||||
}
|
||||
if (Constraint.u.constraint.encoding) {
|
||||
type == der-oid|ber-oid
|
||||
}
|
||||
*/
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
Constraint : '(' ConstraintSpec ')'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
|
||||
ConstraintSpec : GeneralConstraint
|
||||
|
||||
GeneralConstraint: ContentsConstraint
|
||||
| UserDefinedConstraint
|
||||
;
|
||||
|
||||
ContentsConstraint: kw_CONTAINING Type
|
||||
{
|
||||
$$ = new_constraint_spec(CT_CONTENTS);
|
||||
$$->u.content.type = $2;
|
||||
$$->u.content.encoding = NULL;
|
||||
}
|
||||
| kw_ENCODED kw_BY Value
|
||||
{
|
||||
if ($3->type != objectidentifiervalue)
|
||||
error_message("Non-OID used in ENCODED BY constraint");
|
||||
$$ = new_constraint_spec(CT_CONTENTS);
|
||||
$$->u.content.type = NULL;
|
||||
$$->u.content.encoding = $3;
|
||||
}
|
||||
| kw_CONTAINING Type kw_ENCODED kw_BY Value
|
||||
{
|
||||
if ($5->type != objectidentifiervalue)
|
||||
error_message("Non-OID used in ENCODED BY constraint");
|
||||
$$ = new_constraint_spec(CT_CONTENTS);
|
||||
$$->u.content.type = $2;
|
||||
$$->u.content.encoding = $5;
|
||||
}
|
||||
;
|
||||
|
||||
UserDefinedConstraint: kw_CONSTRAINED kw_BY '{' '}'
|
||||
{
|
||||
$$ = new_constraint_spec(CT_USER);
|
||||
}
|
||||
;
|
||||
|
||||
TaggedType : Tag tagenv Type
|
||||
{
|
||||
$$ = new_type(TTag);
|
||||
$$->tag = $1;
|
||||
$$->tag.tagenv = $2;
|
||||
if($3->type == TTag && $2 == TE_IMPLICIT) {
|
||||
$$->subtype = $3->subtype;
|
||||
free($3);
|
||||
} else
|
||||
$$->subtype = $3;
|
||||
}
|
||||
;
|
||||
|
||||
Tag : '[' Class NUMBER ']'
|
||||
{
|
||||
$$.tagclass = $2;
|
||||
$$.tagvalue = $3;
|
||||
$$.tagenv = TE_EXPLICIT;
|
||||
}
|
||||
;
|
||||
|
||||
Class : /* */
|
||||
{
|
||||
$$ = ASN1_C_CONTEXT;
|
||||
}
|
||||
| kw_UNIVERSAL
|
||||
{
|
||||
$$ = ASN1_C_UNIV;
|
||||
}
|
||||
| kw_APPLICATION
|
||||
{
|
||||
$$ = ASN1_C_APPL;
|
||||
}
|
||||
| kw_PRIVATE
|
||||
{
|
||||
$$ = ASN1_C_PRIVATE;
|
||||
}
|
||||
;
|
||||
|
||||
tagenv : /* */
|
||||
{
|
||||
$$ = TE_EXPLICIT;
|
||||
}
|
||||
| kw_EXPLICIT
|
||||
{
|
||||
$$ = TE_EXPLICIT;
|
||||
}
|
||||
| kw_IMPLICIT
|
||||
{
|
||||
$$ = TE_IMPLICIT;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
ValueAssignment : IDENTIFIER Type EEQUAL Value
|
||||
{
|
||||
Symbol *s;
|
||||
s = addsym ($1);
|
||||
|
||||
s->stype = SValue;
|
||||
s->value = $4;
|
||||
generate_constant (s);
|
||||
}
|
||||
;
|
||||
|
||||
CharacterStringType: RestrictedCharactedStringType
|
||||
;
|
||||
|
||||
RestrictedCharactedStringType: kw_GeneralString
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_GeneralString,
|
||||
TE_EXPLICIT, new_type(TGeneralString));
|
||||
}
|
||||
| kw_UTF8String
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_UTF8String,
|
||||
TE_EXPLICIT, new_type(TUTF8String));
|
||||
}
|
||||
| kw_PrintableString
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_PrintableString,
|
||||
TE_EXPLICIT, new_type(TPrintableString));
|
||||
}
|
||||
| kw_IA5String
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_IA5String,
|
||||
TE_EXPLICIT, new_type(TIA5String));
|
||||
}
|
||||
| kw_BMPString
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_BMPString,
|
||||
TE_EXPLICIT, new_type(TBMPString));
|
||||
}
|
||||
| kw_UniversalString
|
||||
{
|
||||
$$ = new_tag(ASN1_C_UNIV, UT_UniversalString,
|
||||
TE_EXPLICIT, new_type(TUniversalString));
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
ComponentTypeList: ComponentType
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
ASN1_TAILQ_INIT($$);
|
||||
ASN1_TAILQ_INSERT_HEAD($$, $1, members);
|
||||
}
|
||||
| ComponentTypeList ',' ComponentType
|
||||
{
|
||||
ASN1_TAILQ_INSERT_TAIL($1, $3, members);
|
||||
$$ = $1;
|
||||
}
|
||||
| ComponentTypeList ',' ELLIPSIS
|
||||
{
|
||||
struct member *m = ecalloc(1, sizeof(*m));
|
||||
m->name = estrdup("...");
|
||||
m->gen_name = estrdup("asn1_ellipsis");
|
||||
m->ellipsis = 1;
|
||||
ASN1_TAILQ_INSERT_TAIL($1, m, members);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
NamedType : IDENTIFIER Type
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
$$->name = $1;
|
||||
$$->gen_name = estrdup($1);
|
||||
output_name ($$->gen_name);
|
||||
$$->type = $2;
|
||||
$$->ellipsis = 0;
|
||||
}
|
||||
;
|
||||
|
||||
ComponentType : NamedType
|
||||
{
|
||||
$$ = $1;
|
||||
$$->optional = 0;
|
||||
$$->defval = NULL;
|
||||
}
|
||||
| NamedType kw_OPTIONAL
|
||||
{
|
||||
$$ = $1;
|
||||
$$->optional = 1;
|
||||
$$->defval = NULL;
|
||||
}
|
||||
| NamedType kw_DEFAULT Value
|
||||
{
|
||||
$$ = $1;
|
||||
$$->optional = 0;
|
||||
$$->defval = $3;
|
||||
}
|
||||
;
|
||||
|
||||
NamedBitList : NamedBit
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
ASN1_TAILQ_INIT($$);
|
||||
ASN1_TAILQ_INSERT_HEAD($$, $1, members);
|
||||
}
|
||||
| NamedBitList ',' NamedBit
|
||||
{
|
||||
ASN1_TAILQ_INSERT_TAIL($1, $3, members);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
NamedBit : IDENTIFIER '(' NUMBER ')'
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
$$->name = $1;
|
||||
$$->gen_name = estrdup($1);
|
||||
output_name ($$->gen_name);
|
||||
$$->val = $3;
|
||||
$$->optional = 0;
|
||||
$$->ellipsis = 0;
|
||||
$$->type = NULL;
|
||||
}
|
||||
;
|
||||
|
||||
objid_opt : objid
|
||||
| /* empty */ { $$ = NULL; }
|
||||
;
|
||||
|
||||
objid : '{' objid_list '}'
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
objid_list : /* empty */
|
||||
{
|
||||
$$ = NULL;
|
||||
}
|
||||
| objid_element objid_list
|
||||
{
|
||||
if ($2) {
|
||||
$$ = $2;
|
||||
add_oid_to_tail($2, $1);
|
||||
} else {
|
||||
$$ = $1;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
objid_element : IDENTIFIER '(' NUMBER ')'
|
||||
{
|
||||
$$ = new_objid($1, $3);
|
||||
}
|
||||
| IDENTIFIER
|
||||
{
|
||||
Symbol *s = addsym($1);
|
||||
if(s->stype != SValue ||
|
||||
s->value->type != objectidentifiervalue) {
|
||||
error_message("%s is not an object identifier\n",
|
||||
s->name);
|
||||
exit(1);
|
||||
}
|
||||
$$ = s->value->u.objectidentifiervalue;
|
||||
}
|
||||
| NUMBER
|
||||
{
|
||||
$$ = new_objid(NULL, $1);
|
||||
}
|
||||
;
|
||||
|
||||
Value : BuiltinValue
|
||||
| ReferencedValue
|
||||
;
|
||||
|
||||
BuiltinValue : BooleanValue
|
||||
| CharacterStringValue
|
||||
| IntegerValue
|
||||
| ObjectIdentifierValue
|
||||
| NullValue
|
||||
;
|
||||
|
||||
ReferencedValue : DefinedValue
|
||||
;
|
||||
|
||||
DefinedValue : Valuereference
|
||||
;
|
||||
|
||||
Valuereference : IDENTIFIER
|
||||
{
|
||||
Symbol *s = addsym($1);
|
||||
if(s->stype != SValue)
|
||||
error_message ("%s is not a value\n",
|
||||
s->name);
|
||||
else
|
||||
$$ = s->value;
|
||||
}
|
||||
;
|
||||
|
||||
CharacterStringValue: STRING
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
$$->type = stringvalue;
|
||||
$$->u.stringvalue = $1;
|
||||
}
|
||||
;
|
||||
|
||||
BooleanValue : kw_TRUE
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
$$->type = booleanvalue;
|
||||
$$->u.booleanvalue = 0;
|
||||
}
|
||||
| kw_FALSE
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
$$->type = booleanvalue;
|
||||
$$->u.booleanvalue = 0;
|
||||
}
|
||||
;
|
||||
|
||||
IntegerValue : SignedNumber
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
$$->type = integervalue;
|
||||
$$->u.integervalue = $1;
|
||||
}
|
||||
;
|
||||
|
||||
SignedNumber : NUMBER
|
||||
;
|
||||
|
||||
NullValue : kw_NULL
|
||||
{
|
||||
}
|
||||
;
|
||||
|
||||
ObjectIdentifierValue: objid
|
||||
{
|
||||
$$ = emalloc(sizeof(*$$));
|
||||
$$->type = objectidentifiervalue;
|
||||
$$->u.objectidentifiervalue = $1;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
yyerror (const char *s)
|
||||
{
|
||||
error_message ("%s\n", s);
|
||||
}
|
||||
|
||||
static Type *
|
||||
new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
|
||||
{
|
||||
Type *t;
|
||||
if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
|
||||
t = oldtype;
|
||||
oldtype = oldtype->subtype; /* XXX */
|
||||
} else
|
||||
t = new_type (TTag);
|
||||
|
||||
t->tag.tagclass = tagclass;
|
||||
t->tag.tagvalue = tagvalue;
|
||||
t->tag.tagenv = tagenv;
|
||||
t->subtype = oldtype;
|
||||
return t;
|
||||
}
|
||||
|
||||
static struct objid *
|
||||
new_objid(const char *label, int value)
|
||||
{
|
||||
struct objid *s;
|
||||
s = emalloc(sizeof(*s));
|
||||
s->label = label;
|
||||
s->value = value;
|
||||
s->next = NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
static void
|
||||
add_oid_to_tail(struct objid *head, struct objid *tail)
|
||||
{
|
||||
struct objid *o;
|
||||
o = head;
|
||||
while (o->next)
|
||||
o = o->next;
|
||||
o->next = tail;
|
||||
}
|
||||
|
||||
static Type *
|
||||
new_type (Typetype tt)
|
||||
{
|
||||
Type *t = ecalloc(1, sizeof(*t));
|
||||
t->type = tt;
|
||||
return t;
|
||||
}
|
||||
|
||||
static struct constraint_spec *
|
||||
new_constraint_spec(enum ctype ct)
|
||||
{
|
||||
struct constraint_spec *c = ecalloc(1, sizeof(*c));
|
||||
c->ctype = ct;
|
||||
return c;
|
||||
}
|
||||
|
||||
static void fix_labels2(Type *t, const char *prefix);
|
||||
static void fix_labels1(struct memhead *members, const char *prefix)
|
||||
{
|
||||
Member *m;
|
||||
|
||||
if(members == NULL)
|
||||
return;
|
||||
ASN1_TAILQ_FOREACH(m, members, members) {
|
||||
asprintf(&m->label, "%s_%s", prefix, m->gen_name);
|
||||
if (m->label == NULL)
|
||||
errx(1, "malloc");
|
||||
if(m->type != NULL)
|
||||
fix_labels2(m->type, m->label);
|
||||
}
|
||||
}
|
||||
|
||||
static void fix_labels2(Type *t, const char *prefix)
|
||||
{
|
||||
for(; t; t = t->subtype)
|
||||
fix_labels1(t->members, prefix);
|
||||
}
|
||||
|
||||
static void
|
||||
fix_labels(Symbol *s)
|
||||
{
|
||||
char *p;
|
||||
asprintf(&p, "choice_%s", s->gen_name);
|
||||
if (p == NULL)
|
||||
errx(1, "malloc");
|
||||
fix_labels2(s->type, p);
|
||||
free(p);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
-- $Id: pkcs12.asn1,v 1.3 2005/07/23 11:07:39 lha Exp $ --
|
||||
|
||||
PKCS12 DEFINITIONS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
IMPORTS ContentInfo FROM cms
|
||||
DigestInfo FROM rfc2459
|
||||
heim_any, heim_any_set FROM heim;
|
||||
|
||||
-- The PFX PDU
|
||||
|
||||
id-pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) pkcs-12(12) }
|
||||
|
||||
id-pkcs-12PbeIds OBJECT IDENTIFIER ::= { id-pkcs-12 1}
|
||||
id-pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 1}
|
||||
id-pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 2}
|
||||
id-pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 3}
|
||||
id-pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 4}
|
||||
id-pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 5}
|
||||
id-pbewithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= { id-pkcs-12PbeIds 6}
|
||||
|
||||
id-pkcs12-bagtypes OBJECT IDENTIFIER ::= { id-pkcs-12 10 1}
|
||||
|
||||
id-pkcs12-keyBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 1 }
|
||||
id-pkcs12-pkcs8ShroudedKeyBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 2 }
|
||||
id-pkcs12-certBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 3 }
|
||||
id-pkcs12-crlBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 4 }
|
||||
id-pkcs12-secretBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 5 }
|
||||
id-pkcs12-safeContentsBag OBJECT IDENTIFIER ::= { id-pkcs12-bagtypes 6 }
|
||||
|
||||
|
||||
PKCS12-MacData ::= SEQUENCE {
|
||||
mac DigestInfo,
|
||||
macSalt OCTET STRING,
|
||||
iterations INTEGER OPTIONAL
|
||||
}
|
||||
|
||||
PKCS12-PFX ::= SEQUENCE {
|
||||
version INTEGER,
|
||||
authSafe ContentInfo,
|
||||
macData PKCS12-MacData OPTIONAL
|
||||
}
|
||||
|
||||
PKCS12-AuthenticatedSafe ::= SEQUENCE OF ContentInfo
|
||||
-- Data if unencrypted
|
||||
-- EncryptedData if password-encrypted
|
||||
-- EnvelopedData if public key-encrypted
|
||||
|
||||
PKCS12-Attribute ::= SEQUENCE {
|
||||
attrId OBJECT IDENTIFIER,
|
||||
attrValues -- SET OF -- heim_any_set
|
||||
}
|
||||
|
||||
PKCS12-Attributes ::= SET OF PKCS12-Attribute
|
||||
|
||||
PKCS12-SafeBag ::= SEQUENCE {
|
||||
bagId OBJECT IDENTIFIER,
|
||||
bagValue [0] heim_any,
|
||||
bagAttributes PKCS12-Attributes OPTIONAL
|
||||
}
|
||||
|
||||
PKCS12-SafeContents ::= SEQUENCE OF PKCS12-SafeBag
|
||||
|
||||
PKCS12-CertBag ::= SEQUENCE {
|
||||
certType OBJECT IDENTIFIER,
|
||||
certValue [0] heim_any
|
||||
}
|
||||
|
||||
PKCS12-PBEParams ::= SEQUENCE {
|
||||
salt OCTET STRING,
|
||||
iterations INTEGER (0..4294967295) OPTIONAL
|
||||
}
|
||||
|
||||
PKCS12-OctetString ::= OCTET STRING
|
||||
|
||||
-- KeyBag ::= PrivateKeyInfo
|
||||
-- PKCS8ShroudedKeyBag ::= EncryptedPrivateKeyInfo
|
||||
|
||||
END
|
||||
@@ -0,0 +1,30 @@
|
||||
-- $Id: pkcs8.asn1,v 1.3 2005/09/13 19:41:29 lha Exp $ --
|
||||
|
||||
PKCS8 DEFINITIONS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
IMPORTS Attribute, AlgorithmIdentifier FROM rfc2459
|
||||
heim_any, heim_any_set FROM heim;
|
||||
|
||||
PKCS8PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
|
||||
PKCS8PrivateKey ::= OCTET STRING
|
||||
|
||||
PKCS8Attributes ::= SET OF Attribute
|
||||
|
||||
PKCS8PrivateKeyInfo ::= SEQUENCE {
|
||||
version INTEGER,
|
||||
privateKeyAlgorithm PKCS8PrivateKeyAlgorithmIdentifier,
|
||||
privateKey PKCS8PrivateKey,
|
||||
attributes [0] IMPLICIT SET OF Attribute OPTIONAL
|
||||
}
|
||||
|
||||
PKCS8EncryptedData ::= OCTET STRING
|
||||
|
||||
PKCS8EncryptedPrivateKeyInfo ::= SEQUENCE {
|
||||
encryptionAlgorithm AlgorithmIdentifier,
|
||||
encryptedData PKCS8EncryptedData
|
||||
}
|
||||
|
||||
END
|
||||
@@ -0,0 +1,28 @@
|
||||
-- $Id: pkcs9.asn1,v 1.5 2006/04/24 08:59:10 lha Exp $ --
|
||||
|
||||
PKCS9 DEFINITIONS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
-- The PFX PDU
|
||||
|
||||
id-pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) pkcs-9(9) }
|
||||
|
||||
id-pkcs9-emailAddress OBJECT IDENTIFIER ::= {id-pkcs-9 1 }
|
||||
id-pkcs9-contentType OBJECT IDENTIFIER ::= {id-pkcs-9 3 }
|
||||
id-pkcs9-messageDigest OBJECT IDENTIFIER ::= {id-pkcs-9 4 }
|
||||
id-pkcs9-signingTime OBJECT IDENTIFIER ::= {id-pkcs-9 5 }
|
||||
id-pkcs9-countersignature OBJECT IDENTIFIER ::= {id-pkcs-9 6 }
|
||||
|
||||
id-pkcs-9-at-friendlyName OBJECT IDENTIFIER ::= {id-pkcs-9 20}
|
||||
id-pkcs-9-at-localKeyId OBJECT IDENTIFIER ::= {id-pkcs-9 21}
|
||||
id-pkcs-9-at-certTypes OBJECT IDENTIFIER ::= {id-pkcs-9 22}
|
||||
id-pkcs-9-at-certTypes-x509 OBJECT IDENTIFIER ::= {id-pkcs-9-at-certTypes 1}
|
||||
|
||||
PKCS9-BMPString ::= BMPString
|
||||
|
||||
PKCS9-friendlyName ::= SET OF PKCS9-BMPString
|
||||
|
||||
END
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
-- $Id$ --
|
||||
|
||||
PKINIT DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS EncryptionKey, PrincipalName, Realm, KerberosTime, Checksum FROM krb5
|
||||
IssuerAndSerialNumber, ContentInfo FROM cms
|
||||
SubjectPublicKeyInfo, AlgorithmIdentifier FROM rfc2459
|
||||
heim_any FROM heim;
|
||||
|
||||
id-pkinit OBJECT IDENTIFIER ::=
|
||||
{ iso (1) org (3) dod (6) internet (1) security (5)
|
||||
kerberosv5 (2) pkinit (3) }
|
||||
|
||||
id-pkauthdata OBJECT IDENTIFIER ::= { id-pkinit 1 }
|
||||
id-pkdhkeydata OBJECT IDENTIFIER ::= { id-pkinit 2 }
|
||||
id-pkrkeydata OBJECT IDENTIFIER ::= { id-pkinit 3 }
|
||||
id-pkekuoid OBJECT IDENTIFIER ::= { id-pkinit 4 }
|
||||
id-pkkdcekuoid OBJECT IDENTIFIER ::= { id-pkinit 5 }
|
||||
|
||||
id-pkinit-san OBJECT IDENTIFIER ::=
|
||||
{ iso(1) org(3) dod(6) internet(1) security(5) kerberosv5(2)
|
||||
x509-sanan(2) }
|
||||
|
||||
id-pkinit-ms-san OBJECT IDENTIFIER ::=
|
||||
{ iso(1) org(3) dod(6) internet(1) foo1(4)
|
||||
foo2(1) foo3(311) foo4(20) foo5(2) foo6(3) }
|
||||
|
||||
pa-pk-as-req INTEGER ::= 16
|
||||
pa-pk-as-rep INTEGER ::= 17
|
||||
|
||||
ad-initial-verified-cas INTEGER ::= 9
|
||||
|
||||
td-trusted-certifiers INTEGER ::= 104
|
||||
td-invalid-certificates INTEGER ::= 105
|
||||
td-dh-parameters INTEGER ::= 109
|
||||
|
||||
DHNonce ::= OCTET STRING
|
||||
|
||||
TrustedCA ::= SEQUENCE {
|
||||
caName [0] IMPLICIT OCTET STRING,
|
||||
certificateSerialNumber [1] INTEGER OPTIONAL,
|
||||
subjectKeyIdentifier [2] OCTET STRING OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
ExternalPrincipalIdentifier ::= SEQUENCE {
|
||||
subjectName [0] IMPLICIT OCTET STRING OPTIONAL,
|
||||
issuerAndSerialNumber [1] IMPLICIT OCTET STRING OPTIONAL,
|
||||
subjectKeyIdentifier [2] IMPLICIT OCTET STRING OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
ExternalPrincipalIdentifiers ::= SEQUENCE OF ExternalPrincipalIdentifier
|
||||
|
||||
PA-PK-AS-REQ ::= SEQUENCE {
|
||||
signedAuthPack [0] IMPLICIT OCTET STRING,
|
||||
trustedCertifiers [1] ExternalPrincipalIdentifiers OPTIONAL,
|
||||
kdcPkId [2] IMPLICIT OCTET STRING OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
PKAuthenticator ::= SEQUENCE {
|
||||
cusec [0] INTEGER -- (0..999999) --,
|
||||
ctime [1] KerberosTime,
|
||||
nonce [2] INTEGER (0..4294967295),
|
||||
paChecksum [3] OCTET STRING OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
AuthPack ::= SEQUENCE {
|
||||
pkAuthenticator [0] PKAuthenticator,
|
||||
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL,
|
||||
supportedCMSTypes [2] SEQUENCE OF AlgorithmIdentifier OPTIONAL,
|
||||
clientDHNonce [3] DHNonce OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
TD-TRUSTED-CERTIFIERS ::= ExternalPrincipalIdentifiers
|
||||
TD-INVALID-CERTIFICATES ::= ExternalPrincipalIdentifiers
|
||||
|
||||
KRB5PrincipalName ::= SEQUENCE {
|
||||
realm [0] Realm,
|
||||
principalName [1] PrincipalName
|
||||
}
|
||||
|
||||
AD-INITIAL-VERIFIED-CAS ::= SEQUENCE OF ExternalPrincipalIdentifier
|
||||
|
||||
|
||||
DHRepInfo ::= SEQUENCE {
|
||||
dhSignedData [0] IMPLICIT OCTET STRING,
|
||||
serverDHNonce [1] DHNonce OPTIONAL
|
||||
}
|
||||
|
||||
PA-PK-AS-REP ::= CHOICE {
|
||||
dhInfo [0] DHRepInfo,
|
||||
encKeyPack [1] IMPLICIT OCTET STRING,
|
||||
...
|
||||
}
|
||||
|
||||
KDCDHKeyInfo ::= SEQUENCE {
|
||||
subjectPublicKey [0] BIT STRING,
|
||||
nonce [1] INTEGER (0..4294967295),
|
||||
dhKeyExpiration [2] KerberosTime OPTIONAL,
|
||||
...
|
||||
}
|
||||
|
||||
ReplyKeyPack ::= SEQUENCE {
|
||||
replyKey [0] EncryptionKey,
|
||||
asChecksum [1] Checksum,
|
||||
...
|
||||
}
|
||||
|
||||
TD-DH-PARAMETERS ::= SEQUENCE OF AlgorithmIdentifier
|
||||
|
||||
|
||||
-- Windows compat glue --
|
||||
|
||||
PKAuthenticator-Win2k ::= SEQUENCE {
|
||||
kdcName [0] PrincipalName,
|
||||
kdcRealm [1] Realm,
|
||||
cusec [2] INTEGER (0..4294967295),
|
||||
ctime [3] KerberosTime,
|
||||
nonce [4] INTEGER (-2147483648..2147483647)
|
||||
}
|
||||
|
||||
AuthPack-Win2k ::= SEQUENCE {
|
||||
pkAuthenticator [0] PKAuthenticator-Win2k,
|
||||
clientPublicValue [1] SubjectPublicKeyInfo OPTIONAL
|
||||
}
|
||||
|
||||
|
||||
TrustedCA-Win2k ::= CHOICE {
|
||||
caName [1] heim_any,
|
||||
issuerAndSerial [2] IssuerAndSerialNumber
|
||||
}
|
||||
|
||||
PA-PK-AS-REQ-Win2k ::= SEQUENCE {
|
||||
signed-auth-pack [0] IMPLICIT OCTET STRING,
|
||||
trusted-certifiers [2] SEQUENCE OF TrustedCA-Win2k OPTIONAL,
|
||||
kdc-cert [3] IMPLICIT OCTET STRING OPTIONAL,
|
||||
encryption-cert [4] IMPLICIT OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
PA-PK-AS-REP-Win2k ::= CHOICE {
|
||||
dhSignedData [0] IMPLICIT OCTET STRING,
|
||||
encKeyPack [1] IMPLICIT OCTET STRING
|
||||
}
|
||||
|
||||
|
||||
KDCDHKeyInfo-Win2k ::= SEQUENCE {
|
||||
nonce [0] INTEGER (-2147483648..2147483647),
|
||||
subjectPublicKey [2] BIT STRING
|
||||
}
|
||||
|
||||
ReplyKeyPack-Win2k ::= SEQUENCE {
|
||||
replyKey [0] EncryptionKey,
|
||||
nonce [1] INTEGER (0..4294967295),
|
||||
...
|
||||
}
|
||||
|
||||
END
|
||||
@@ -0,0 +1,426 @@
|
||||
-- $Id$ --
|
||||
-- Definitions from rfc2459/rfc3280
|
||||
|
||||
RFC2459 DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS heim_any FROM heim;
|
||||
|
||||
Version ::= INTEGER {
|
||||
rfc3280_version_1(0),
|
||||
rfc3280_version_2(1),
|
||||
rfc3280_version_3(2)
|
||||
}
|
||||
|
||||
id-pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) 1 }
|
||||
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 }
|
||||
id-pkcs1-sha256WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 11 }
|
||||
id-pkcs1-sha384WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 12 }
|
||||
id-pkcs1-sha512WithRSAEncryption OBJECT IDENTIFIER ::= { id-pkcs-1 13 }
|
||||
|
||||
id-pkcs-2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) 2 }
|
||||
id-pkcs2-md2 OBJECT IDENTIFIER ::= { id-pkcs-2 2 }
|
||||
id-pkcs2-md4 OBJECT IDENTIFIER ::= { id-pkcs-2 4 }
|
||||
id-pkcs2-md5 OBJECT IDENTIFIER ::= { id-pkcs-2 5 }
|
||||
|
||||
id-rsa-digestAlgorithm OBJECT IDENTIFIER ::=
|
||||
{ iso(1) member-body(2) us(840) rsadsi(113549) 2 }
|
||||
|
||||
id-rsa-digest-md2 OBJECT IDENTIFIER ::= { id-rsa-digestAlgorithm 2 }
|
||||
id-rsa-digest-md4 OBJECT IDENTIFIER ::= { id-rsa-digestAlgorithm 4 }
|
||||
id-rsa-digest-md5 OBJECT IDENTIFIER ::= { id-rsa-digestAlgorithm 5 }
|
||||
|
||||
id-pkcs-3 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) pkcs(1) 3 }
|
||||
|
||||
id-pkcs3-rc2-cbc OBJECT IDENTIFIER ::= { id-pkcs-3 2 }
|
||||
id-pkcs3-rc4 OBJECT IDENTIFIER ::= { id-pkcs-3 4 }
|
||||
id-pkcs3-des-ede3-cbc OBJECT IDENTIFIER ::= { id-pkcs-3 7 }
|
||||
|
||||
id-rsadsi-encalg OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840)
|
||||
rsadsi(113549) 3 }
|
||||
|
||||
id-rsadsi-rc2-cbc OBJECT IDENTIFIER ::= { id-rsadsi-encalg 2 }
|
||||
id-rsadsi-des-ede3-cbc OBJECT IDENTIFIER ::= { id-rsadsi-encalg 7 }
|
||||
|
||||
id-secsig-sha-1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
|
||||
oiw(14) secsig(3) algorithm(2) 26 }
|
||||
|
||||
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 }
|
||||
id-aes-192-cbc OBJECT IDENTIFIER ::= { id-nist-aes-algs 22 }
|
||||
id-aes-256-cbc OBJECT IDENTIFIER ::= { id-nist-aes-algs 42 }
|
||||
|
||||
id-nist-sha-algs OBJECT IDENTIFIER ::= { id-nistAlgorithm 2 }
|
||||
|
||||
id-sha256 OBJECT IDENTIFIER ::= { id-nist-sha-algs 1 }
|
||||
id-sha224 OBJECT IDENTIFIER ::= { id-nist-sha-algs 4 }
|
||||
id-sha384 OBJECT IDENTIFIER ::= { id-nist-sha-algs 2 }
|
||||
id-sha512 OBJECT IDENTIFIER ::= { id-nist-sha-algs 3 }
|
||||
|
||||
id-dhpublicnumber OBJECT IDENTIFIER ::= {
|
||||
iso(1) member-body(2) us(840) ansi-x942(10046)
|
||||
number-type(2) 1 }
|
||||
|
||||
id-x9-57 OBJECT IDENTIFIER ::= {
|
||||
iso(1) member-body(2) us(840) ansi-x942(10046)
|
||||
4 }
|
||||
|
||||
id-dsa OBJECT IDENTIFIER ::= { id-x9-57 1 }
|
||||
id-dsa-with-sha1 OBJECT IDENTIFIER ::= { id-x9-57 3 }
|
||||
|
||||
-- x.520 names types
|
||||
|
||||
id-x520-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 }
|
||||
|
||||
id-at-commonName OBJECT IDENTIFIER ::= { id-x520-at 3 }
|
||||
id-at-surname OBJECT IDENTIFIER ::= { id-x520-at 4 }
|
||||
id-at-serialNumber OBJECT IDENTIFIER ::= { id-x520-at 5 }
|
||||
id-at-countryName OBJECT IDENTIFIER ::= { id-x520-at 6 }
|
||||
id-at-localityName OBJECT IDENTIFIER ::= { id-x520-at 7 }
|
||||
id-at-stateOrProvinceName OBJECT IDENTIFIER ::= { id-x520-at 8 }
|
||||
id-at-organizationName OBJECT IDENTIFIER ::= { id-x520-at 10 }
|
||||
id-at-organizationalUnitName OBJECT IDENTIFIER ::= { id-x520-at 11 }
|
||||
id-at-name OBJECT IDENTIFIER ::= { id-x520-at 41 }
|
||||
id-at-givenName OBJECT IDENTIFIER ::= { id-x520-at 42 }
|
||||
id-at-initials OBJECT IDENTIFIER ::= { id-x520-at 43 }
|
||||
id-at-generationQualifier OBJECT IDENTIFIER ::= { id-x520-at 44 }
|
||||
id-at-pseudonym OBJECT IDENTIFIER ::= { id-x520-at 65 }
|
||||
-- RFC 2247
|
||||
id-Userid OBJECT IDENTIFIER ::=
|
||||
{ 0 9 2342 19200300 100 1 1 }
|
||||
id-domainComponent OBJECT IDENTIFIER ::=
|
||||
{ 0 9 2342 19200300 100 1 25 }
|
||||
|
||||
|
||||
-- rfc3280
|
||||
|
||||
id-x509-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
|
||||
|
||||
AlgorithmIdentifier ::= SEQUENCE {
|
||||
algorithm OBJECT IDENTIFIER,
|
||||
parameters heim_any OPTIONAL
|
||||
}
|
||||
|
||||
AttributeType ::= OBJECT IDENTIFIER
|
||||
|
||||
AttributeValue ::= heim_any
|
||||
|
||||
TeletexStringx ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
|
||||
|
||||
DirectoryString ::= CHOICE {
|
||||
ia5String IA5String,
|
||||
teletexString TeletexStringx,
|
||||
printableString PrintableString,
|
||||
universalString UniversalString,
|
||||
utf8String UTF8String,
|
||||
bmpString BMPString
|
||||
}
|
||||
|
||||
Attribute ::= SEQUENCE {
|
||||
type AttributeType,
|
||||
value SET OF -- AttributeValue -- heim_any
|
||||
}
|
||||
|
||||
AttributeTypeAndValue ::= SEQUENCE {
|
||||
type AttributeType,
|
||||
value DirectoryString
|
||||
}
|
||||
|
||||
RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
|
||||
|
||||
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
||||
|
||||
Name ::= CHOICE {
|
||||
rdnSequence RDNSequence
|
||||
}
|
||||
|
||||
CertificateSerialNumber ::= INTEGER
|
||||
|
||||
Time ::= CHOICE {
|
||||
utcTime UTCTime,
|
||||
generalTime GeneralizedTime
|
||||
}
|
||||
|
||||
Validity ::= SEQUENCE {
|
||||
notBefore Time,
|
||||
notAfter Time
|
||||
}
|
||||
|
||||
UniqueIdentifier ::= BIT STRING
|
||||
|
||||
SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
algorithm AlgorithmIdentifier,
|
||||
subjectPublicKey BIT STRING
|
||||
}
|
||||
|
||||
Extension ::= SEQUENCE {
|
||||
extnID OBJECT IDENTIFIER,
|
||||
critical BOOLEAN OPTIONAL, -- DEFAULT FALSE XXX
|
||||
extnValue OCTET STRING
|
||||
}
|
||||
|
||||
Extensions ::= SEQUENCE OF Extension -- SIZE (1..MAX)
|
||||
|
||||
TBSCertificate ::= SEQUENCE {
|
||||
version [0] Version OPTIONAL, -- EXPLICIT nnn DEFAULT 1,
|
||||
serialNumber CertificateSerialNumber,
|
||||
signature AlgorithmIdentifier,
|
||||
issuer Name,
|
||||
validity Validity,
|
||||
subject Name,
|
||||
subjectPublicKeyInfo SubjectPublicKeyInfo,
|
||||
issuerUniqueID [1] IMPLICIT BIT STRING -- UniqueIdentifier -- OPTIONAL,
|
||||
-- If present, version shall be v2 or v3
|
||||
subjectUniqueID [2] IMPLICIT BIT STRING -- UniqueIdentifier -- OPTIONAL,
|
||||
-- If present, version shall be v2 or v3
|
||||
extensions [3] EXPLICIT Extensions OPTIONAL
|
||||
-- If present, version shall be v3
|
||||
}
|
||||
|
||||
Certificate ::= SEQUENCE {
|
||||
tbsCertificate TBSCertificate,
|
||||
signatureAlgorithm AlgorithmIdentifier,
|
||||
signatureValue BIT STRING
|
||||
}
|
||||
|
||||
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, -- factor of p-1
|
||||
j INTEGER OPTIONAL, -- subgroup factor
|
||||
validationParms ValidationParms OPTIONAL -- ValidationParms
|
||||
}
|
||||
|
||||
DHPublicKey ::= INTEGER
|
||||
|
||||
OtherName ::= SEQUENCE {
|
||||
type-id OBJECT IDENTIFIER,
|
||||
value [0] EXPLICIT heim_any
|
||||
}
|
||||
|
||||
GeneralName ::= CHOICE {
|
||||
otherName [0] IMPLICIT -- OtherName -- SEQUENCE {
|
||||
type-id OBJECT IDENTIFIER,
|
||||
value [0] EXPLICIT heim_any
|
||||
},
|
||||
rfc822Name [1] IMPLICIT IA5String,
|
||||
dNSName [2] IMPLICIT IA5String,
|
||||
-- x400Address [3] IMPLICIT ORAddress,--
|
||||
directoryName [4] IMPLICIT -- Name -- CHOICE {
|
||||
rdnSequence RDNSequence
|
||||
},
|
||||
-- ediPartyName [5] IMPLICIT EDIPartyName, --
|
||||
uniformResourceIdentifier [6] IMPLICIT IA5String,
|
||||
iPAddress [7] IMPLICIT OCTET STRING,
|
||||
registeredID [8] IMPLICIT OBJECT IDENTIFIER
|
||||
}
|
||||
|
||||
GeneralNames ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralName
|
||||
|
||||
id-x509-ce-keyUsage OBJECT IDENTIFIER ::= { id-x509-ce 15 }
|
||||
|
||||
KeyUsage ::= BIT STRING {
|
||||
digitalSignature (0),
|
||||
nonRepudiation (1),
|
||||
keyEncipherment (2),
|
||||
dataEncipherment (3),
|
||||
keyAgreement (4),
|
||||
keyCertSign (5),
|
||||
cRLSign (6),
|
||||
encipherOnly (7),
|
||||
decipherOnly (8)
|
||||
}
|
||||
|
||||
id-x509-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-x509-ce 35 }
|
||||
|
||||
KeyIdentifier ::= OCTET STRING
|
||||
|
||||
AuthorityKeyIdentifier ::= SEQUENCE {
|
||||
keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL,
|
||||
authorityCertIssuer [1] IMPLICIT -- GeneralName --
|
||||
SEQUENCE -- SIZE (1..MAX) -- OF GeneralName OPTIONAL,
|
||||
authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL
|
||||
}
|
||||
|
||||
id-x509-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-x509-ce 14 }
|
||||
|
||||
SubjectKeyIdentifier ::= KeyIdentifier
|
||||
|
||||
id-x509-ce-basicConstraints OBJECT IDENTIFIER ::= { id-x509-ce 19 }
|
||||
|
||||
BasicConstraints ::= SEQUENCE {
|
||||
cA BOOLEAN OPTIONAL -- DEFAULT FALSE --,
|
||||
pathLenConstraint INTEGER (0..4294967295) OPTIONAL
|
||||
}
|
||||
|
||||
id-x509-ce-nameConstraints OBJECT IDENTIFIER ::= { id-x509-ce 30 }
|
||||
|
||||
BaseDistance ::= INTEGER -- (0..MAX) --
|
||||
|
||||
GeneralSubtree ::= SEQUENCE {
|
||||
base GeneralName,
|
||||
minimum [0] IMPLICIT -- BaseDistance -- INTEGER OPTIONAL -- DEFAULT 0 --,
|
||||
maximum [1] IMPLICIT -- BaseDistance -- INTEGER OPTIONAL
|
||||
}
|
||||
|
||||
GeneralSubtrees ::= SEQUENCE -- SIZE (1..MAX) -- OF GeneralSubtree
|
||||
|
||||
NameConstraints ::= SEQUENCE {
|
||||
permittedSubtrees [0] IMPLICIT -- GeneralSubtrees -- SEQUENCE OF GeneralSubtree OPTIONAL,
|
||||
excludedSubtrees [1] IMPLICIT -- GeneralSubtrees -- SEQUENCE OF GeneralSubtree OPTIONAL
|
||||
}
|
||||
|
||||
id-x509-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-x509-ce 16 }
|
||||
id-x509-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-x509-ce 32 }
|
||||
id-x509-ce-policyMappings OBJECT IDENTIFIER ::= { id-x509-ce 33 }
|
||||
id-x509-ce-subjectAltName OBJECT IDENTIFIER ::= { id-x509-ce 17 }
|
||||
id-x509-ce-issuerAltName OBJECT IDENTIFIER ::= { id-x509-ce 18 }
|
||||
id-x509-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-x509-ce 9 }
|
||||
id-x509-ce-policyConstraints OBJECT IDENTIFIER ::= { id-x509-ce 36 }
|
||||
|
||||
id-x509-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-x509-ce 37}
|
||||
|
||||
ExtKeyUsage ::= SEQUENCE OF OBJECT IDENTIFIER
|
||||
|
||||
id-x509-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-x509-ce 31 }
|
||||
id-x509-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-x509-ce 27 }
|
||||
id-x509-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-x509-ce 28 }
|
||||
id-x509-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-x509-ce 23 }
|
||||
id-x509-ce-invalidityDate OBJECT IDENTIFIER ::= { id-x509-ce 24 }
|
||||
id-x509-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-x509-ce 29 }
|
||||
id-x509-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-x509-ce 54 }
|
||||
|
||||
-- rfc3279
|
||||
|
||||
DSASigValue ::= SEQUENCE {
|
||||
r INTEGER,
|
||||
s INTEGER
|
||||
}
|
||||
|
||||
DSAPublicKey ::= INTEGER
|
||||
|
||||
DSAParams ::= SEQUENCE {
|
||||
p INTEGER,
|
||||
q INTEGER,
|
||||
g INTEGER
|
||||
}
|
||||
|
||||
-- really pkcs1
|
||||
|
||||
RSAPublicKey ::= SEQUENCE {
|
||||
modulus INTEGER, -- n
|
||||
publicExponent INTEGER -- e
|
||||
}
|
||||
|
||||
RSAPrivateKey ::= SEQUENCE {
|
||||
version INTEGER (0..4294967295),
|
||||
modulus INTEGER, -- n
|
||||
publicExponent INTEGER, -- e
|
||||
privateExponent INTEGER, -- d
|
||||
prime1 INTEGER, -- p
|
||||
prime2 INTEGER, -- q
|
||||
exponent1 INTEGER, -- d mod (p-1)
|
||||
exponent2 INTEGER, -- d mod (q-1)
|
||||
coefficient INTEGER -- (inverse of q) mod p
|
||||
}
|
||||
|
||||
DigestInfo ::= SEQUENCE {
|
||||
digestAlgorithm AlgorithmIdentifier,
|
||||
digest OCTET STRING
|
||||
}
|
||||
|
||||
-- some ms ext
|
||||
|
||||
-- szOID_ENROLL_CERTTYPE_EXTENSION "1.3.6.1.4.1.311.20.2" is Encoded as a
|
||||
|
||||
-- UNICODESTRING (0x1E tag)
|
||||
|
||||
-- szOID_CERTIFICATE_TEMPLATE "1.3.6.1.4.1.311.21.7" is Encoded as:
|
||||
|
||||
-- TemplateVersion ::= INTEGER (0..4294967295)
|
||||
|
||||
-- CertificateTemplate ::= SEQUENCE {
|
||||
-- templateID OBJECT IDENTIFIER,
|
||||
-- templateMajorVersion TemplateVersion,
|
||||
-- templateMinorVersion TemplateVersion OPTIONAL
|
||||
-- }
|
||||
|
||||
|
||||
--
|
||||
-- CRL
|
||||
--
|
||||
|
||||
TBSCRLCertList ::= SEQUENCE {
|
||||
version Version OPTIONAL, -- if present, MUST be v2
|
||||
signature AlgorithmIdentifier,
|
||||
issuer Name,
|
||||
thisUpdate Time,
|
||||
nextUpdate Time OPTIONAL,
|
||||
revokedCertificates SEQUENCE OF SEQUENCE {
|
||||
userCertificate CertificateSerialNumber,
|
||||
revocationDate Time,
|
||||
crlEntryExtensions Extensions OPTIONAL
|
||||
-- if present, MUST be v2
|
||||
} OPTIONAL,
|
||||
crlExtensions [0] EXPLICIT Extensions OPTIONAL
|
||||
-- if present, MUST be v2
|
||||
}
|
||||
|
||||
|
||||
CRLCertificateList ::= SEQUENCE {
|
||||
tbsCertList TBSCRLCertList,
|
||||
signatureAlgorithm AlgorithmIdentifier,
|
||||
signatureValue BIT STRING
|
||||
}
|
||||
|
||||
id-x509-ce-cRLNumber OBJECT IDENTIFIER ::= { id-x509-ce 20 }
|
||||
id-x509-ce-freshestCRL OBJECT IDENTIFIER ::= { id-x509-ce 46 }
|
||||
id-x509-ce-cRLReason OBJECT IDENTIFIER ::= { id-x509-ce 21 }
|
||||
|
||||
CRLReason ::= ENUMERATED {
|
||||
unspecified (0),
|
||||
keyCompromise (1),
|
||||
cACompromise (2),
|
||||
affiliationChanged (3),
|
||||
superseded (4),
|
||||
cessationOfOperation (5),
|
||||
certificateHold (6),
|
||||
removeFromCRL (8),
|
||||
privilegeWithdrawn (9),
|
||||
aACompromise (10)
|
||||
}
|
||||
|
||||
-- RFC 3820 Proxy Certificate Profile
|
||||
|
||||
id-pkix-pe OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
|
||||
dod(6) internet(1) security(5) mechanisms(5) pkix(7) 1 }
|
||||
|
||||
id-pe-proxyCertInfo OBJECT IDENTIFIER ::= { id-pkix-pe 14 }
|
||||
|
||||
ProxyPolicy ::= SEQUENCE {
|
||||
policyLanguage OBJECT IDENTIFIER,
|
||||
policy OCTET STRING OPTIONAL
|
||||
}
|
||||
|
||||
ProxyCertInfo ::= SEQUENCE {
|
||||
pCPathLenConstraint INTEGER (0..4294967295) OPTIONAL, -- really MAX
|
||||
proxyPolicy ProxyPolicy
|
||||
}
|
||||
|
||||
END
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gen_locl.h"
|
||||
#include "lex.h"
|
||||
|
||||
RCSID("$Id: symbol.c,v 1.10 2005/07/12 06:27:39 lha Exp $");
|
||||
|
||||
static Hashtab *htab;
|
||||
|
||||
static int
|
||||
cmp(void *a, void *b)
|
||||
{
|
||||
Symbol *s1 = (Symbol *) a;
|
||||
Symbol *s2 = (Symbol *) b;
|
||||
|
||||
return strcmp(s1->name, s2->name);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
hash(void *a)
|
||||
{
|
||||
Symbol *s = (Symbol *) a;
|
||||
|
||||
return hashjpw(s->name);
|
||||
}
|
||||
|
||||
void
|
||||
initsym(void)
|
||||
{
|
||||
htab = hashtabnew(101, cmp, hash);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
output_name(char *s)
|
||||
{
|
||||
char *p;
|
||||
|
||||
for (p = s; *p; ++p)
|
||||
if (*p == '-')
|
||||
*p = '_';
|
||||
}
|
||||
|
||||
Symbol *
|
||||
addsym(char *name)
|
||||
{
|
||||
Symbol key, *s;
|
||||
|
||||
key.name = name;
|
||||
s = (Symbol *) hashtabsearch(htab, (void *) &key);
|
||||
if (s == NULL) {
|
||||
s = (Symbol *) emalloc(sizeof(*s));
|
||||
s->name = name;
|
||||
s->gen_name = estrdup(name);
|
||||
output_name(s->gen_name);
|
||||
s->stype = SUndefined;
|
||||
hashtabadd(htab, s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static int
|
||||
checkfunc(void *ptr, void *arg)
|
||||
{
|
||||
Symbol *s = ptr;
|
||||
if (s->stype == SUndefined) {
|
||||
error_message("%s is still undefined\n", s->name);
|
||||
*(int *) arg = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
checkundefined(void)
|
||||
{
|
||||
int f = 0;
|
||||
hashtabforeach(htab, checkfunc, &f);
|
||||
return f;
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id: symbol.h,v 1.13 2005/12/06 19:59:52 lha Exp $ */
|
||||
|
||||
#ifndef _SYMBOL_H
|
||||
#define _SYMBOL_H
|
||||
|
||||
#include "asn1_queue.h"
|
||||
|
||||
enum typetype {
|
||||
TBitString,
|
||||
TBoolean,
|
||||
TChoice,
|
||||
TEnumerated,
|
||||
TGeneralString,
|
||||
TGeneralizedTime,
|
||||
TIA5String,
|
||||
TInteger,
|
||||
TNull,
|
||||
TOID,
|
||||
TOctetString,
|
||||
TPrintableString,
|
||||
TSequence,
|
||||
TSequenceOf,
|
||||
TSet,
|
||||
TSetOf,
|
||||
TTag,
|
||||
TType,
|
||||
TUTCTime,
|
||||
TUTF8String,
|
||||
TBMPString,
|
||||
TUniversalString
|
||||
};
|
||||
|
||||
typedef enum typetype Typetype;
|
||||
|
||||
struct type;
|
||||
|
||||
struct value {
|
||||
enum { booleanvalue,
|
||||
nullvalue,
|
||||
integervalue,
|
||||
stringvalue,
|
||||
objectidentifiervalue
|
||||
} type;
|
||||
union {
|
||||
int booleanvalue;
|
||||
int integervalue;
|
||||
char *stringvalue;
|
||||
struct objid *objectidentifiervalue;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct member {
|
||||
char *name;
|
||||
char *gen_name;
|
||||
char *label;
|
||||
int val;
|
||||
int optional;
|
||||
int ellipsis;
|
||||
struct type *type;
|
||||
ASN1_TAILQ_ENTRY(member) members;
|
||||
struct value *defval;
|
||||
};
|
||||
|
||||
typedef struct member Member;
|
||||
|
||||
ASN1_TAILQ_HEAD(memhead, member);
|
||||
|
||||
struct symbol;
|
||||
|
||||
struct tagtype {
|
||||
int tagclass;
|
||||
int tagvalue;
|
||||
enum { TE_IMPLICIT, TE_EXPLICIT } tagenv;
|
||||
};
|
||||
|
||||
struct range {
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
enum ctype { CT_CONTENTS, CT_USER } ;
|
||||
|
||||
struct constraint_spec;
|
||||
|
||||
struct type {
|
||||
Typetype type;
|
||||
struct memhead *members;
|
||||
struct symbol *symbol;
|
||||
struct type *subtype;
|
||||
struct tagtype tag;
|
||||
struct range *range;
|
||||
struct constraint_spec *constraint;
|
||||
};
|
||||
|
||||
typedef struct type Type;
|
||||
|
||||
struct constraint_spec {
|
||||
enum ctype ctype;
|
||||
union {
|
||||
struct {
|
||||
Type *type;
|
||||
struct value *encoding;
|
||||
} content;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct objid {
|
||||
const char *label;
|
||||
int value;
|
||||
struct objid *next;
|
||||
};
|
||||
|
||||
struct symbol {
|
||||
char *name;
|
||||
char *gen_name;
|
||||
enum { SUndefined, SValue, Stype } stype;
|
||||
struct value *value;
|
||||
Type *type;
|
||||
};
|
||||
|
||||
typedef struct symbol Symbol;
|
||||
|
||||
void initsym (void);
|
||||
Symbol *addsym (char *);
|
||||
void output_name (char *);
|
||||
int checkundefined(void);
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
-- $Id: test.asn1,v 1.9 2006/09/05 14:00:44 lha Exp $ --
|
||||
|
||||
TEST DEFINITIONS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
IMPORTS heim_any FROM heim;
|
||||
|
||||
TESTLargeTag ::= SEQUENCE {
|
||||
foo[127] INTEGER (-2147483648..2147483647)
|
||||
}
|
||||
|
||||
TESTSeq ::= SEQUENCE {
|
||||
tag0[0] INTEGER (-2147483648..2147483647),
|
||||
tag1[1] TESTLargeTag,
|
||||
tagless INTEGER (-2147483648..2147483647),
|
||||
tag3[2] INTEGER (-2147483648..2147483647)
|
||||
}
|
||||
|
||||
TESTChoice1 ::= CHOICE {
|
||||
i1[1] INTEGER (-2147483648..2147483647),
|
||||
i2[2] INTEGER (-2147483648..2147483647),
|
||||
...
|
||||
}
|
||||
|
||||
TESTChoice2 ::= CHOICE {
|
||||
i1[1] INTEGER (-2147483648..2147483647),
|
||||
...
|
||||
}
|
||||
|
||||
TESTInteger ::= INTEGER (-2147483648..2147483647)
|
||||
|
||||
TESTInteger2 ::= [4] IMPLICIT TESTInteger
|
||||
TESTInteger3 ::= [5] IMPLICIT TESTInteger2
|
||||
|
||||
TESTImplicit ::= SEQUENCE {
|
||||
ti1[0] IMPLICIT INTEGER (-2147483648..2147483647),
|
||||
ti2[1] IMPLICIT SEQUENCE {
|
||||
foo[127] INTEGER (-2147483648..2147483647)
|
||||
},
|
||||
ti3[2] IMPLICIT [5] IMPLICIT [4] IMPLICIT INTEGER (-2147483648..2147483647)
|
||||
}
|
||||
|
||||
TESTImplicit2 ::= SEQUENCE {
|
||||
ti1[0] IMPLICIT TESTInteger,
|
||||
ti2[1] IMPLICIT TESTLargeTag,
|
||||
ti3[2] IMPLICIT TESTInteger3
|
||||
}
|
||||
|
||||
TESTAllocInner ::= SEQUENCE {
|
||||
ai[0] TESTInteger
|
||||
}
|
||||
|
||||
TESTAlloc ::= SEQUENCE {
|
||||
tagless TESTAllocInner OPTIONAL,
|
||||
three [1] INTEGER (-2147483648..2147483647),
|
||||
tagless2 heim_any OPTIONAL
|
||||
}
|
||||
|
||||
|
||||
TESTCONTAINING ::= OCTET STRING ( CONTAINING INTEGER )
|
||||
TESTENCODEDBY ::= OCTET STRING ( ENCODED BY
|
||||
{ joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
|
||||
)
|
||||
|
||||
TESTDer OBJECT IDENTIFIER ::= {
|
||||
joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1)
|
||||
}
|
||||
|
||||
TESTCONTAININGENCODEDBY ::= OCTET STRING ( CONTAINING INTEGER ENCODED BY
|
||||
{ joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
|
||||
)
|
||||
|
||||
TESTCONTAININGENCODEDBY2 ::= OCTET STRING (
|
||||
CONTAINING INTEGER ENCODED BY TESTDer
|
||||
)
|
||||
|
||||
|
||||
TESTValue1 INTEGER ::= 1
|
||||
|
||||
TESTUSERCONSTRAINED ::= OCTET STRING (CONSTRAINED BY { -- meh -- })
|
||||
-- TESTUSERCONSTRAINED2 ::= OCTET STRING (CONSTRAINED BY { TESTInteger })
|
||||
-- TESTUSERCONSTRAINED3 ::= OCTET STRING (CONSTRAINED BY { INTEGER })
|
||||
-- TESTUSERCONSTRAINED4 ::= OCTET STRING (CONSTRAINED BY { INTEGER : 1 })
|
||||
|
||||
TESTSeqOf ::= SEQUENCE OF TESTInteger
|
||||
|
||||
END
|
||||
@@ -0,0 +1,14 @@
|
||||
# $Id: test.gen,v 1.2 2005/07/12 06:27:41 lha Exp $
|
||||
# Sample for TESTSeq in test.asn1
|
||||
#
|
||||
|
||||
UNIV CONS Sequence 23
|
||||
CONTEXT CONS 0 3
|
||||
UNIV PRIM Integer 1 01
|
||||
CONTEXT CONS 1 8
|
||||
UNIV CONS Sequence 6
|
||||
CONTEXT CONS 127 3
|
||||
UNIV PRIM Integer 1 01
|
||||
UNIV PRIM Integer 1 01
|
||||
CONTEXT CONS 2 3
|
||||
UNIV PRIM Integer 1 01
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 1997 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "der_locl.h"
|
||||
|
||||
RCSID("$Id: timegm.c,v 1.11 2006/10/19 16:19:32 lha Exp $");
|
||||
|
||||
static int
|
||||
is_leap(unsigned y)
|
||||
{
|
||||
y += 1900;
|
||||
return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a simplifed version of _der_timegm that doesn't accept out
|
||||
* of bound values that timegm(3) normally accepts but those are not
|
||||
* valid in asn1 encodings.
|
||||
*/
|
||||
|
||||
time_t
|
||||
_der_timegm (struct tm *tm)
|
||||
{
|
||||
static const unsigned ndays[2][12] ={
|
||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
||||
time_t res = 0;
|
||||
unsigned i;
|
||||
|
||||
if (tm->tm_year < 0)
|
||||
return -1;
|
||||
if (tm->tm_mon < 0 || tm->tm_mon > 11)
|
||||
return -1;
|
||||
if (tm->tm_mday < 1 || tm->tm_mday > ndays[is_leap(tm->tm_year)][tm->tm_mon])
|
||||
return -1;
|
||||
if (tm->tm_hour < 0 || tm->tm_hour > 23)
|
||||
return -1;
|
||||
if (tm->tm_min < 0 || tm->tm_min > 59)
|
||||
return -1;
|
||||
if (tm->tm_sec < 0 || tm->tm_sec > 59)
|
||||
return -1;
|
||||
|
||||
for (i = 70; i < tm->tm_year; ++i)
|
||||
res += is_leap(i) ? 366 : 365;
|
||||
|
||||
for (i = 0; i < tm->tm_mon; ++i)
|
||||
res += ndays[is_leap(tm->tm_year)][i];
|
||||
res += tm->tm_mday - 1;
|
||||
res *= 24;
|
||||
res += tm->tm_hour;
|
||||
res *= 60;
|
||||
res += tm->tm_min;
|
||||
res *= 60;
|
||||
res += tm->tm_sec;
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2002 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: com_err.c,v 1.19 2005/04/24 19:42:39 lha Exp $");
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <roken.h>
|
||||
#include "com_err.h"
|
||||
|
||||
struct et_list *_et_list = NULL;
|
||||
|
||||
|
||||
const char *
|
||||
error_message (long code)
|
||||
{
|
||||
static char msg[128];
|
||||
const char *p = com_right(_et_list, code);
|
||||
if (p == NULL) {
|
||||
if (code < 0)
|
||||
snprintf(msg, sizeof(msg), "Unknown error %ld", code);
|
||||
else
|
||||
p = strerror(code);
|
||||
}
|
||||
if (p != NULL && *p != '\0') {
|
||||
strlcpy(msg, p, sizeof(msg));
|
||||
} else
|
||||
snprintf(msg, sizeof(msg), "Unknown error %ld", code);
|
||||
return msg;
|
||||
}
|
||||
|
||||
int
|
||||
init_error_table(const char **msgs, long base, int count)
|
||||
{
|
||||
initialize_error_table_r(&_et_list, msgs, count, base);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
default_proc (const char *whoami, long code, const char *fmt, va_list args)
|
||||
__attribute__((__format__(__printf__, 3, 0)));
|
||||
|
||||
static void
|
||||
default_proc (const char *whoami, long code, const char *fmt, va_list args)
|
||||
{
|
||||
if (whoami)
|
||||
fprintf(stderr, "%s: ", whoami);
|
||||
if (code)
|
||||
fprintf(stderr, "%s ", error_message(code));
|
||||
if (fmt)
|
||||
vfprintf(stderr, fmt, args);
|
||||
fprintf(stderr, "\r\n"); /* ??? */
|
||||
}
|
||||
|
||||
static errf com_err_hook = default_proc;
|
||||
|
||||
void
|
||||
com_err_va (const char *whoami,
|
||||
long code,
|
||||
const char *fmt,
|
||||
va_list args)
|
||||
{
|
||||
(*com_err_hook) (whoami, code, fmt, args);
|
||||
}
|
||||
|
||||
void
|
||||
com_err (const char *whoami,
|
||||
long code,
|
||||
const char *fmt,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
com_err_va (whoami, code, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
errf
|
||||
set_com_err_hook (errf new)
|
||||
{
|
||||
errf old = com_err_hook;
|
||||
|
||||
if (new)
|
||||
com_err_hook = new;
|
||||
else
|
||||
com_err_hook = default_proc;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
errf
|
||||
reset_com_err_hook (void)
|
||||
{
|
||||
return set_com_err_hook(NULL);
|
||||
}
|
||||
|
||||
#define ERRCODE_RANGE 8 /* # of bits to shift table number */
|
||||
#define BITS_PER_CHAR 6 /* # bits to shift per character in name */
|
||||
|
||||
static const char char_set[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
|
||||
|
||||
static char buf[6];
|
||||
|
||||
const char *
|
||||
error_table_name(int num)
|
||||
{
|
||||
int ch;
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
/* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
|
||||
p = buf;
|
||||
num >>= ERRCODE_RANGE;
|
||||
/* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
|
||||
num &= 077777777;
|
||||
/* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
|
||||
for (i = 4; i >= 0; i--) {
|
||||
ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1);
|
||||
if (ch != 0)
|
||||
*p++ = char_set[ch-1];
|
||||
}
|
||||
*p = '\0';
|
||||
return(buf);
|
||||
}
|
||||
|
||||
void
|
||||
add_to_error_table(struct et_list *new_table)
|
||||
{
|
||||
struct et_list *et;
|
||||
|
||||
for (et = _et_list; et; et = et->next) {
|
||||
if (et->table->base == new_table->table->base)
|
||||
return;
|
||||
}
|
||||
|
||||
new_table->next = _et_list;
|
||||
_et_list = new_table;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id: com_err.h,v 1.11 2005/07/07 14:58:07 lha Exp $ */
|
||||
|
||||
/* MIT compatible com_err library */
|
||||
|
||||
#ifndef __COM_ERR_H__
|
||||
#define __COM_ERR_H__
|
||||
|
||||
#include <com_right.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined(__GNUC__) && !defined(__attribute__)
|
||||
#define __attribute__(X)
|
||||
#endif
|
||||
|
||||
typedef void (*errf) (const char *, long, const char *, va_list);
|
||||
|
||||
const char * error_message (long);
|
||||
int init_error_table (const char**, long, int);
|
||||
|
||||
void com_err_va (const char *, long, const char *, va_list)
|
||||
__attribute__((format(printf, 3, 0)));
|
||||
|
||||
void com_err (const char *, long, const char *, ...)
|
||||
__attribute__((format(printf, 3, 4)));
|
||||
|
||||
errf set_com_err_hook (errf);
|
||||
errf reset_com_err_hook (void);
|
||||
|
||||
const char *error_table_name (int num);
|
||||
|
||||
void add_to_error_table (struct et_list *new_table);
|
||||
|
||||
#endif /* __COM_ERR_H__ */
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2000 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: com_right.h,v 1.12 2005/02/03 08:43:01 lha Exp $ */
|
||||
|
||||
#ifndef __COM_RIGHT_H__
|
||||
#define __COM_RIGHT_H__
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <stdarg.h>
|
||||
#endif
|
||||
|
||||
struct error_table {
|
||||
char const * const * msgs;
|
||||
long base;
|
||||
int n_msgs;
|
||||
};
|
||||
struct et_list {
|
||||
struct et_list *next;
|
||||
struct error_table *table;
|
||||
};
|
||||
extern struct et_list *_et_list;
|
||||
|
||||
const char *com_right (struct et_list *list, long code);
|
||||
void initialize_error_table_r (struct et_list **, const char **, int, long);
|
||||
void free_error_table (struct et_list *);
|
||||
|
||||
#endif /* __COM_RIGHT_H__ */
|
||||
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2002 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.
|
||||
*/
|
||||
|
||||
#undef ROKEN_RENAME
|
||||
#include "compile_et.h"
|
||||
#include <getarg.h>
|
||||
|
||||
RCSID("$Id: compile_et.c,v 1.19 2005/06/16 19:21:00 lha Exp $");
|
||||
|
||||
#include <roken.h>
|
||||
#include <err.h>
|
||||
#include "parse.h"
|
||||
|
||||
int numerror;
|
||||
extern FILE *yyin;
|
||||
|
||||
extern void yyparse(void);
|
||||
|
||||
long base_id;
|
||||
int number;
|
||||
char *prefix;
|
||||
char *id_str;
|
||||
|
||||
char name[128];
|
||||
char Basename[128];
|
||||
|
||||
#ifdef YYDEBUG
|
||||
extern int yydebug = 1;
|
||||
#endif
|
||||
|
||||
char *filename;
|
||||
char hfn[128];
|
||||
char cfn[128];
|
||||
|
||||
struct error_code *codes = NULL;
|
||||
|
||||
static int
|
||||
generate_c(void)
|
||||
{
|
||||
int n;
|
||||
struct error_code *ec;
|
||||
|
||||
FILE *c_file = fopen(cfn, "w");
|
||||
if(c_file == NULL)
|
||||
return 1;
|
||||
|
||||
fprintf(c_file, "/* Generated from %s */\n", filename);
|
||||
if(id_str)
|
||||
fprintf(c_file, "/* %s */\n", id_str);
|
||||
fprintf(c_file, "\n");
|
||||
fprintf(c_file, "#include <stddef.h>\n");
|
||||
fprintf(c_file, "#include <com_err.h>\n");
|
||||
fprintf(c_file, "#include \"%s\"\n", hfn);
|
||||
fprintf(c_file, "\n");
|
||||
|
||||
fprintf(c_file, "static const char *%s_error_strings[] = {\n", name);
|
||||
|
||||
for(ec = codes, n = 0; ec; ec = ec->next, n++) {
|
||||
while(n < ec->number) {
|
||||
fprintf(c_file, "\t/* %03d */ \"Reserved %s error (%d)\",\n",
|
||||
n, name, n);
|
||||
n++;
|
||||
|
||||
}
|
||||
fprintf(c_file, "\t/* %03d */ \"%s\",\n", ec->number, ec->string);
|
||||
}
|
||||
|
||||
fprintf(c_file, "\tNULL\n");
|
||||
fprintf(c_file, "};\n");
|
||||
fprintf(c_file, "\n");
|
||||
fprintf(c_file, "#define num_errors %d\n", number);
|
||||
fprintf(c_file, "\n");
|
||||
fprintf(c_file,
|
||||
"void initialize_%s_error_table_r(struct et_list **list)\n",
|
||||
name);
|
||||
fprintf(c_file, "{\n");
|
||||
fprintf(c_file,
|
||||
" initialize_error_table_r(list, %s_error_strings, "
|
||||
"num_errors, ERROR_TABLE_BASE_%s);\n", name, name);
|
||||
fprintf(c_file, "}\n");
|
||||
fprintf(c_file, "\n");
|
||||
fprintf(c_file, "void initialize_%s_error_table(void)\n", name);
|
||||
fprintf(c_file, "{\n");
|
||||
fprintf(c_file,
|
||||
" init_error_table(%s_error_strings, ERROR_TABLE_BASE_%s, "
|
||||
"num_errors);\n", name, name);
|
||||
fprintf(c_file, "}\n");
|
||||
|
||||
fclose(c_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
generate_h(void)
|
||||
{
|
||||
struct error_code *ec;
|
||||
char fn[128];
|
||||
FILE *h_file = fopen(hfn, "w");
|
||||
char *p;
|
||||
|
||||
if(h_file == NULL)
|
||||
return 1;
|
||||
|
||||
snprintf(fn, sizeof(fn), "__%s__", hfn);
|
||||
for(p = fn; *p; p++)
|
||||
if(!isalnum((unsigned char)*p))
|
||||
*p = '_';
|
||||
|
||||
fprintf(h_file, "/* Generated from %s */\n", filename);
|
||||
if(id_str)
|
||||
fprintf(h_file, "/* %s */\n", id_str);
|
||||
fprintf(h_file, "\n");
|
||||
fprintf(h_file, "#ifndef %s\n", fn);
|
||||
fprintf(h_file, "#define %s\n", fn);
|
||||
fprintf(h_file, "\n");
|
||||
fprintf(h_file, "struct et_list;\n");
|
||||
fprintf(h_file, "\n");
|
||||
fprintf(h_file,
|
||||
"void initialize_%s_error_table_r(struct et_list **);\n",
|
||||
name);
|
||||
fprintf(h_file, "\n");
|
||||
fprintf(h_file, "void initialize_%s_error_table(void);\n", name);
|
||||
fprintf(h_file, "#define init_%s_err_tbl initialize_%s_error_table\n",
|
||||
name, name);
|
||||
fprintf(h_file, "\n");
|
||||
fprintf(h_file, "typedef enum %s_error_number{\n", name);
|
||||
|
||||
for(ec = codes; ec; ec = ec->next) {
|
||||
fprintf(h_file, "\t%s = %ld%s\n", ec->name, base_id + ec->number,
|
||||
(ec->next != NULL) ? "," : "");
|
||||
}
|
||||
|
||||
fprintf(h_file, "} %s_error_number;\n", name);
|
||||
fprintf(h_file, "\n");
|
||||
fprintf(h_file, "#define ERROR_TABLE_BASE_%s %ld\n", name, base_id);
|
||||
fprintf(h_file, "\n");
|
||||
fprintf(h_file, "#endif /* %s */\n", fn);
|
||||
|
||||
|
||||
fclose(h_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
generate(void)
|
||||
{
|
||||
return generate_c() || generate_h();
|
||||
}
|
||||
|
||||
int version_flag;
|
||||
int help_flag;
|
||||
struct getargs args[] = {
|
||||
{ "version", 0, arg_flag, &version_flag },
|
||||
{ "help", 0, arg_flag, &help_flag }
|
||||
};
|
||||
int num_args = sizeof(args) / sizeof(args[0]);
|
||||
|
||||
static void
|
||||
usage(int code)
|
||||
{
|
||||
arg_printusage(args, num_args, NULL, "error-table");
|
||||
exit(code);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *p;
|
||||
int 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);
|
||||
}
|
||||
|
||||
if(optidx == argc)
|
||||
usage(1);
|
||||
filename = argv[optidx];
|
||||
yyin = fopen(filename, "r");
|
||||
if(yyin == NULL)
|
||||
err(1, "%s", filename);
|
||||
|
||||
|
||||
p = strrchr(filename, '/');
|
||||
if(p)
|
||||
p++;
|
||||
else
|
||||
p = filename;
|
||||
strlcpy(Basename, p, sizeof(Basename));
|
||||
|
||||
Basename[strcspn(Basename, ".")] = '\0';
|
||||
|
||||
snprintf(hfn, sizeof(hfn), "%s.h", Basename);
|
||||
snprintf(cfn, sizeof(cfn), "%s.c", Basename);
|
||||
|
||||
yyparse();
|
||||
if(numerror)
|
||||
return 1;
|
||||
|
||||
return generate();
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 1998 - 2000 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: compile_et.h,v 1.8 2005/06/16 19:21:26 lha Exp $ */
|
||||
|
||||
#ifndef __COMPILE_ET_H__
|
||||
#define __COMPILE_ET_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <roken.h>
|
||||
|
||||
extern long base_id;
|
||||
extern int number;
|
||||
extern char *prefix;
|
||||
extern char name[128];
|
||||
extern char *id_str;
|
||||
extern char *filename;
|
||||
extern int numerror;
|
||||
|
||||
struct error_code {
|
||||
unsigned number;
|
||||
char *name;
|
||||
char *string;
|
||||
struct error_code *next, **tail;
|
||||
};
|
||||
|
||||
extern struct error_code *codes;
|
||||
|
||||
#define APPEND(L, V) \
|
||||
do { \
|
||||
if((L) == NULL) { \
|
||||
(L) = (V); \
|
||||
(L)->tail = &(V)->next; \
|
||||
(L)->next = NULL; \
|
||||
}else{ \
|
||||
*(L)->tail = (V); \
|
||||
(L)->tail = &(V)->next; \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
#endif /* __COMPILE_ET_H__ */
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 2001 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
RCSID("$Id: error.c,v 1.15 2001/02/28 20:00:13 joda Exp $");
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <com_right.h>
|
||||
|
||||
const char *
|
||||
com_right(struct et_list *list, long code)
|
||||
{
|
||||
struct et_list *p;
|
||||
for (p = list; p; p = p->next) {
|
||||
if (code >= p->table->base && code < p->table->base + p->table->n_msgs)
|
||||
return p->table->msgs[code - p->table->base];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct foobar {
|
||||
struct et_list etl;
|
||||
struct error_table et;
|
||||
};
|
||||
|
||||
void
|
||||
initialize_error_table_r(struct et_list **list,
|
||||
const char **messages,
|
||||
int num_errors,
|
||||
long base)
|
||||
{
|
||||
struct et_list *et, **end;
|
||||
struct foobar *f;
|
||||
for (end = list, et = *list; et; end = &et->next, et = et->next)
|
||||
if (et->table->msgs == messages)
|
||||
return;
|
||||
f = malloc(sizeof(*f));
|
||||
if (f == NULL)
|
||||
return;
|
||||
et = &f->etl;
|
||||
et->table = &f->et;
|
||||
et->table->msgs = messages;
|
||||
et->table->n_msgs = num_errors;
|
||||
et->table->base = base;
|
||||
et->next = NULL;
|
||||
*end = et;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
free_error_table(struct et_list *et)
|
||||
{
|
||||
while(et){
|
||||
struct et_list *p = et;
|
||||
et = et->next;
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 1997 - 2000 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: lex.h,v 1.1 2000/06/22 00:42:52 assar Exp $ */
|
||||
|
||||
void error_message (const char *, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
int yylex(void);
|
||||
@@ -0,0 +1,128 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1998 - 2000 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is to handle the definition of this symbol in some AIX
|
||||
* headers, which will conflict with the definition that lex will
|
||||
* generate for it. It's only a problem for AIX lex.
|
||||
*/
|
||||
|
||||
#undef ECHO
|
||||
|
||||
#include "compile_et.h"
|
||||
#include "parse.h"
|
||||
#include "lex.h"
|
||||
|
||||
RCSID("$Id: lex.l,v 1.8 2005/05/16 08:52:54 lha Exp $");
|
||||
|
||||
static unsigned lineno = 1;
|
||||
static int getstring(void);
|
||||
|
||||
#define YY_NO_UNPUT
|
||||
|
||||
#undef ECHO
|
||||
|
||||
%}
|
||||
|
||||
|
||||
%%
|
||||
et { return ET; }
|
||||
error_table { return ET; }
|
||||
ec { return EC; }
|
||||
error_code { return EC; }
|
||||
prefix { return PREFIX; }
|
||||
index { return INDEX; }
|
||||
id { return ID; }
|
||||
end { return END; }
|
||||
[0-9]+ { yylval.number = atoi(yytext); return NUMBER; }
|
||||
#[^\n]* ;
|
||||
[ \t] ;
|
||||
\n { lineno++; }
|
||||
\" { return getstring(); }
|
||||
[a-zA-Z0-9_]+ { yylval.string = strdup(yytext); return STRING; }
|
||||
. { return *yytext; }
|
||||
%%
|
||||
|
||||
#ifndef yywrap /* XXX */
|
||||
int
|
||||
yywrap ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
getstring(void)
|
||||
{
|
||||
char x[128];
|
||||
int i = 0;
|
||||
int c;
|
||||
int quote = 0;
|
||||
while(i < sizeof(x) - 1 && (c = input()) != EOF){
|
||||
if(quote) {
|
||||
x[i++] = c;
|
||||
quote = 0;
|
||||
continue;
|
||||
}
|
||||
if(c == '\n'){
|
||||
error_message("unterminated string");
|
||||
lineno++;
|
||||
break;
|
||||
}
|
||||
if(c == '\\'){
|
||||
quote++;
|
||||
continue;
|
||||
}
|
||||
if(c == '\"')
|
||||
break;
|
||||
x[i++] = c;
|
||||
}
|
||||
x[i] = '\0';
|
||||
yylval.string = strdup(x);
|
||||
if (yylval.string == NULL)
|
||||
err(1, "malloc");
|
||||
return STRING;
|
||||
}
|
||||
|
||||
void
|
||||
error_message (const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
fprintf (stderr, "%s:%d:", filename, lineno);
|
||||
vfprintf (stderr, format, args);
|
||||
va_end (args);
|
||||
numerror++;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,15 @@
|
||||
typedef union {
|
||||
char *string;
|
||||
int number;
|
||||
} YYSTYPE;
|
||||
#define ET 257
|
||||
#define INDEX 258
|
||||
#define PREFIX 259
|
||||
#define EC 260
|
||||
#define ID 261
|
||||
#define END 262
|
||||
#define STRING 263
|
||||
#define NUMBER 264
|
||||
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
@@ -0,0 +1,173 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1998 - 2000 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 "compile_et.h"
|
||||
#include "lex.h"
|
||||
|
||||
RCSID("$Id: parse.y,v 1.15 2005/06/16 19:21:42 lha Exp $");
|
||||
|
||||
void yyerror (char *s);
|
||||
static long name2number(const char *str);
|
||||
|
||||
extern char *yytext;
|
||||
|
||||
/* This is for bison */
|
||||
|
||||
#if !defined(alloca) && !defined(HAVE_ALLOCA)
|
||||
#define alloca(x) malloc(x)
|
||||
#endif
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char *string;
|
||||
int number;
|
||||
}
|
||||
|
||||
%token ET INDEX PREFIX EC ID END
|
||||
%token <string> STRING
|
||||
%token <number> NUMBER
|
||||
|
||||
%%
|
||||
|
||||
file : /* */
|
||||
| header statements
|
||||
;
|
||||
|
||||
header : id et
|
||||
| et
|
||||
;
|
||||
|
||||
id : ID STRING
|
||||
{
|
||||
id_str = $2;
|
||||
}
|
||||
;
|
||||
|
||||
et : ET STRING
|
||||
{
|
||||
base_id = name2number($2);
|
||||
strlcpy(name, $2, sizeof(name));
|
||||
free($2);
|
||||
}
|
||||
| ET STRING STRING
|
||||
{
|
||||
base_id = name2number($2);
|
||||
strlcpy(name, $3, sizeof(name));
|
||||
free($2);
|
||||
free($3);
|
||||
}
|
||||
;
|
||||
|
||||
statements : statement
|
||||
| statements statement
|
||||
;
|
||||
|
||||
statement : INDEX NUMBER
|
||||
{
|
||||
number = $2;
|
||||
}
|
||||
| PREFIX STRING
|
||||
{
|
||||
free(prefix);
|
||||
asprintf (&prefix, "%s_", $2);
|
||||
if (prefix == NULL)
|
||||
errx(1, "malloc");
|
||||
free($2);
|
||||
}
|
||||
| PREFIX
|
||||
{
|
||||
prefix = realloc(prefix, 1);
|
||||
if (prefix == NULL)
|
||||
errx(1, "malloc");
|
||||
*prefix = '\0';
|
||||
}
|
||||
| EC STRING ',' STRING
|
||||
{
|
||||
struct error_code *ec = malloc(sizeof(*ec));
|
||||
|
||||
if (ec == NULL)
|
||||
errx(1, "malloc");
|
||||
|
||||
ec->next = NULL;
|
||||
ec->number = number;
|
||||
if(prefix && *prefix != '\0') {
|
||||
asprintf (&ec->name, "%s%s", prefix, $2);
|
||||
if (ec->name == NULL)
|
||||
errx(1, "malloc");
|
||||
free($2);
|
||||
} else
|
||||
ec->name = $2;
|
||||
ec->string = $4;
|
||||
APPEND(codes, ec);
|
||||
number++;
|
||||
}
|
||||
| END
|
||||
{
|
||||
YYACCEPT;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
static long
|
||||
name2number(const char *str)
|
||||
{
|
||||
const char *p;
|
||||
long num = 0;
|
||||
const char *x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz0123456789_";
|
||||
if(strlen(str) > 4) {
|
||||
yyerror("table name too long");
|
||||
return 0;
|
||||
}
|
||||
for(p = str; *p; p++){
|
||||
char *q = strchr(x, *p);
|
||||
if(q == NULL) {
|
||||
yyerror("invalid character in table name");
|
||||
return 0;
|
||||
}
|
||||
num = (num << 6) + (q - x) + 1;
|
||||
}
|
||||
num <<= 8;
|
||||
if(num > 0x7fffffff)
|
||||
num = -(0xffffffff - num + 1);
|
||||
return num;
|
||||
}
|
||||
|
||||
void
|
||||
yyerror (char *s)
|
||||
{
|
||||
error_message ("%s\n", s);
|
||||
}
|
||||
Executable
+124
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 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: aes.c,v 1.5 2005/06/18 22:46:35 lha Exp $");
|
||||
#endif
|
||||
|
||||
#ifdef KRB5
|
||||
#include <krb5-types.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "rijndael-alg-fst.h"
|
||||
#include "aes.h"
|
||||
|
||||
int
|
||||
AES_set_encrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key)
|
||||
{
|
||||
key->rounds = rijndaelKeySetupEnc(key->key, userkey, bits);
|
||||
if (key->rounds == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
AES_set_decrypt_key(const unsigned char *userkey, const int bits, AES_KEY *key)
|
||||
{
|
||||
key->rounds = rijndaelKeySetupDec(key->key, userkey, bits);
|
||||
if (key->rounds == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
|
||||
{
|
||||
rijndaelEncrypt(key->key, key->rounds, in, out);
|
||||
}
|
||||
|
||||
void
|
||||
AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key)
|
||||
{
|
||||
rijndaelDecrypt(key->key, key->rounds, in, out);
|
||||
}
|
||||
|
||||
void
|
||||
AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
unsigned long size, const AES_KEY *key,
|
||||
unsigned char *iv, int forward_encrypt)
|
||||
{
|
||||
unsigned char tmp[AES_BLOCK_SIZE];
|
||||
int i;
|
||||
|
||||
if (forward_encrypt) {
|
||||
while (size >= AES_BLOCK_SIZE) {
|
||||
for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
tmp[i] = in[i] ^ iv[i];
|
||||
AES_encrypt(tmp, out, key);
|
||||
memcpy(iv, out, AES_BLOCK_SIZE);
|
||||
size -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (size) {
|
||||
for (i = 0; i < size; i++)
|
||||
tmp[i] = in[i] ^ iv[i];
|
||||
for (i = size; i < AES_BLOCK_SIZE; i++)
|
||||
tmp[i] = iv[i];
|
||||
AES_encrypt(tmp, out, key);
|
||||
memcpy(iv, out, AES_BLOCK_SIZE);
|
||||
}
|
||||
} else {
|
||||
while (size >= AES_BLOCK_SIZE) {
|
||||
memcpy(tmp, in, AES_BLOCK_SIZE);
|
||||
AES_decrypt(tmp, out, key);
|
||||
for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
out[i] ^= iv[i];
|
||||
memcpy(iv, tmp, AES_BLOCK_SIZE);
|
||||
size -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
if (size) {
|
||||
memcpy(tmp, in, AES_BLOCK_SIZE);
|
||||
AES_decrypt(tmp, out, key);
|
||||
for (i = 0; i < size; i++)
|
||||
out[i] ^= iv[i];
|
||||
memcpy(iv, tmp, AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2004 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $Id: aes.h,v 1.6 2006/05/05 11:06:35 lha Exp $ */
|
||||
|
||||
#ifndef HEIM_AES_H
|
||||
#define HEIM_AES_H 1
|
||||
|
||||
/* symbol renaming */
|
||||
#define AES_set_encrypt_key hc_AES_set_encrypt_key
|
||||
#define AES_set_decrypt_key hc_AES_decrypt_key
|
||||
#define AES_encrypt hc_AES_encrypt
|
||||
#define AES_decrypt hc_AES_decrypt
|
||||
#define AES_cbc_encrypt hc_AES_cbc_encrypt
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define AES_MAXNR 14
|
||||
|
||||
#define AES_ENCRYPT 1
|
||||
#define AES_DECRYPT 0
|
||||
|
||||
typedef struct aes_key {
|
||||
uint32_t key[(AES_MAXNR+1)*4];
|
||||
int rounds;
|
||||
} AES_KEY;
|
||||
|
||||
int AES_set_encrypt_key(const unsigned char *, const int, AES_KEY *);
|
||||
int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *);
|
||||
|
||||
void AES_encrypt(const unsigned char *, unsigned char *, const AES_KEY *);
|
||||
void AES_decrypt(const unsigned char *, unsigned char *, const AES_KEY *);
|
||||
|
||||
void AES_cbc_encrypt(const unsigned char *, unsigned char *,
|
||||
const unsigned long, const AES_KEY *,
|
||||
unsigned char *, int);
|
||||
|
||||
#endif /* HEIM_AES_H */
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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: bn.h,v 1.3 2006/01/13 08:27:50 lha Exp $
|
||||
*/
|
||||
|
||||
#ifndef _HEIM_BN_H
|
||||
#define _HEIM_BN_H 1
|
||||
|
||||
/* symbol renaming */
|
||||
#define BN_GENCB_call hc_BN_GENCB_call
|
||||
#define BN_GENCB_set hc_BN_GENCB_set
|
||||
#define BN_bin2bn hc_BN_bin2bn
|
||||
#define BN_bn2bin hc_BN_bn2bin
|
||||
#define BN_bn2hex hc_BN_bn2hex
|
||||
#define BN_clear hc_BN_clear
|
||||
#define BN_clear_bit hc_BN_clear_bit
|
||||
#define BN_clear_free hc_BN_clear_free
|
||||
#define BN_cmp hc_BN_cmp
|
||||
#define BN_dup hc_BN_dup
|
||||
#define BN_free hc_BN_free
|
||||
#define BN_is_negative hc_BN_is_negative
|
||||
#define BN_get_word hc_BN_get_word
|
||||
#define BN_hex2bn hc_BN_hex2bn
|
||||
#define BN_is_bit_set hc_BN_is_bit_set
|
||||
#define BN_new hc_BN_new
|
||||
#define BN_num_bits hc_BN_num_bits
|
||||
#define BN_num_bytes hc_BN_num_bytes
|
||||
#define BN_rand hc_BN_rand
|
||||
#define BN_set_bit hc_BN_set_bit
|
||||
#define BN_set_negative hc_BN_set_negative
|
||||
#define BN_set_word hc_BN_set_word
|
||||
#define BN_uadd hc_BN_uadd
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
typedef void BIGNUM;
|
||||
typedef struct BN_GENCB BN_GENCB;
|
||||
typedef void BN_CTX;
|
||||
typedef void BN_MONT_CTX;
|
||||
typedef void BN_BLINDING;
|
||||
|
||||
struct BN_GENCB {
|
||||
unsigned int ver;
|
||||
void *arg;
|
||||
union {
|
||||
int (*cb_2)(int, int, BN_GENCB *);
|
||||
} cb;
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
BIGNUM *BN_new(void);
|
||||
void BN_free(BIGNUM *);
|
||||
void BN_clear_free(BIGNUM *);
|
||||
void BN_clear(BIGNUM *);
|
||||
BIGNUM *BN_dup(const BIGNUM *);
|
||||
|
||||
int BN_num_bits(const BIGNUM *);
|
||||
int BN_num_bytes(const BIGNUM *);
|
||||
|
||||
int BN_cmp(const BIGNUM *, const BIGNUM *);
|
||||
|
||||
void BN_set_negative(BIGNUM *, int);
|
||||
int BN_is_negative(BIGNUM *);
|
||||
|
||||
int BN_is_bit_set(const BIGNUM *, int);
|
||||
int BN_set_bit(BIGNUM *, int);
|
||||
int BN_clear_bit(BIGNUM *, int);
|
||||
|
||||
int BN_set_word(BIGNUM *, unsigned long);
|
||||
unsigned long BN_get_word(const BIGNUM *);
|
||||
|
||||
BIGNUM *BN_bin2bn(const void *,int len,BIGNUM *);
|
||||
int BN_bn2bin(const BIGNUM *, void *);
|
||||
int BN_hex2bn(BIGNUM **, const char *);
|
||||
char * BN_bn2hex(const BIGNUM *);
|
||||
|
||||
int BN_uadd(BIGNUM *, const BIGNUM *, const BIGNUM *);
|
||||
|
||||
int BN_rand(BIGNUM *, int, int, int);
|
||||
|
||||
void BN_GENCB_set(BN_GENCB *, int (*)(int, int, BN_GENCB *), void *);
|
||||
int BN_GENCB_call(BN_GENCB *, int, int);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,196 @@
|
||||
/* GENERATE FILE from gen-des.pl, do not edit */
|
||||
|
||||
/* pc1_c_3 bit pattern 5 13 21 */
|
||||
static int pc1_c_3[8] = {
|
||||
0x00000000, 0x00000010, 0x00001000, 0x00001010,
|
||||
0x00100000, 0x00100010, 0x00101000, 0x00101010
|
||||
};
|
||||
/* pc1_c_4 bit pattern 1 9 17 25 */
|
||||
static int pc1_c_4[16] = {
|
||||
0x00000000, 0x00000001, 0x00000100, 0x00000101,
|
||||
0x00010000, 0x00010001, 0x00010100, 0x00010101,
|
||||
0x01000000, 0x01000001, 0x01000100, 0x01000101,
|
||||
0x01010000, 0x01010001, 0x01010100, 0x01010101
|
||||
};
|
||||
/* pc1_d_3 bit pattern 49 41 33 */
|
||||
static int pc1_d_3[8] = {
|
||||
0x00000000, 0x01000000, 0x00010000, 0x01010000,
|
||||
0x00000100, 0x01000100, 0x00010100, 0x01010100
|
||||
};
|
||||
/* pc1_d_4 bit pattern 57 53 45 37 */
|
||||
static int pc1_d_4[16] = {
|
||||
0x00000000, 0x00100000, 0x00001000, 0x00101000,
|
||||
0x00000010, 0x00100010, 0x00001010, 0x00101010,
|
||||
0x00000001, 0x00100001, 0x00001001, 0x00101001,
|
||||
0x00000011, 0x00100011, 0x00001011, 0x00101011
|
||||
};
|
||||
/* pc2_c_1 bit pattern 5 24 7 16 6 10 */
|
||||
static int pc2_c_1[64] = {
|
||||
0x00000000, 0x00004000, 0x00040000, 0x00044000,
|
||||
0x00000100, 0x00004100, 0x00040100, 0x00044100,
|
||||
0x00020000, 0x00024000, 0x00060000, 0x00064000,
|
||||
0x00020100, 0x00024100, 0x00060100, 0x00064100,
|
||||
0x00000001, 0x00004001, 0x00040001, 0x00044001,
|
||||
0x00000101, 0x00004101, 0x00040101, 0x00044101,
|
||||
0x00020001, 0x00024001, 0x00060001, 0x00064001,
|
||||
0x00020101, 0x00024101, 0x00060101, 0x00064101,
|
||||
0x00080000, 0x00084000, 0x000c0000, 0x000c4000,
|
||||
0x00080100, 0x00084100, 0x000c0100, 0x000c4100,
|
||||
0x000a0000, 0x000a4000, 0x000e0000, 0x000e4000,
|
||||
0x000a0100, 0x000a4100, 0x000e0100, 0x000e4100,
|
||||
0x00080001, 0x00084001, 0x000c0001, 0x000c4001,
|
||||
0x00080101, 0x00084101, 0x000c0101, 0x000c4101,
|
||||
0x000a0001, 0x000a4001, 0x000e0001, 0x000e4001,
|
||||
0x000a0101, 0x000a4101, 0x000e0101, 0x000e4101
|
||||
};
|
||||
/* pc2_c_2 bit pattern 20 18 12 3 15 23 */
|
||||
static int pc2_c_2[64] = {
|
||||
0x00000000, 0x00000002, 0x00000200, 0x00000202,
|
||||
0x00200000, 0x00200002, 0x00200200, 0x00200202,
|
||||
0x00001000, 0x00001002, 0x00001200, 0x00001202,
|
||||
0x00201000, 0x00201002, 0x00201200, 0x00201202,
|
||||
0x00000040, 0x00000042, 0x00000240, 0x00000242,
|
||||
0x00200040, 0x00200042, 0x00200240, 0x00200242,
|
||||
0x00001040, 0x00001042, 0x00001240, 0x00001242,
|
||||
0x00201040, 0x00201042, 0x00201240, 0x00201242,
|
||||
0x00000010, 0x00000012, 0x00000210, 0x00000212,
|
||||
0x00200010, 0x00200012, 0x00200210, 0x00200212,
|
||||
0x00001010, 0x00001012, 0x00001210, 0x00001212,
|
||||
0x00201010, 0x00201012, 0x00201210, 0x00201212,
|
||||
0x00000050, 0x00000052, 0x00000250, 0x00000252,
|
||||
0x00200050, 0x00200052, 0x00200250, 0x00200252,
|
||||
0x00001050, 0x00001052, 0x00001250, 0x00001252,
|
||||
0x00201050, 0x00201052, 0x00201250, 0x00201252
|
||||
};
|
||||
/* pc2_c_3 bit pattern 1 9 19 2 14 22 */
|
||||
static int pc2_c_3[64] = {
|
||||
0x00000000, 0x00000004, 0x00000400, 0x00000404,
|
||||
0x00400000, 0x00400004, 0x00400400, 0x00400404,
|
||||
0x00000020, 0x00000024, 0x00000420, 0x00000424,
|
||||
0x00400020, 0x00400024, 0x00400420, 0x00400424,
|
||||
0x00008000, 0x00008004, 0x00008400, 0x00008404,
|
||||
0x00408000, 0x00408004, 0x00408400, 0x00408404,
|
||||
0x00008020, 0x00008024, 0x00008420, 0x00008424,
|
||||
0x00408020, 0x00408024, 0x00408420, 0x00408424,
|
||||
0x00800000, 0x00800004, 0x00800400, 0x00800404,
|
||||
0x00c00000, 0x00c00004, 0x00c00400, 0x00c00404,
|
||||
0x00800020, 0x00800024, 0x00800420, 0x00800424,
|
||||
0x00c00020, 0x00c00024, 0x00c00420, 0x00c00424,
|
||||
0x00808000, 0x00808004, 0x00808400, 0x00808404,
|
||||
0x00c08000, 0x00c08004, 0x00c08400, 0x00c08404,
|
||||
0x00808020, 0x00808024, 0x00808420, 0x00808424,
|
||||
0x00c08020, 0x00c08024, 0x00c08420, 0x00c08424
|
||||
};
|
||||
/* pc2_c_4 bit pattern 11 13 4 17 21 8 */
|
||||
static int pc2_c_4[64] = {
|
||||
0x00000000, 0x00010000, 0x00000008, 0x00010008,
|
||||
0x00000080, 0x00010080, 0x00000088, 0x00010088,
|
||||
0x00100000, 0x00110000, 0x00100008, 0x00110008,
|
||||
0x00100080, 0x00110080, 0x00100088, 0x00110088,
|
||||
0x00000800, 0x00010800, 0x00000808, 0x00010808,
|
||||
0x00000880, 0x00010880, 0x00000888, 0x00010888,
|
||||
0x00100800, 0x00110800, 0x00100808, 0x00110808,
|
||||
0x00100880, 0x00110880, 0x00100888, 0x00110888,
|
||||
0x00002000, 0x00012000, 0x00002008, 0x00012008,
|
||||
0x00002080, 0x00012080, 0x00002088, 0x00012088,
|
||||
0x00102000, 0x00112000, 0x00102008, 0x00112008,
|
||||
0x00102080, 0x00112080, 0x00102088, 0x00112088,
|
||||
0x00002800, 0x00012800, 0x00002808, 0x00012808,
|
||||
0x00002880, 0x00012880, 0x00002888, 0x00012888,
|
||||
0x00102800, 0x00112800, 0x00102808, 0x00112808,
|
||||
0x00102880, 0x00112880, 0x00102888, 0x00112888
|
||||
};
|
||||
/* pc2_d_1 bit pattern 51 35 31 52 39 45 */
|
||||
static int pc2_d_1[64] = {
|
||||
0x00000000, 0x00000080, 0x00002000, 0x00002080,
|
||||
0x00000001, 0x00000081, 0x00002001, 0x00002081,
|
||||
0x00200000, 0x00200080, 0x00202000, 0x00202080,
|
||||
0x00200001, 0x00200081, 0x00202001, 0x00202081,
|
||||
0x00020000, 0x00020080, 0x00022000, 0x00022080,
|
||||
0x00020001, 0x00020081, 0x00022001, 0x00022081,
|
||||
0x00220000, 0x00220080, 0x00222000, 0x00222080,
|
||||
0x00220001, 0x00220081, 0x00222001, 0x00222081,
|
||||
0x00000002, 0x00000082, 0x00002002, 0x00002082,
|
||||
0x00000003, 0x00000083, 0x00002003, 0x00002083,
|
||||
0x00200002, 0x00200082, 0x00202002, 0x00202082,
|
||||
0x00200003, 0x00200083, 0x00202003, 0x00202083,
|
||||
0x00020002, 0x00020082, 0x00022002, 0x00022082,
|
||||
0x00020003, 0x00020083, 0x00022003, 0x00022083,
|
||||
0x00220002, 0x00220082, 0x00222002, 0x00222082,
|
||||
0x00220003, 0x00220083, 0x00222003, 0x00222083
|
||||
};
|
||||
/* pc2_d_2 bit pattern 50 32 43 36 29 48 */
|
||||
static int pc2_d_2[64] = {
|
||||
0x00000000, 0x00000010, 0x00800000, 0x00800010,
|
||||
0x00010000, 0x00010010, 0x00810000, 0x00810010,
|
||||
0x00000200, 0x00000210, 0x00800200, 0x00800210,
|
||||
0x00010200, 0x00010210, 0x00810200, 0x00810210,
|
||||
0x00100000, 0x00100010, 0x00900000, 0x00900010,
|
||||
0x00110000, 0x00110010, 0x00910000, 0x00910010,
|
||||
0x00100200, 0x00100210, 0x00900200, 0x00900210,
|
||||
0x00110200, 0x00110210, 0x00910200, 0x00910210,
|
||||
0x00000004, 0x00000014, 0x00800004, 0x00800014,
|
||||
0x00010004, 0x00010014, 0x00810004, 0x00810014,
|
||||
0x00000204, 0x00000214, 0x00800204, 0x00800214,
|
||||
0x00010204, 0x00010214, 0x00810204, 0x00810214,
|
||||
0x00100004, 0x00100014, 0x00900004, 0x00900014,
|
||||
0x00110004, 0x00110014, 0x00910004, 0x00910014,
|
||||
0x00100204, 0x00100214, 0x00900204, 0x00900214,
|
||||
0x00110204, 0x00110214, 0x00910204, 0x00910214
|
||||
};
|
||||
/* pc2_d_3 bit pattern 41 38 47 33 40 42 */
|
||||
static int pc2_d_3[64] = {
|
||||
0x00000000, 0x00000400, 0x00001000, 0x00001400,
|
||||
0x00080000, 0x00080400, 0x00081000, 0x00081400,
|
||||
0x00000020, 0x00000420, 0x00001020, 0x00001420,
|
||||
0x00080020, 0x00080420, 0x00081020, 0x00081420,
|
||||
0x00004000, 0x00004400, 0x00005000, 0x00005400,
|
||||
0x00084000, 0x00084400, 0x00085000, 0x00085400,
|
||||
0x00004020, 0x00004420, 0x00005020, 0x00005420,
|
||||
0x00084020, 0x00084420, 0x00085020, 0x00085420,
|
||||
0x00000800, 0x00000c00, 0x00001800, 0x00001c00,
|
||||
0x00080800, 0x00080c00, 0x00081800, 0x00081c00,
|
||||
0x00000820, 0x00000c20, 0x00001820, 0x00001c20,
|
||||
0x00080820, 0x00080c20, 0x00081820, 0x00081c20,
|
||||
0x00004800, 0x00004c00, 0x00005800, 0x00005c00,
|
||||
0x00084800, 0x00084c00, 0x00085800, 0x00085c00,
|
||||
0x00004820, 0x00004c20, 0x00005820, 0x00005c20,
|
||||
0x00084820, 0x00084c20, 0x00085820, 0x00085c20
|
||||
};
|
||||
/* pc2_d_4 bit pattern 49 37 30 46 34 44 */
|
||||
static int pc2_d_4[64] = {
|
||||
0x00000000, 0x00000100, 0x00040000, 0x00040100,
|
||||
0x00000040, 0x00000140, 0x00040040, 0x00040140,
|
||||
0x00400000, 0x00400100, 0x00440000, 0x00440100,
|
||||
0x00400040, 0x00400140, 0x00440040, 0x00440140,
|
||||
0x00008000, 0x00008100, 0x00048000, 0x00048100,
|
||||
0x00008040, 0x00008140, 0x00048040, 0x00048140,
|
||||
0x00408000, 0x00408100, 0x00448000, 0x00448100,
|
||||
0x00408040, 0x00408140, 0x00448040, 0x00448140,
|
||||
0x00000008, 0x00000108, 0x00040008, 0x00040108,
|
||||
0x00000048, 0x00000148, 0x00040048, 0x00040148,
|
||||
0x00400008, 0x00400108, 0x00440008, 0x00440108,
|
||||
0x00400048, 0x00400148, 0x00440048, 0x00440148,
|
||||
0x00008008, 0x00008108, 0x00048008, 0x00048108,
|
||||
0x00008048, 0x00008148, 0x00048048, 0x00048148,
|
||||
0x00408008, 0x00408108, 0x00448008, 0x00448108,
|
||||
0x00408048, 0x00408148, 0x00448048, 0x00448148
|
||||
};
|
||||
static unsigned char odd_parity[256] = {
|
||||
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
|
||||
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
|
||||
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
|
||||
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
|
||||
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
|
||||
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
|
||||
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
|
||||
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
|
||||
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
|
||||
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
|
||||
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
|
||||
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
|
||||
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
|
||||
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
|
||||
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
|
||||
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254,
|
||||
};
|
||||
@@ -0,0 +1,967 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The document that got me started for real was "Efficient
|
||||
* Implementation of the Data Encryption Standard" by Dag Arne Osvik.
|
||||
* I never got to the PC1 transformation was working, instead I used
|
||||
* table-lookup was used for all key schedule setup. The document was
|
||||
* very useful since it de-mystified other implementations for me.
|
||||
*
|
||||
* The core DES function (SBOX + P transformation) is from Richard
|
||||
* Outerbridge public domain DES implementation. My sanity is saved
|
||||
* thanks to his work. Thank you Richard.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
RCSID("$Id: des.c,v 1.18 2006/04/24 14:26:19 lha Exp $");
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <krb5-types.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "des.h"
|
||||
#include "ui.h"
|
||||
|
||||
static void desx(uint32_t [2], DES_key_schedule *, int);
|
||||
static void IP(uint32_t [2]);
|
||||
static void FP(uint32_t [2]);
|
||||
|
||||
#include "des-tables.h"
|
||||
|
||||
#define ROTATE_LEFT28(x,one) \
|
||||
if (one) { \
|
||||
x = ( ((x)<<(1)) & 0xffffffe) | ((x) >> 27); \
|
||||
} else { \
|
||||
x = ( ((x)<<(2)) & 0xffffffc) | ((x) >> 26); \
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
DES_set_odd_parity(DES_cblock *key)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < DES_CBLOCK_LEN; i++)
|
||||
(*key)[i] = odd_parity[(*key)[i]];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
/* FIPS 74 */
|
||||
static DES_cblock weak_keys[] = {
|
||||
{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, /* weak keys */
|
||||
{0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
|
||||
{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
|
||||
{0xE0,0xE0,0xE0,0xE0,0xF1,0xF1,0xF1,0xF1},
|
||||
{0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE}, /* semi-weak keys */
|
||||
{0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
|
||||
{0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
|
||||
{0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
|
||||
{0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
|
||||
{0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
|
||||
{0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
|
||||
{0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
|
||||
{0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
|
||||
{0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
|
||||
{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
|
||||
{0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}
|
||||
};
|
||||
|
||||
int
|
||||
DES_is_weak_key(DES_cblock *key)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(weak_keys)/sizeof(weak_keys[0]); i++) {
|
||||
if (memcmp(weak_keys[i], key, DES_CBLOCK_LEN) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
DES_set_key(DES_cblock *key, DES_key_schedule *ks)
|
||||
{
|
||||
uint32_t t1, t2;
|
||||
uint32_t c, d;
|
||||
int shifts[16] = { 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
|
||||
uint32_t *k = &ks->ks[0];
|
||||
int i;
|
||||
|
||||
t1 = (*key)[0] << 24 | (*key)[1] << 16 | (*key)[2] << 8 | (*key)[3];
|
||||
t2 = (*key)[4] << 24 | (*key)[5] << 16 | (*key)[6] << 8 | (*key)[7];
|
||||
|
||||
c = (pc1_c_3[(t1 >> (5 )) & 0x7] << 3)
|
||||
| (pc1_c_3[(t1 >> (5 + 8 )) & 0x7] << 2)
|
||||
| (pc1_c_3[(t1 >> (5 + 8 + 8 )) & 0x7] << 1)
|
||||
| (pc1_c_3[(t1 >> (5 + 8 + 8 + 8)) & 0x7] << 0)
|
||||
| (pc1_c_4[(t2 >> (4 )) & 0xf] << 3)
|
||||
| (pc1_c_4[(t2 >> (4 + 8 )) & 0xf] << 2)
|
||||
| (pc1_c_4[(t2 >> (4 + 8 + 8 )) & 0xf] << 1)
|
||||
| (pc1_c_4[(t2 >> (4 + 8 + 8 + 8)) & 0xf] << 0);
|
||||
|
||||
|
||||
d = (pc1_d_3[(t2 >> (1 )) & 0x7] << 3)
|
||||
| (pc1_d_3[(t2 >> (1 + 8 )) & 0x7] << 2)
|
||||
| (pc1_d_3[(t2 >> (1 + 8 + 8 )) & 0x7] << 1)
|
||||
| (pc1_d_3[(t2 >> (1 + 8 + 8 + 8)) & 0x7] << 0)
|
||||
| (pc1_d_4[(t1 >> (1 )) & 0xf] << 3)
|
||||
| (pc1_d_4[(t1 >> (1 + 8 )) & 0xf] << 2)
|
||||
| (pc1_d_4[(t1 >> (1 + 8 + 8 )) & 0xf] << 1)
|
||||
| (pc1_d_4[(t1 >> (1 + 8 + 8 + 8)) & 0xf] << 0);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
uint32_t kc, kd;
|
||||
|
||||
ROTATE_LEFT28(c, shifts[i]);
|
||||
ROTATE_LEFT28(d, shifts[i]);
|
||||
|
||||
kc = pc2_c_1[(c >> 22) & 0x3f] |
|
||||
pc2_c_2[((c >> 16) & 0x30) | ((c >> 15) & 0xf)] |
|
||||
pc2_c_3[((c >> 9 ) & 0x3c) | ((c >> 8 ) & 0x3)] |
|
||||
pc2_c_4[((c >> 2 ) & 0x20) | ((c >> 1) & 0x18) | (c & 0x7)];
|
||||
kd = pc2_d_1[(d >> 22) & 0x3f] |
|
||||
pc2_d_2[((d >> 15) & 0x30) | ((d >> 14) & 0xf)] |
|
||||
pc2_d_3[ (d >> 7 ) & 0x3f] |
|
||||
pc2_d_4[((d >> 1 ) & 0x3c) | ((d ) & 0x3)];
|
||||
|
||||
/* Change to byte order used by the S boxes */
|
||||
*k = (kc & 0x00fc0000L) << 6;
|
||||
*k |= (kc & 0x00000fc0L) << 10;
|
||||
*k |= (kd & 0x00fc0000L) >> 10;
|
||||
*k++ |= (kd & 0x00000fc0L) >> 6;
|
||||
*k = (kc & 0x0003f000L) << 12;
|
||||
*k |= (kc & 0x0000003fL) << 16;
|
||||
*k |= (kd & 0x0003f000L) >> 4;
|
||||
*k++ |= (kd & 0x0000003fL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
DES_set_key_checked(DES_cblock *key, DES_key_schedule *ks)
|
||||
{
|
||||
if (DES_is_weak_key(key)) {
|
||||
memset(ks, 0, sizeof(*ks));
|
||||
return 1;
|
||||
}
|
||||
return DES_set_key(key, ks);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compatibility function for eay libdes
|
||||
*/
|
||||
|
||||
int
|
||||
DES_key_sched(DES_cblock *key, DES_key_schedule *ks)
|
||||
{
|
||||
return DES_set_key(key, ks);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
load(const unsigned char *b, uint32_t v[2])
|
||||
{
|
||||
v[0] = b[0] << 24;
|
||||
v[0] |= b[1] << 16;
|
||||
v[0] |= b[2] << 8;
|
||||
v[0] |= b[3] << 0;
|
||||
v[1] = b[4] << 24;
|
||||
v[1] |= b[5] << 16;
|
||||
v[1] |= b[6] << 8;
|
||||
v[1] |= b[7] << 0;
|
||||
}
|
||||
|
||||
static void
|
||||
store(const uint32_t v[2], unsigned char *b)
|
||||
{
|
||||
b[0] = (v[0] >> 24) & 0xff;
|
||||
b[1] = (v[0] >> 16) & 0xff;
|
||||
b[2] = (v[0] >> 8) & 0xff;
|
||||
b[3] = (v[0] >> 0) & 0xff;
|
||||
b[4] = (v[1] >> 24) & 0xff;
|
||||
b[5] = (v[1] >> 16) & 0xff;
|
||||
b[6] = (v[1] >> 8) & 0xff;
|
||||
b[7] = (v[1] >> 0) & 0xff;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
DES_encrypt(uint32_t u[2], DES_key_schedule *ks, int forward_encrypt)
|
||||
{
|
||||
IP(u);
|
||||
desx(u, ks, forward_encrypt);
|
||||
FP(u);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
DES_ecb_encrypt(DES_cblock *input, DES_cblock *output,
|
||||
DES_key_schedule *ks, int forward_encrypt)
|
||||
{
|
||||
uint32_t u[2];
|
||||
load(*input, u);
|
||||
DES_encrypt(u, ks, forward_encrypt);
|
||||
store(u, *output);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
DES_cbc_encrypt(const void *in, void *out, long length,
|
||||
DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
|
||||
{
|
||||
const unsigned char *input = in;
|
||||
unsigned char *output = out;
|
||||
uint32_t u[2];
|
||||
uint32_t uiv[2];
|
||||
|
||||
load(*iv, uiv);
|
||||
|
||||
if (forward_encrypt) {
|
||||
while (length >= DES_CBLOCK_LEN) {
|
||||
load(input, u);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
DES_encrypt(u, ks, 1);
|
||||
uiv[0] = u[0]; uiv[1] = u[1];
|
||||
store(u, output);
|
||||
|
||||
length -= DES_CBLOCK_LEN;
|
||||
input += DES_CBLOCK_LEN;
|
||||
output += DES_CBLOCK_LEN;
|
||||
}
|
||||
if (length) {
|
||||
unsigned char tmp[DES_CBLOCK_LEN];
|
||||
memcpy(tmp, input, length);
|
||||
memset(tmp + length, 0, DES_CBLOCK_LEN - length);
|
||||
load(tmp, u);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
DES_encrypt(u, ks, 1);
|
||||
store(u, output);
|
||||
}
|
||||
} else {
|
||||
uint32_t t[2];
|
||||
while (length >= DES_CBLOCK_LEN) {
|
||||
load(input, u);
|
||||
t[0] = u[0]; t[1] = u[1];
|
||||
DES_encrypt(u, ks, 0);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
store(u, output);
|
||||
uiv[0] = t[0]; uiv[1] = t[1];
|
||||
|
||||
length -= DES_CBLOCK_LEN;
|
||||
input += DES_CBLOCK_LEN;
|
||||
output += DES_CBLOCK_LEN;
|
||||
}
|
||||
if (length) {
|
||||
unsigned char tmp[DES_CBLOCK_LEN];
|
||||
memcpy(tmp, input, length);
|
||||
memset(tmp + length, 0, DES_CBLOCK_LEN - length);
|
||||
load(tmp, u);
|
||||
DES_encrypt(u, ks, 0);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
store(u, output);
|
||||
}
|
||||
}
|
||||
uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
DES_pcbc_encrypt(const void *in, void *out, long length,
|
||||
DES_key_schedule *ks, DES_cblock *iv, int forward_encrypt)
|
||||
{
|
||||
const unsigned char *input = in;
|
||||
unsigned char *output = out;
|
||||
uint32_t u[2];
|
||||
uint32_t uiv[2];
|
||||
|
||||
load(*iv, uiv);
|
||||
|
||||
if (forward_encrypt) {
|
||||
uint32_t t[2];
|
||||
while (length >= DES_CBLOCK_LEN) {
|
||||
load(input, u);
|
||||
t[0] = u[0]; t[1] = u[1];
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
DES_encrypt(u, ks, 1);
|
||||
uiv[0] = u[0] ^ t[0]; uiv[1] = u[1] ^ t[1];
|
||||
store(u, output);
|
||||
|
||||
length -= DES_CBLOCK_LEN;
|
||||
input += DES_CBLOCK_LEN;
|
||||
output += DES_CBLOCK_LEN;
|
||||
}
|
||||
if (length) {
|
||||
unsigned char tmp[DES_CBLOCK_LEN];
|
||||
memcpy(tmp, input, length);
|
||||
memset(tmp + length, 0, DES_CBLOCK_LEN - length);
|
||||
load(tmp, u);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
DES_encrypt(u, ks, 1);
|
||||
store(u, output);
|
||||
}
|
||||
} else {
|
||||
uint32_t t[2];
|
||||
while (length >= DES_CBLOCK_LEN) {
|
||||
load(input, u);
|
||||
t[0] = u[0]; t[1] = u[1];
|
||||
DES_encrypt(u, ks, 0);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
store(u, output);
|
||||
uiv[0] = t[0] ^ u[0]; uiv[1] = t[1] ^ u[1];
|
||||
|
||||
length -= DES_CBLOCK_LEN;
|
||||
input += DES_CBLOCK_LEN;
|
||||
output += DES_CBLOCK_LEN;
|
||||
}
|
||||
if (length) {
|
||||
unsigned char tmp[DES_CBLOCK_LEN];
|
||||
memcpy(tmp, input, length);
|
||||
memset(tmp + length, 0, DES_CBLOCK_LEN - length);
|
||||
load(tmp, u);
|
||||
DES_encrypt(u, ks, 0);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
}
|
||||
}
|
||||
uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
_des3_encrypt(uint32_t u[2], DES_key_schedule *ks1, DES_key_schedule *ks2,
|
||||
DES_key_schedule *ks3, int forward_encrypt)
|
||||
{
|
||||
IP(u);
|
||||
if (forward_encrypt) {
|
||||
desx(u, ks1, 1); /* IP + FP cancel out each other */
|
||||
desx(u, ks2, 0);
|
||||
desx(u, ks3, 1);
|
||||
} else {
|
||||
desx(u, ks3, 0);
|
||||
desx(u, ks2, 1);
|
||||
desx(u, ks1, 0);
|
||||
}
|
||||
FP(u);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
DES_ecb3_encrypt(DES_cblock *input,
|
||||
DES_cblock *output,
|
||||
DES_key_schedule *ks1,
|
||||
DES_key_schedule *ks2,
|
||||
DES_key_schedule *ks3,
|
||||
int forward_encrypt)
|
||||
{
|
||||
uint32_t u[2];
|
||||
load(*input, u);
|
||||
_des3_encrypt(u, ks1, ks2, ks3, forward_encrypt);
|
||||
store(u, *output);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
DES_ede3_cbc_encrypt(const void *in, void *out,
|
||||
long length, DES_key_schedule *ks1,
|
||||
DES_key_schedule *ks2, DES_key_schedule *ks3,
|
||||
DES_cblock *iv, int forward_encrypt)
|
||||
{
|
||||
const unsigned char *input = in;
|
||||
unsigned char *output = out;
|
||||
uint32_t u[2];
|
||||
uint32_t uiv[2];
|
||||
|
||||
load(*iv, uiv);
|
||||
|
||||
if (forward_encrypt) {
|
||||
while (length >= DES_CBLOCK_LEN) {
|
||||
load(input, u);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
_des3_encrypt(u, ks1, ks2, ks3, 1);
|
||||
uiv[0] = u[0]; uiv[1] = u[1];
|
||||
store(u, output);
|
||||
|
||||
length -= DES_CBLOCK_LEN;
|
||||
input += DES_CBLOCK_LEN;
|
||||
output += DES_CBLOCK_LEN;
|
||||
}
|
||||
if (length) {
|
||||
unsigned char tmp[DES_CBLOCK_LEN];
|
||||
memcpy(tmp, input, length);
|
||||
memset(tmp + length, 0, DES_CBLOCK_LEN - length);
|
||||
load(tmp, u);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
_des3_encrypt(u, ks1, ks2, ks3, 1);
|
||||
store(u, output);
|
||||
}
|
||||
} else {
|
||||
uint32_t t[2];
|
||||
while (length >= DES_CBLOCK_LEN) {
|
||||
load(input, u);
|
||||
t[0] = u[0]; t[1] = u[1];
|
||||
_des3_encrypt(u, ks1, ks2, ks3, 0);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
store(u, output);
|
||||
uiv[0] = t[0]; uiv[1] = t[1];
|
||||
|
||||
length -= DES_CBLOCK_LEN;
|
||||
input += DES_CBLOCK_LEN;
|
||||
output += DES_CBLOCK_LEN;
|
||||
}
|
||||
if (length) {
|
||||
unsigned char tmp[DES_CBLOCK_LEN];
|
||||
memcpy(tmp, input, length);
|
||||
memset(tmp + length, 0, DES_CBLOCK_LEN - length);
|
||||
load(tmp, u);
|
||||
_des3_encrypt(u, ks1, ks2, ks3, 0);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
store(u, output);
|
||||
}
|
||||
}
|
||||
store(uiv, *iv);
|
||||
uiv[0] = 0; u[0] = 0; uiv[1] = 0; u[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
DES_cfb64_encrypt(const void *in, void *out,
|
||||
long length, DES_key_schedule *ks, DES_cblock *iv,
|
||||
int *num, int forward_encrypt)
|
||||
{
|
||||
const unsigned char *input = in;
|
||||
unsigned char *output = out;
|
||||
unsigned char tmp[DES_CBLOCK_LEN];
|
||||
uint32_t uiv[2];
|
||||
|
||||
load(*iv, uiv);
|
||||
|
||||
assert(*num >= 0 && *num < DES_CBLOCK_LEN);
|
||||
|
||||
if (forward_encrypt) {
|
||||
int i = *num;
|
||||
|
||||
while (length > 0) {
|
||||
if (i == 0)
|
||||
DES_encrypt(uiv, ks, 1);
|
||||
store(uiv, tmp);
|
||||
for (; i < DES_CBLOCK_LEN && i < length; i++) {
|
||||
output[i] = tmp[i] ^ input[i];
|
||||
}
|
||||
if (i == DES_CBLOCK_LEN)
|
||||
load(output, uiv);
|
||||
output += i;
|
||||
input += i;
|
||||
length -= i;
|
||||
if (i == DES_CBLOCK_LEN)
|
||||
i = 0;
|
||||
}
|
||||
store(uiv, *iv);
|
||||
*num = i;
|
||||
} else {
|
||||
int i = *num;
|
||||
unsigned char c;
|
||||
|
||||
while (length > 0) {
|
||||
if (i == 0) {
|
||||
DES_encrypt(uiv, ks, 1);
|
||||
store(uiv, tmp);
|
||||
}
|
||||
for (; i < DES_CBLOCK_LEN && i < length; i++) {
|
||||
c = input[i];
|
||||
output[i] = tmp[i] ^ input[i];
|
||||
(*iv)[i] = c;
|
||||
}
|
||||
output += i;
|
||||
input += i;
|
||||
length -= i;
|
||||
if (i == DES_CBLOCK_LEN) {
|
||||
i = 0;
|
||||
load(*iv, uiv);
|
||||
}
|
||||
}
|
||||
store(uiv, *iv);
|
||||
*num = i;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
DES_cbc_cksum(const void *in, DES_cblock *output,
|
||||
long length, DES_key_schedule *ks, DES_cblock *iv)
|
||||
{
|
||||
const unsigned char *input = in;
|
||||
uint32_t uiv[2];
|
||||
uint32_t u[2] = { 0, 0 };
|
||||
|
||||
load(*iv, uiv);
|
||||
|
||||
while (length >= DES_CBLOCK_LEN) {
|
||||
load(input, u);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
DES_encrypt(u, ks, 1);
|
||||
uiv[0] = u[0]; uiv[1] = u[1];
|
||||
|
||||
length -= DES_CBLOCK_LEN;
|
||||
input += DES_CBLOCK_LEN;
|
||||
}
|
||||
if (length) {
|
||||
unsigned char tmp[DES_CBLOCK_LEN];
|
||||
memcpy(tmp, input, length);
|
||||
memset(tmp + length, 0, DES_CBLOCK_LEN - length);
|
||||
load(tmp, u);
|
||||
u[0] ^= uiv[0]; u[1] ^= uiv[1];
|
||||
DES_encrypt(u, ks, 1);
|
||||
}
|
||||
if (output)
|
||||
store(u, *output);
|
||||
|
||||
uiv[0] = 0; u[0] = 0; uiv[1] = 0;
|
||||
return u[1];
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static unsigned char
|
||||
bitswap8(unsigned char b)
|
||||
{
|
||||
unsigned char r = 0;
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
r = r << 1 | (b & 1);
|
||||
b = b >> 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
DES_string_to_key(const char *str, DES_cblock *key)
|
||||
{
|
||||
const unsigned char *s;
|
||||
unsigned char *k;
|
||||
DES_key_schedule ks;
|
||||
size_t i, len;
|
||||
|
||||
memset(key, 0, sizeof(*key));
|
||||
k = *key;
|
||||
s = (const unsigned char *)str;
|
||||
|
||||
len = strlen(str);
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((i % 16) < 8)
|
||||
k[i % 8] ^= s[i] << 1;
|
||||
else
|
||||
k[7 - (i % 8)] ^= bitswap8(s[i]);
|
||||
}
|
||||
DES_set_odd_parity(key);
|
||||
if (DES_is_weak_key(key))
|
||||
k[7] ^= 0xF0;
|
||||
DES_set_key(key, &ks);
|
||||
DES_cbc_cksum(s, key, len, &ks, key);
|
||||
memset(&ks, 0, sizeof(ks));
|
||||
DES_set_odd_parity(key);
|
||||
if (DES_is_weak_key(key))
|
||||
k[7] ^= 0xF0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
DES_read_password(DES_cblock *key, char *prompt, int verify)
|
||||
{
|
||||
char buf[512];
|
||||
int ret;
|
||||
|
||||
ret = UI_UTIL_read_pw_string(buf, sizeof(buf) - 1, prompt, verify);
|
||||
if (ret == 0)
|
||||
DES_string_to_key(buf, key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
_DES_ipfp_test(void)
|
||||
{
|
||||
DES_cblock k = "\x01\x02\x04\x08\x10\x20\x40\x80", k2;
|
||||
uint32_t u[2] = { 1, 0 };
|
||||
IP(u);
|
||||
FP(u);
|
||||
IP(u);
|
||||
FP(u);
|
||||
if (u[0] != 1 || u[1] != 0)
|
||||
abort();
|
||||
|
||||
load(k, u);
|
||||
store(u, k2);
|
||||
if (memcmp(k, k2, 8) != 0)
|
||||
abort();
|
||||
}
|
||||
|
||||
/* D3DES (V5.09) -
|
||||
*
|
||||
* A portable, public domain, version of the Data Encryption Standard.
|
||||
*
|
||||
* Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
|
||||
* Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
|
||||
* code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
|
||||
* Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
|
||||
* for humouring me on.
|
||||
*
|
||||
* Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
|
||||
* (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
|
||||
*/
|
||||
|
||||
static uint32_t SP1[64] = {
|
||||
0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
|
||||
0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
|
||||
0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
|
||||
0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
|
||||
0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
|
||||
0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
|
||||
0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
|
||||
0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
|
||||
0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
|
||||
0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
|
||||
0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
|
||||
0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
|
||||
0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
|
||||
0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
|
||||
0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
|
||||
0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
|
||||
|
||||
static uint32_t SP2[64] = {
|
||||
0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
|
||||
0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
|
||||
0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
|
||||
0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
|
||||
0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
|
||||
0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
|
||||
0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
|
||||
0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
|
||||
0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
|
||||
0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
|
||||
0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
|
||||
0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
|
||||
0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
|
||||
0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
|
||||
0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
|
||||
0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
|
||||
|
||||
static uint32_t SP3[64] = {
|
||||
0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
|
||||
0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
|
||||
0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
|
||||
0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
|
||||
0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
|
||||
0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
|
||||
0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
|
||||
0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
|
||||
0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
|
||||
0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
|
||||
0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
|
||||
0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
|
||||
0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
|
||||
0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
|
||||
0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
|
||||
0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
|
||||
|
||||
static uint32_t SP4[64] = {
|
||||
0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
|
||||
0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
|
||||
0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
|
||||
0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
|
||||
0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
|
||||
0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
|
||||
0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
|
||||
0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
|
||||
0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
|
||||
0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
|
||||
0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
|
||||
0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
|
||||
0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
|
||||
0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
|
||||
0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
|
||||
0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
|
||||
|
||||
static uint32_t SP5[64] = {
|
||||
0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
|
||||
0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
|
||||
0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
|
||||
0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
|
||||
0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
|
||||
0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
|
||||
0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
|
||||
0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
|
||||
0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
|
||||
0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
|
||||
0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
|
||||
0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
|
||||
0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
|
||||
0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
|
||||
0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
|
||||
0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
|
||||
|
||||
static uint32_t SP6[64] = {
|
||||
0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
|
||||
0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
|
||||
0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
|
||||
0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
|
||||
0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
|
||||
0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
|
||||
0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
|
||||
0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
|
||||
0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
|
||||
0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
|
||||
0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
|
||||
0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
|
||||
0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
|
||||
0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
|
||||
0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
|
||||
0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
|
||||
|
||||
static uint32_t SP7[64] = {
|
||||
0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
|
||||
0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
|
||||
0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
|
||||
0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
|
||||
0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
|
||||
0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
|
||||
0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
|
||||
0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
|
||||
0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
|
||||
0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
|
||||
0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
|
||||
0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
|
||||
0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
|
||||
0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
|
||||
0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
|
||||
0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
|
||||
|
||||
static uint32_t SP8[64] = {
|
||||
0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
|
||||
0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
|
||||
0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
|
||||
0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
|
||||
0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
|
||||
0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
|
||||
0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
|
||||
0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
|
||||
0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
|
||||
0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
|
||||
0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
|
||||
0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
|
||||
0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
|
||||
0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
|
||||
0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
|
||||
0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
|
||||
|
||||
static void
|
||||
IP(uint32_t v[2])
|
||||
{
|
||||
uint32_t work;
|
||||
|
||||
work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
|
||||
v[1] ^= work;
|
||||
v[0] ^= (work << 4);
|
||||
work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
|
||||
v[1] ^= work;
|
||||
v[0] ^= (work << 16);
|
||||
work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
|
||||
v[0] ^= work;
|
||||
v[1] ^= (work << 2);
|
||||
work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
|
||||
v[0] ^= work;
|
||||
v[1] ^= (work << 8);
|
||||
v[1] = ((v[1] << 1) | ((v[1] >> 31) & 1L)) & 0xffffffffL;
|
||||
work = (v[0] ^ v[1]) & 0xaaaaaaaaL;
|
||||
v[0] ^= work;
|
||||
v[1] ^= work;
|
||||
v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
|
||||
}
|
||||
|
||||
static void
|
||||
FP(uint32_t v[2])
|
||||
{
|
||||
uint32_t work;
|
||||
|
||||
v[0] = (v[0] << 31) | (v[0] >> 1);
|
||||
work = (v[1] ^ v[0]) & 0xaaaaaaaaL;
|
||||
v[1] ^= work;
|
||||
v[0] ^= work;
|
||||
v[1] = (v[1] << 31) | (v[1] >> 1);
|
||||
work = ((v[1] >> 8) ^ v[0]) & 0x00ff00ffL;
|
||||
v[0] ^= work;
|
||||
v[1] ^= (work << 8);
|
||||
work = ((v[1] >> 2) ^ v[0]) & 0x33333333L;
|
||||
v[0] ^= work;
|
||||
v[1] ^= (work << 2);
|
||||
work = ((v[0] >> 16) ^ v[1]) & 0x0000ffffL;
|
||||
v[1] ^= work;
|
||||
v[0] ^= (work << 16);
|
||||
work = ((v[0] >> 4) ^ v[1]) & 0x0f0f0f0fL;
|
||||
v[1] ^= work;
|
||||
v[0] ^= (work << 4);
|
||||
}
|
||||
|
||||
static void
|
||||
desx(uint32_t block[2], DES_key_schedule *ks, int forward_encrypt)
|
||||
{
|
||||
uint32_t *keys;
|
||||
uint32_t fval, work, right, left;
|
||||
int round;
|
||||
|
||||
left = block[0];
|
||||
right = block[1];
|
||||
|
||||
if (forward_encrypt) {
|
||||
keys = &ks->ks[0];
|
||||
|
||||
for( round = 0; round < 8; round++ ) {
|
||||
work = (right << 28) | (right >> 4);
|
||||
work ^= *keys++;
|
||||
fval = SP7[ work & 0x3fL];
|
||||
fval |= SP5[(work >> 8) & 0x3fL];
|
||||
fval |= SP3[(work >> 16) & 0x3fL];
|
||||
fval |= SP1[(work >> 24) & 0x3fL];
|
||||
work = right ^ *keys++;
|
||||
fval |= SP8[ work & 0x3fL];
|
||||
fval |= SP6[(work >> 8) & 0x3fL];
|
||||
fval |= SP4[(work >> 16) & 0x3fL];
|
||||
fval |= SP2[(work >> 24) & 0x3fL];
|
||||
left ^= fval;
|
||||
work = (left << 28) | (left >> 4);
|
||||
work ^= *keys++;
|
||||
fval = SP7[ work & 0x3fL];
|
||||
fval |= SP5[(work >> 8) & 0x3fL];
|
||||
fval |= SP3[(work >> 16) & 0x3fL];
|
||||
fval |= SP1[(work >> 24) & 0x3fL];
|
||||
work = left ^ *keys++;
|
||||
fval |= SP8[ work & 0x3fL];
|
||||
fval |= SP6[(work >> 8) & 0x3fL];
|
||||
fval |= SP4[(work >> 16) & 0x3fL];
|
||||
fval |= SP2[(work >> 24) & 0x3fL];
|
||||
right ^= fval;
|
||||
}
|
||||
} else {
|
||||
keys = &ks->ks[30];
|
||||
|
||||
for( round = 0; round < 8; round++ ) {
|
||||
work = (right << 28) | (right >> 4);
|
||||
work ^= *keys++;
|
||||
fval = SP7[ work & 0x3fL];
|
||||
fval |= SP5[(work >> 8) & 0x3fL];
|
||||
fval |= SP3[(work >> 16) & 0x3fL];
|
||||
fval |= SP1[(work >> 24) & 0x3fL];
|
||||
work = right ^ *keys++;
|
||||
fval |= SP8[ work & 0x3fL];
|
||||
fval |= SP6[(work >> 8) & 0x3fL];
|
||||
fval |= SP4[(work >> 16) & 0x3fL];
|
||||
fval |= SP2[(work >> 24) & 0x3fL];
|
||||
left ^= fval;
|
||||
work = (left << 28) | (left >> 4);
|
||||
keys -= 4;
|
||||
work ^= *keys++;
|
||||
fval = SP7[ work & 0x3fL];
|
||||
fval |= SP5[(work >> 8) & 0x3fL];
|
||||
fval |= SP3[(work >> 16) & 0x3fL];
|
||||
fval |= SP1[(work >> 24) & 0x3fL];
|
||||
work = left ^ *keys++;
|
||||
fval |= SP8[ work & 0x3fL];
|
||||
fval |= SP6[(work >> 8) & 0x3fL];
|
||||
fval |= SP4[(work >> 16) & 0x3fL];
|
||||
fval |= SP2[(work >> 24) & 0x3fL];
|
||||
right ^= fval;
|
||||
keys -= 4;
|
||||
}
|
||||
}
|
||||
block[0] = right;
|
||||
block[1] = left;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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: des.h,v 1.25 2006/01/08 21:47:28 lha Exp $ */
|
||||
|
||||
#ifndef _DESperate_H
|
||||
#define _DESperate_H 1
|
||||
|
||||
/* symbol renaming */
|
||||
#define DES_set_odd_parity hc_DES_set_odd_parity
|
||||
#define DES_is_weak_key hc_DES_is_weak_key
|
||||
#define DES_key_sched hc_DES_key_sched
|
||||
#define DES_set_key hc_DES_set_key
|
||||
#define DES_set_key_checked hc_DES_set_key_checked
|
||||
#define DES_set_key_sched hc_DES_set_key_sched
|
||||
#define DES_new_random_key hc_DES_new_random_key
|
||||
#define DES_string_to_key hc_DES_string_to_key
|
||||
#define DES_read_password hc_DES_read_password
|
||||
#define DES_rand_data hc_DES_rand_data
|
||||
#define DES_set_random_generator_seed hc_DES_set_random_generator_seed
|
||||
#define DES_generate_random_block hc_DES_generate_random_block
|
||||
#define DES_set_sequence_number hc_DES_set_sequence_number
|
||||
#define DES_init_random_number_generator hc_DES_init_random_number_generator
|
||||
#define DES_random_key hc_DES_random_key
|
||||
#define DES_encrypt hc_DES_encrypt
|
||||
#define DES_ecb_encrypt hc_DES_ecb_encrypt
|
||||
#define DES_ecb3_encrypt hc_DES_ecb3_encrypt
|
||||
#define DES_pcbc_encrypt hc_DES_pcbc_encrypt
|
||||
#define DES_cbc_encrypt hc_DES_cbc_encrypt
|
||||
#define DES_cbc_cksum hc_DES_cbc_cksum
|
||||
#define DES_ede3_cbc_encrypt hc_DES_ede3_cbc_encrypt
|
||||
#define DES_cfb64_encrypt hc_DES_cfb64_encrypt
|
||||
#define _DES_ipfp_test _hc_DES_ipfp_test
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#define DES_CBLOCK_LEN 8
|
||||
#define DES_KEY_SZ 8
|
||||
|
||||
#define DES_ENCRYPT 1
|
||||
#define DES_DECRYPT 0
|
||||
|
||||
typedef unsigned char DES_cblock[DES_CBLOCK_LEN];
|
||||
typedef struct DES_key_schedule
|
||||
{
|
||||
uint32_t ks[32];
|
||||
} DES_key_schedule;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
int DES_set_odd_parity(DES_cblock *);
|
||||
int DES_is_weak_key(DES_cblock *);
|
||||
int DES_set_key(DES_cblock *, DES_key_schedule *);
|
||||
int DES_set_key_checked(DES_cblock *, DES_key_schedule *);
|
||||
int DES_key_sched(DES_cblock *, DES_key_schedule *);
|
||||
int DES_new_random_key(DES_cblock *);
|
||||
void DES_string_to_key(const char *, DES_cblock *);
|
||||
int DES_read_password(DES_cblock *, char *, int);
|
||||
|
||||
void DES_rand_data(void *, int);
|
||||
void DES_set_random_generator_seed(DES_cblock *);
|
||||
void DES_generate_random_block(DES_cblock *);
|
||||
void DES_set_sequence_number(void *);
|
||||
void DES_init_random_number_generator(DES_cblock *);
|
||||
void DES_random_key(DES_cblock *);
|
||||
|
||||
|
||||
void DES_encrypt(uint32_t [2], DES_key_schedule *, int);
|
||||
void DES_ecb_encrypt(DES_cblock *, DES_cblock *, DES_key_schedule *, int);
|
||||
void DES_ecb3_encrypt(DES_cblock *,DES_cblock *, DES_key_schedule *,
|
||||
DES_key_schedule *, DES_key_schedule *, int);
|
||||
void DES_pcbc_encrypt(const void *, void *, long,
|
||||
DES_key_schedule *, DES_cblock *, int);
|
||||
void DES_cbc_encrypt(const void *, void *, long,
|
||||
DES_key_schedule *, DES_cblock *, int);
|
||||
void DES_ede3_cbc_encrypt(const void *, void *, long,
|
||||
DES_key_schedule *, DES_key_schedule *,
|
||||
DES_key_schedule *, DES_cblock *, int);
|
||||
void DES_cfb64_encrypt(const void *, void *, long,
|
||||
DES_key_schedule *, DES_cblock *, int *, int);
|
||||
|
||||
|
||||
uint32_t DES_cbc_cksum(const void *, DES_cblock *,
|
||||
long, DES_key_schedule *, DES_cblock *);
|
||||
|
||||
|
||||
void _DES_ipfp_test(void);
|
||||
|
||||
|
||||
#endif /* _DESperate_H */
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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: dh.h,v 1.6 2006/05/06 13:11:15 lha Exp $
|
||||
*/
|
||||
|
||||
#ifndef _HEIM_DH_H
|
||||
#define _HEIM_DH_H 1
|
||||
|
||||
/* symbol renaming */
|
||||
#define DH_null_method hc_DH_null_method
|
||||
#define DH_imath_method hc_DH_imath_method
|
||||
#define DH_new hc_DH_new
|
||||
#define DH_new_method hc_DH_new_method
|
||||
#define DH_free hc_DH_free
|
||||
#define DH_up_ref hc_DH_up_ref
|
||||
#define DH_size hc_DH_size
|
||||
#define DH_set_default_method hc_DH_set_default_method
|
||||
#define DH_get_default_method hc_DH_get_default_method
|
||||
#define DH_set_method hc_DH_set_method
|
||||
#define DH_get_method hc_DH_get_method
|
||||
#define DH_set_ex_data hc_DH_set_ex_data
|
||||
#define DH_get_ex_data hc_DH_get_ex_data
|
||||
#define DH_generate_parameters_ex hc_DH_generate_parameters_ex
|
||||
#define DH_check_pubkey hc_DH_check_pubkey
|
||||
#define DH_generate_key hc_DH_generate_key
|
||||
#define DH_compute_key hc_DH_compute_key
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct DH DH;
|
||||
typedef struct DH_METHOD DH_METHOD;
|
||||
|
||||
#include <hcrypto/bn.h>
|
||||
#include <hcrypto/engine.h>
|
||||
|
||||
struct DH_METHOD {
|
||||
const char *name;
|
||||
int (*generate_key)(DH *);
|
||||
int (*compute_key)(unsigned char *,const BIGNUM *,DH *);
|
||||
int (*bn_mod_exp)(const DH *, BIGNUM *, const BIGNUM *,
|
||||
const BIGNUM *, const BIGNUM *, BN_CTX *,
|
||||
BN_MONT_CTX *);
|
||||
int (*init)(DH *);
|
||||
int (*finish)(DH *);
|
||||
int flags;
|
||||
void *app_data;
|
||||
int (*generate_params)(DH *, int, int, BN_GENCB *);
|
||||
};
|
||||
|
||||
struct DH {
|
||||
int pad;
|
||||
int version;
|
||||
BIGNUM *p;
|
||||
BIGNUM *g;
|
||||
long length;
|
||||
BIGNUM *pub_key;
|
||||
BIGNUM *priv_key;
|
||||
int flags;
|
||||
void *method_mont_p;
|
||||
BIGNUM *q;
|
||||
BIGNUM *j;
|
||||
void *seed;
|
||||
int seedlen;
|
||||
BIGNUM *counter;
|
||||
int references;
|
||||
struct CRYPTO_EX_DATA {
|
||||
void *sk;
|
||||
int dummy;
|
||||
} ex_data;
|
||||
const DH_METHOD *meth;
|
||||
ENGINE *engine;
|
||||
};
|
||||
|
||||
/* DH_check_pubkey return codes in `codes' argument. */
|
||||
#define DH_CHECK_PUBKEY_TOO_SMALL 1
|
||||
#define DH_CHECK_PUBKEY_TOO_LARGE 2
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
const DH_METHOD *DH_null_method(void);
|
||||
const DH_METHOD *DH_imath_method(void);
|
||||
|
||||
DH * DH_new(void);
|
||||
DH * DH_new_method(ENGINE *);
|
||||
void DH_free(DH *);
|
||||
int DH_up_ref(DH *);
|
||||
|
||||
int DH_size(const DH *);
|
||||
|
||||
|
||||
void DH_set_default_method(const DH_METHOD *);
|
||||
const DH_METHOD *
|
||||
DH_get_default_method(void);
|
||||
int DH_set_method(DH *, const DH_METHOD *);
|
||||
|
||||
int DH_set_ex_data(DH *, int, void *);
|
||||
void * DH_get_ex_data(DH *, int);
|
||||
|
||||
int DH_generate_parameters_ex(DH *, int, int, BN_GENCB *);
|
||||
int DH_check_pubkey(const DH *, const BIGNUM *, int *);
|
||||
int DH_generate_key(DH *);
|
||||
int DH_compute_key(unsigned char *,const BIGNUM *,DH *);
|
||||
|
||||
#endif /* _HEIM_DH_H */
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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: dsa.h,v 1.2 2006/01/13 15:26:52 lha Exp $
|
||||
*/
|
||||
|
||||
#ifndef _HEIM_DSA_H
|
||||
#define _HEIM_DSA_H 1
|
||||
|
||||
#include <hcrypto/bn.h>
|
||||
|
||||
/* symbol renaming */
|
||||
#define DSA_null_method hc_DSA_null_method
|
||||
#define DSA_new hc_DSA_new
|
||||
#define DSA_free hc_DSA_free
|
||||
#define DSA_up_ref hc_DSA_up_ref
|
||||
#define DSA_set_default_method hc_DSA_set_default_method
|
||||
#define DSA_get_default_method hc_DSA_get_default_method
|
||||
#define DSA_set_method hc_DSA_set_method
|
||||
#define DSA_get_method hc_DSA_get_method
|
||||
#define DSA_set_app_data hc_DSA_set_app_data
|
||||
#define DSA_get_app_data hc_DSA_get_app_data
|
||||
#define DSA_size hc_DSA_size
|
||||
#define DSA_verify hc_DSA_verify
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
typedef struct DSA DSA;
|
||||
typedef struct DSA_METHOD DSA_METHOD;
|
||||
typedef struct DSA_SIG DSA_SIG;
|
||||
|
||||
struct DSA_SIG {
|
||||
BIGNUM *r;
|
||||
BIGNUM *s;
|
||||
};
|
||||
|
||||
struct DSA_METHOD {
|
||||
const char *name;
|
||||
DSA_SIG * (*dsa_do_sign)(const unsigned char *, int, DSA *);
|
||||
int (*dsa_sign_setup)(DSA *, BN_CTX *, BIGNUM **, BIGNUM **);
|
||||
int (*dsa_do_verify)(const unsigned char *, int, DSA_SIG *, DSA *);
|
||||
int (*dsa_mod_exp)(DSA *, BIGNUM *, BIGNUM *, BIGNUM *,
|
||||
BIGNUM *, BIGNUM *, BIGNUM *, BN_CTX *,
|
||||
BN_MONT_CTX *);
|
||||
int (*bn_mod_exp)(DSA *, BIGNUM *, BIGNUM *, const BIGNUM *,
|
||||
const BIGNUM *, BN_CTX *,
|
||||
BN_MONT_CTX *);
|
||||
int (*init)(DSA *);
|
||||
int (*finish)(DSA *);
|
||||
int flags;
|
||||
void *app_data;
|
||||
};
|
||||
|
||||
struct DSA {
|
||||
int pad;
|
||||
long version;
|
||||
int write_params;
|
||||
BIGNUM *p;
|
||||
BIGNUM *q;
|
||||
BIGNUM *g;
|
||||
|
||||
BIGNUM *pub_key;
|
||||
BIGNUM *priv_key;
|
||||
|
||||
BIGNUM *kinv;
|
||||
BIGNUM *r;
|
||||
int flags;
|
||||
void *method_mont_p;
|
||||
int references;
|
||||
struct dsa_CRYPTO_EX_DATA {
|
||||
void *sk;
|
||||
int dummy;
|
||||
} ex_data;
|
||||
const DSA_METHOD *meth;
|
||||
void *engine;
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
const DSA_METHOD *DSA_null_method(void);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
DSA * DSA_new(void);
|
||||
void DSA_free(DSA *);
|
||||
int DSA_up_ref(DSA *);
|
||||
|
||||
void DSA_set_default_method(const DSA_METHOD *);
|
||||
const DSA_METHOD * DSA_get_default_method(void);
|
||||
|
||||
const DSA_METHOD * DSA_get_method(const DSA *);
|
||||
int DSA_set_method(DSA *, const DSA_METHOD *);
|
||||
|
||||
void DSA_set_app_data(DSA *, void *arg);
|
||||
void * DSA_get_app_data(DSA *);
|
||||
|
||||
int DSA_size(const DSA *);
|
||||
|
||||
int DSA_verify(int, const unsigned char *, int,
|
||||
const unsigned char *, int, DSA *);
|
||||
|
||||
#endif /* _HEIM_DSA_H */
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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: engine.h,v 1.6 2006/05/06 12:34:36 lha Exp $
|
||||
*/
|
||||
|
||||
#ifndef _HEIM_ENGINE_H
|
||||
#define _HEIM_ENGINE_H 1
|
||||
|
||||
/* symbol renaming */
|
||||
#define ENGINE_add_conf_module hc_ENGINE_add_conf_module
|
||||
#define ENGINE_by_dso hc_ENGINE_by_dso
|
||||
#define ENGINE_by_id hc_ENGINE_by_id
|
||||
#define ENGINE_finish hc_ENGINE_finish
|
||||
#define ENGINE_get_DH hc_ENGINE_get_DH
|
||||
#define ENGINE_get_RSA hc_ENGINE_get_RSA
|
||||
#define ENGINE_get_RAND hc_ENGINE_get_RAND
|
||||
#define ENGINE_get_id hc_ENGINE_get_id
|
||||
#define ENGINE_get_name hc_ENGINE_get_name
|
||||
#define ENGINE_load_builtin_engines hc_ENGINE_load_builtin_engines
|
||||
#define ENGINE_set_DH hc_ENGINE_set_DH
|
||||
#define ENGINE_set_RSA hc_ENGINE_set_RSA
|
||||
#define ENGINE_set_id hc_ENGINE_set_id
|
||||
#define ENGINE_set_name hc_ENGINE_set_name
|
||||
#define ENGINE_set_destroy_function hc_ENGINE_set_destroy_function
|
||||
#define ENGINE_up_ref hc_ENGINE_up_ref
|
||||
#define ENGINE_get_default_DH hc_ENGINE_get_default_DH
|
||||
#define ENGINE_get_default_RSA hc_ENGINE_get_default_RSA
|
||||
#define ENGINE_set_default_DH hc_ENGINE_set_default_DH
|
||||
#define ENGINE_set_default_RSA hc_ENGINE_set_default_RSA
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct hc_engine ENGINE;
|
||||
|
||||
#include <hcrypto/rsa.h>
|
||||
#include <hcrypto/dsa.h>
|
||||
#include <hcrypto/dh.h>
|
||||
#include <hcrypto/rand.h>
|
||||
|
||||
#define OPENSSL_DYNAMIC_VERSION (unsigned long)0x00020000
|
||||
|
||||
typedef int (*openssl_bind_engine)(ENGINE *, const char *, const void *);
|
||||
typedef unsigned long (*openssl_v_check)(unsigned long);
|
||||
|
||||
void ENGINE_add_conf_module(void);
|
||||
void ENGINE_load_builtin_engines(void);
|
||||
ENGINE *ENGINE_by_id(const char *);
|
||||
ENGINE *ENGINE_by_dso(const char *, const char *);
|
||||
int ENGINE_finish(ENGINE *);
|
||||
int ENGINE_up_ref(ENGINE *);
|
||||
int ENGINE_set_id(ENGINE *, const char *);
|
||||
int ENGINE_set_name(ENGINE *, const char *);
|
||||
int ENGINE_set_RSA(ENGINE *, const RSA_METHOD *);
|
||||
int ENGINE_set_DH(ENGINE *, const DH_METHOD *);
|
||||
int ENGINE_set_destroy_function(ENGINE *, void (*)(ENGINE *));
|
||||
|
||||
const char * ENGINE_get_id(const ENGINE *);
|
||||
const char * ENGINE_get_name(const ENGINE *);
|
||||
const RSA_METHOD * ENGINE_get_RSA(const ENGINE *);
|
||||
const DH_METHOD * ENGINE_get_DH(const ENGINE *);
|
||||
const RAND_METHOD * ENGINE_get_RAND(const ENGINE *);
|
||||
|
||||
int ENGINE_set_default_RSA(ENGINE *);
|
||||
ENGINE * ENGINE_get_default_RSA(void);
|
||||
int ENGINE_set_default_DH(ENGINE *);
|
||||
ENGINE * ENGINE_get_default_DH(void);
|
||||
|
||||
|
||||
#endif /* _HEIM_ENGINE_H */
|
||||
@@ -0,0 +1,905 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <evp.h>
|
||||
|
||||
#include <krb5-types.h>
|
||||
|
||||
#include <aes.h>
|
||||
#include <des.h>
|
||||
#include <sha.h>
|
||||
#include <rc2.h>
|
||||
#include <rc4.h>
|
||||
#include <md2.h>
|
||||
#include <md4.h>
|
||||
#include <md5.h>
|
||||
|
||||
typedef int (*evp_md_init)(EVP_MD_CTX *);
|
||||
typedef int (*evp_md_update)(EVP_MD_CTX *,const void *, size_t);
|
||||
typedef int (*evp_md_final)(void *, EVP_MD_CTX *);
|
||||
typedef int (*evp_md_cleanup)(EVP_MD_CTX *);
|
||||
|
||||
struct hc_evp_md {
|
||||
int hash_size;
|
||||
int block_size;
|
||||
int ctx_size;
|
||||
evp_md_init init;
|
||||
evp_md_update update;
|
||||
evp_md_final final;
|
||||
evp_md_cleanup cleanup;
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
size_t
|
||||
EVP_MD_size(const EVP_MD *md)
|
||||
{
|
||||
return md->hash_size;
|
||||
}
|
||||
|
||||
size_t
|
||||
EVP_MD_block_size(const EVP_MD *md)
|
||||
{
|
||||
return md->block_size;
|
||||
}
|
||||
|
||||
EVP_MD_CTX *
|
||||
EVP_MD_CTX_create(void)
|
||||
{
|
||||
return calloc(1, sizeof(EVP_MD_CTX));
|
||||
}
|
||||
|
||||
void
|
||||
EVP_MD_CTX_init(EVP_MD_CTX *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
void
|
||||
EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
|
||||
{
|
||||
EVP_MD_CTX_cleanup(ctx);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
int
|
||||
EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
|
||||
{
|
||||
if (ctx->md && ctx->md->cleanup)
|
||||
(ctx->md->cleanup)(ctx);
|
||||
ctx->md = NULL;
|
||||
ctx->engine = NULL;
|
||||
free(ctx->ptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
const EVP_MD *
|
||||
EVP_MD_CTX_md(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return ctx->md;
|
||||
}
|
||||
|
||||
size_t
|
||||
EVP_MD_CTX_size(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return EVP_MD_size(ctx->md);
|
||||
}
|
||||
|
||||
size_t
|
||||
EVP_MD_CTX_block_size(EVP_MD_CTX *ctx)
|
||||
{
|
||||
return EVP_MD_block_size(ctx->md);
|
||||
}
|
||||
|
||||
int
|
||||
EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *engine)
|
||||
{
|
||||
if (ctx->md != md || ctx->engine != engine) {
|
||||
EVP_MD_CTX_cleanup(ctx);
|
||||
ctx->md = md;
|
||||
ctx->engine = engine;
|
||||
|
||||
ctx->ptr = calloc(1, md->ctx_size);
|
||||
if (ctx->ptr == NULL)
|
||||
return 0;
|
||||
}
|
||||
(ctx->md->init)(ctx->ptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t size)
|
||||
{
|
||||
(ctx->md->update)(ctx->ptr, data, size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
EVP_DigestFinal_ex(EVP_MD_CTX *ctx, void *hash, unsigned int *size)
|
||||
{
|
||||
(ctx->md->final)(hash, ctx->ptr);
|
||||
if (size)
|
||||
*size = ctx->md->hash_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
EVP_Digest(const void *data, size_t dsize, void *hash, unsigned int *hsize,
|
||||
const EVP_MD *md, ENGINE *engine)
|
||||
{
|
||||
EVP_MD_CTX *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = EVP_MD_CTX_create();
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
ret = EVP_DigestInit_ex(ctx, md, engine);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
ret = EVP_DigestUpdate(ctx, data, dsize);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
ret = EVP_DigestFinal_ex(ctx, hash, hsize);
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
EVP_MD_CTX_destroy(ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
const EVP_MD *
|
||||
EVP_sha256(void)
|
||||
{
|
||||
static const struct hc_evp_md sha256 = {
|
||||
32,
|
||||
64,
|
||||
sizeof(SHA256_CTX),
|
||||
(evp_md_init)SHA256_Init,
|
||||
(evp_md_update)SHA256_Update,
|
||||
(evp_md_final)SHA256_Final,
|
||||
NULL
|
||||
};
|
||||
return &sha256;
|
||||
}
|
||||
|
||||
static const struct hc_evp_md sha1 = {
|
||||
20,
|
||||
64,
|
||||
sizeof(SHA_CTX),
|
||||
(evp_md_init)SHA1_Init,
|
||||
(evp_md_update)SHA1_Update,
|
||||
(evp_md_final)SHA1_Final,
|
||||
NULL
|
||||
};
|
||||
|
||||
const EVP_MD *
|
||||
EVP_sha1(void)
|
||||
{
|
||||
return &sha1;
|
||||
}
|
||||
|
||||
const EVP_MD *
|
||||
EVP_sha(void)
|
||||
{
|
||||
return &sha1;
|
||||
}
|
||||
|
||||
const EVP_MD *
|
||||
EVP_md5(void)
|
||||
{
|
||||
static const struct hc_evp_md md5 = {
|
||||
16,
|
||||
64,
|
||||
sizeof(MD5_CTX),
|
||||
(evp_md_init)MD5_Init,
|
||||
(evp_md_update)MD5_Update,
|
||||
(evp_md_final)MD5_Final,
|
||||
NULL
|
||||
};
|
||||
return &md5;
|
||||
}
|
||||
|
||||
const EVP_MD *
|
||||
EVP_md4(void)
|
||||
{
|
||||
static const struct hc_evp_md md4 = {
|
||||
16,
|
||||
64,
|
||||
sizeof(MD4_CTX),
|
||||
(evp_md_init)MD4_Init,
|
||||
(evp_md_update)MD4_Update,
|
||||
(evp_md_final)MD4_Final,
|
||||
NULL
|
||||
};
|
||||
return &md4;
|
||||
}
|
||||
|
||||
const EVP_MD *
|
||||
EVP_md2(void)
|
||||
{
|
||||
static const struct hc_evp_md md2 = {
|
||||
16,
|
||||
16,
|
||||
sizeof(MD2_CTX),
|
||||
(evp_md_init)MD2_Init,
|
||||
(evp_md_update)MD2_Update,
|
||||
(evp_md_final)MD2_Final,
|
||||
NULL
|
||||
};
|
||||
return &md2;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
null_Init (void *m)
|
||||
{
|
||||
}
|
||||
static void
|
||||
null_Update (void *m, const void * data, size_t size)
|
||||
{
|
||||
}
|
||||
static void
|
||||
null_Final(void *res, struct md5 *m)
|
||||
{
|
||||
}
|
||||
|
||||
const EVP_MD *
|
||||
EVP_md_null(void)
|
||||
{
|
||||
static const struct hc_evp_md null = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
(evp_md_init)null_Init,
|
||||
(evp_md_update)null_Update,
|
||||
(evp_md_final)null_Final,
|
||||
NULL
|
||||
};
|
||||
return &null;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
|
||||
int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
|
||||
int EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
|
||||
int EVP_SignFinal(EVP_MD_CTX *, void *, size_t *, EVP_PKEY *);
|
||||
int EVP_VerifyFinal(EVP_MD_CTX *, const void *, size_t, EVP_PKEY *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
size_t
|
||||
EVP_CIPHER_block_size(const EVP_CIPHER *c)
|
||||
{
|
||||
return c->block_size;
|
||||
}
|
||||
|
||||
size_t
|
||||
EVP_CIPHER_key_length(const EVP_CIPHER *c)
|
||||
{
|
||||
return c->key_len;
|
||||
}
|
||||
|
||||
size_t
|
||||
EVP_CIPHER_iv_length(const EVP_CIPHER *c)
|
||||
{
|
||||
return c->iv_len;
|
||||
}
|
||||
|
||||
void
|
||||
EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *c)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
}
|
||||
|
||||
int
|
||||
EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
|
||||
{
|
||||
if (c->cipher && c->cipher->cleanup)
|
||||
c->cipher->cleanup(c);
|
||||
if (c->cipher_data) {
|
||||
free(c->cipher_data);
|
||||
c->cipher_data = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return ctx->cipher;
|
||||
}
|
||||
|
||||
size_t
|
||||
EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return EVP_CIPHER_block_size(ctx->cipher);
|
||||
}
|
||||
|
||||
size_t
|
||||
EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return EVP_CIPHER_key_length(ctx->cipher);
|
||||
}
|
||||
|
||||
size_t
|
||||
EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return EVP_CIPHER_iv_length(ctx->cipher);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return ctx->cipher->flags;
|
||||
}
|
||||
|
||||
int
|
||||
EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_MODE;
|
||||
}
|
||||
|
||||
void *
|
||||
EVP_CIPHER_CTX_get_app_data(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return ctx->app_data;
|
||||
}
|
||||
|
||||
void
|
||||
EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
|
||||
{
|
||||
ctx->app_data = data;
|
||||
}
|
||||
|
||||
int
|
||||
EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine,
|
||||
const void *key, const void *iv, int encp)
|
||||
{
|
||||
if (encp == -1)
|
||||
encp = ctx->encrypt;
|
||||
else
|
||||
ctx->encrypt = (encp ? 1 : 0);
|
||||
|
||||
if (c && (c != ctx->cipher)) {
|
||||
EVP_CIPHER_CTX_cleanup(ctx);
|
||||
ctx->cipher = c;
|
||||
ctx->key_len = c->key_len;
|
||||
|
||||
ctx->cipher_data = malloc(c->ctx_size);
|
||||
if (ctx->cipher_data == NULL && c->ctx_size != 0)
|
||||
return 0;
|
||||
|
||||
} else if (ctx->cipher == NULL) {
|
||||
/* reuse of cipher, but not any cipher ever set! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (EVP_CIPHER_CTX_flags(ctx)) {
|
||||
case EVP_CIPH_CBC_MODE:
|
||||
|
||||
assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof(ctx->iv));
|
||||
|
||||
if (iv)
|
||||
memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
|
||||
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT))
|
||||
ctx->cipher->init(ctx, key, iv, encp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
EVP_Cipher(EVP_CIPHER_CTX *ctx, void *out, const void *in,size_t size)
|
||||
{
|
||||
return ctx->cipher->do_cipher(ctx, out, in, size);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
enc_null_init(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char * key,
|
||||
const unsigned char * iv,
|
||||
int encp)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
enc_null_do_cipher(EVP_CIPHER_CTX *ctx,
|
||||
unsigned char *out,
|
||||
const unsigned char *in,
|
||||
unsigned int size)
|
||||
{
|
||||
memmove(out, in, size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
enc_null_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_enc_null(void)
|
||||
{
|
||||
static const EVP_CIPHER enc_null = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
EVP_CIPH_CBC_MODE,
|
||||
enc_null_init,
|
||||
enc_null_do_cipher,
|
||||
enc_null_cleanup,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
return &enc_null;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
struct rc2_cbc {
|
||||
unsigned int maximum_effective_key;
|
||||
RC2_KEY key;
|
||||
};
|
||||
|
||||
static int
|
||||
rc2_init(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char * key,
|
||||
const unsigned char * iv,
|
||||
int encp)
|
||||
{
|
||||
struct rc2_cbc *k = ctx->cipher_data;
|
||||
k->maximum_effective_key = EVP_CIPHER_CTX_key_length(ctx) * 8;
|
||||
RC2_set_key(&k->key,
|
||||
EVP_CIPHER_CTX_key_length(ctx),
|
||||
key,
|
||||
k->maximum_effective_key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
rc2_do_cipher(EVP_CIPHER_CTX *ctx,
|
||||
unsigned char *out,
|
||||
const unsigned char *in,
|
||||
unsigned int size)
|
||||
{
|
||||
struct rc2_cbc *k = ctx->cipher_data;
|
||||
RC2_cbc_encrypt(in, out, size, &k->key, ctx->iv, ctx->encrypt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
rc2_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
memset(ctx->cipher_data, 0, sizeof(struct rc2_cbc));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_rc2_cbc(void)
|
||||
{
|
||||
static const EVP_CIPHER rc2_cbc = {
|
||||
0,
|
||||
RC2_BLOCK_SIZE,
|
||||
RC2_KEY_LENGTH,
|
||||
RC2_BLOCK_SIZE,
|
||||
EVP_CIPH_CBC_MODE,
|
||||
rc2_init,
|
||||
rc2_do_cipher,
|
||||
rc2_cleanup,
|
||||
sizeof(struct rc2_cbc),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
return &rc2_cbc;
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_rc2_40_cbc(void)
|
||||
{
|
||||
static const EVP_CIPHER rc2_40_cbc = {
|
||||
0,
|
||||
RC2_BLOCK_SIZE,
|
||||
5,
|
||||
RC2_BLOCK_SIZE,
|
||||
EVP_CIPH_CBC_MODE,
|
||||
rc2_init,
|
||||
rc2_do_cipher,
|
||||
rc2_cleanup,
|
||||
sizeof(struct rc2_cbc),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
return &rc2_40_cbc;
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_rc2_64_cbc(void)
|
||||
{
|
||||
static const EVP_CIPHER rc2_64_cbc = {
|
||||
0,
|
||||
RC2_BLOCK_SIZE,
|
||||
8,
|
||||
RC2_BLOCK_SIZE,
|
||||
EVP_CIPH_CBC_MODE,
|
||||
rc2_init,
|
||||
rc2_do_cipher,
|
||||
rc2_cleanup,
|
||||
sizeof(struct rc2_cbc),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
return &rc2_64_cbc;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_rc4(void)
|
||||
{
|
||||
printf("evp rc4\n");
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_rc4_40(void)
|
||||
{
|
||||
printf("evp rc4_40\n");
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
struct des_ede3_cbc {
|
||||
DES_key_schedule ks[3];
|
||||
};
|
||||
|
||||
static int
|
||||
des_ede3_cbc_init(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char * key,
|
||||
const unsigned char * iv,
|
||||
int encp)
|
||||
{
|
||||
struct des_ede3_cbc *k = ctx->cipher_data;
|
||||
|
||||
DES_key_sched((DES_cblock *)(key), &k->ks[0]);
|
||||
DES_key_sched((DES_cblock *)(key + 8), &k->ks[1]);
|
||||
DES_key_sched((DES_cblock *)(key + 16), &k->ks[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
des_ede3_cbc_do_cipher(EVP_CIPHER_CTX *ctx,
|
||||
unsigned char *out,
|
||||
const unsigned char *in,
|
||||
unsigned int size)
|
||||
{
|
||||
struct des_ede3_cbc *k = ctx->cipher_data;
|
||||
DES_ede3_cbc_encrypt(in, out, size,
|
||||
&k->ks[0], &k->ks[1], &k->ks[2],
|
||||
(DES_cblock *)ctx->iv, ctx->encrypt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
des_ede3_cbc_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
memset(ctx->cipher_data, 0, sizeof(struct des_ede3_cbc));
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_des_ede3_cbc(void)
|
||||
{
|
||||
static const EVP_CIPHER des_ede3_cbc = {
|
||||
0,
|
||||
8,
|
||||
24,
|
||||
8,
|
||||
EVP_CIPH_CBC_MODE,
|
||||
des_ede3_cbc_init,
|
||||
des_ede3_cbc_do_cipher,
|
||||
des_ede3_cbc_cleanup,
|
||||
sizeof(struct des_ede3_cbc),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
return &des_ede3_cbc;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
aes_init(EVP_CIPHER_CTX *ctx,
|
||||
const unsigned char * key,
|
||||
const unsigned char * iv,
|
||||
int encp)
|
||||
{
|
||||
AES_KEY *k = ctx->cipher_data;
|
||||
if (ctx->encrypt)
|
||||
AES_set_encrypt_key(key, ctx->cipher->key_len * 8, k);
|
||||
else
|
||||
AES_set_decrypt_key(key, ctx->cipher->key_len * 8, k);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_do_cipher(EVP_CIPHER_CTX *ctx,
|
||||
unsigned char *out,
|
||||
const unsigned char *in,
|
||||
unsigned int size)
|
||||
{
|
||||
AES_KEY *k = ctx->cipher_data;
|
||||
AES_cbc_encrypt(in, out, size, k, ctx->iv, ctx->encrypt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
aes_cleanup(EVP_CIPHER_CTX *ctx)
|
||||
{
|
||||
memset(ctx->cipher_data, 0, sizeof(AES_KEY));
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_aes_128_cbc(void)
|
||||
{
|
||||
static const EVP_CIPHER aes_128_cbc = {
|
||||
0,
|
||||
16,
|
||||
16,
|
||||
16,
|
||||
EVP_CIPH_CBC_MODE,
|
||||
aes_init,
|
||||
aes_do_cipher,
|
||||
aes_cleanup,
|
||||
sizeof(AES_KEY),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
return &aes_128_cbc;
|
||||
}
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_aes_192_cbc(void)
|
||||
{
|
||||
static const EVP_CIPHER aes_192_cbc = {
|
||||
0,
|
||||
16,
|
||||
24,
|
||||
16,
|
||||
EVP_CIPH_CBC_MODE,
|
||||
aes_init,
|
||||
aes_do_cipher,
|
||||
aes_cleanup,
|
||||
sizeof(AES_KEY),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
return &aes_192_cbc;
|
||||
}
|
||||
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_aes_256_cbc(void)
|
||||
{
|
||||
static const EVP_CIPHER aes_256_cbc = {
|
||||
0,
|
||||
16,
|
||||
32,
|
||||
16,
|
||||
EVP_CIPH_CBC_MODE,
|
||||
aes_init,
|
||||
aes_do_cipher,
|
||||
aes_cleanup,
|
||||
sizeof(AES_KEY),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
return &aes_256_cbc;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static const struct cipher_name {
|
||||
const char *name;
|
||||
const EVP_CIPHER *(*func)(void);
|
||||
} cipher_name[] = {
|
||||
{ "des-ede3-cbc", EVP_des_ede3_cbc },
|
||||
{ "aes-128-cbc", EVP_aes_128_cbc },
|
||||
{ "aes-192-cbc", EVP_aes_192_cbc },
|
||||
{ "aes-256-cbc", EVP_aes_256_cbc }
|
||||
};
|
||||
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_get_cipherbyname(const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(cipher_name)/sizeof(cipher_name[0]); i++) {
|
||||
if (strcasecmp(cipher_name[i].name, name) == 0)
|
||||
return (*cipher_name[i].func)();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a)>(b))?(b):(a))
|
||||
#endif
|
||||
|
||||
int
|
||||
EVP_BytesToKey(const EVP_CIPHER *type,
|
||||
const EVP_MD *md,
|
||||
const void *salt,
|
||||
const void *data, size_t datalen,
|
||||
unsigned int count,
|
||||
void *keydata,
|
||||
void *ivdata)
|
||||
{
|
||||
int ivlen, keylen, first = 0;
|
||||
unsigned int mds = 0, i;
|
||||
unsigned char *key = keydata;
|
||||
unsigned char *iv = ivdata;
|
||||
unsigned char *buf;
|
||||
EVP_MD_CTX c;
|
||||
|
||||
keylen = EVP_CIPHER_key_length(type);
|
||||
ivlen = EVP_CIPHER_iv_length(type);
|
||||
|
||||
if (data == NULL)
|
||||
return keylen;
|
||||
|
||||
buf = malloc(EVP_MD_size(md));
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
EVP_MD_CTX_init(&c);
|
||||
|
||||
first = 1;
|
||||
while (1) {
|
||||
EVP_DigestInit_ex(&c, md, NULL);
|
||||
if (!first)
|
||||
EVP_DigestUpdate(&c, buf, mds);
|
||||
first = 0;
|
||||
EVP_DigestUpdate(&c,data,datalen);
|
||||
|
||||
#define PKCS5_SALT_LEN 8
|
||||
|
||||
if (salt)
|
||||
EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN);
|
||||
|
||||
EVP_DigestFinal_ex(&c, buf, &mds);
|
||||
assert(mds == EVP_MD_size(md));
|
||||
|
||||
for (i = 1; i < count; i++) {
|
||||
EVP_DigestInit_ex(&c, md, NULL);
|
||||
EVP_DigestUpdate(&c, buf, mds);
|
||||
EVP_DigestFinal_ex(&c, buf, &mds);
|
||||
assert(mds == EVP_MD_size(md));
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if (keylen) {
|
||||
size_t sz = min(keylen, mds);
|
||||
if (key) {
|
||||
memcpy(key, buf, sz);
|
||||
key += sz;
|
||||
}
|
||||
keylen -= sz;
|
||||
i += sz;
|
||||
}
|
||||
if (ivlen && mds > i) {
|
||||
size_t sz = min(ivlen, (mds - i));
|
||||
if (iv) {
|
||||
memcpy(iv, &buf[i], sz);
|
||||
iv += sz;
|
||||
}
|
||||
ivlen -= sz;
|
||||
}
|
||||
if (keylen == 0 && ivlen == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_cleanup(&c);
|
||||
free(buf);
|
||||
|
||||
return EVP_CIPHER_key_length(type);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
OpenSSL_add_all_algorithms(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
OpenSSL_add_all_algorithms_conf(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
OpenSSL_add_all_algorithms_noconf(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (c) 2005 - 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: evp.h,v 1.11 2006/10/07 17:21:24 lha Exp $ */
|
||||
|
||||
#ifndef HEIM_EVP_H
|
||||
#define HEIM_EVP_H 1
|
||||
|
||||
#include <hcrypto/engine.h>
|
||||
|
||||
/* symbol renaming */
|
||||
#define EVP_CIPHER_CTX_block_size hc_EVP_CIPHER_CTX_block_size
|
||||
#define EVP_CIPHER_CTX_cipher hc_EVP_CIPHER_CTX_cipher
|
||||
#define EVP_CIPHER_CTX_cleanup hc_EVP_CIPHER_CTX_cleanup
|
||||
#define EVP_CIPHER_CTX_flags hc_EVP_CIPHER_CTX_flags
|
||||
#define EVP_CIPHER_CTX_get_app_data hc_EVP_CIPHER_CTX_get_app_data
|
||||
#define EVP_CIPHER_CTX_init hc_EVP_CIPHER_CTX_init
|
||||
#define EVP_CIPHER_CTX_iv_length hc_EVP_CIPHER_CTX_iv_length
|
||||
#define EVP_CIPHER_CTX_key_length hc_EVP_CIPHER_CTX_key_length
|
||||
#define EVP_CIPHER_CTX_mode hc_EVP_CIPHER_CTX_mode
|
||||
#define EVP_CIPHER_CTX_set_app_data hc_EVP_CIPHER_CTX_set_app_data
|
||||
#define EVP_CIPHER_CTX_set_key_length hc_EVP_CIPHER_CTX_set_key_length
|
||||
#define EVP_CIPHER_CTX_set_padding hc_EVP_CIPHER_CTX_set_padding
|
||||
#define EVP_CIPHER_block_size hc_EVP_CIPHER_block_size
|
||||
#define EVP_CIPHER_iv_length hc_EVP_CIPHER_iv_length
|
||||
#define EVP_CIPHER_key_length hc_EVP_CIPHER_key_length
|
||||
#define EVP_Cipher hc_EVP_Cipher
|
||||
#define EVP_CipherInit_ex hc_EVP_CipherInit_ex
|
||||
#define EVP_Digest hc_EVP_Digest
|
||||
#define EVP_DigestFinal_ex hc_EVP_DigestFinal_ex
|
||||
#define EVP_DigestInit_ex hc_EVP_DigestInit_ex
|
||||
#define EVP_DigestUpdate hc_EVP_DigestUpdate
|
||||
#define EVP_MD_CTX_block_size hc_EVP_MD_CTX_block_size
|
||||
#define EVP_MD_CTX_cleanup hc_EVP_MD_CTX_cleanup
|
||||
#define EVP_MD_CTX_create hc_EVP_MD_CTX_create
|
||||
#define EVP_MD_CTX_init hc_EVP_MD_CTX_init
|
||||
#define EVP_MD_CTX_destroy hc_EVP_MD_CTX_destroy
|
||||
#define EVP_MD_CTX_md hc_EVP_MD_CTX_md
|
||||
#define EVP_MD_CTX_size hc_EVP_MD_CTX_size
|
||||
#define EVP_MD_block_size hc_EVP_MD_block_size
|
||||
#define EVP_MD_size hc_EVP_MD_size
|
||||
#define EVP_aes_128_cbc hc_EVP_aes_128_cbc
|
||||
#define EVP_aes_192_cbc hc_EVP_aes_192_cbc
|
||||
#define EVP_aes_256_cbc hc_EVP_aes_256_cbc
|
||||
#define EVP_des_ede3_cbc hc_EVP_des_ede3_cbc
|
||||
#define EVP_enc_null hc_EVP_enc_null
|
||||
#define EVP_md2 hc_EVP_md2
|
||||
#define EVP_md4 hc_EVP_md4
|
||||
#define EVP_md5 hc_EVP_md5
|
||||
#define EVP_md_null hc_EVP_md_null
|
||||
#define EVP_rc2_40_cbc hc_EVP_rc2_40_cbc
|
||||
#define EVP_rc2_64_cbc hc_EVP_rc2_64_cbc
|
||||
#define EVP_rc2_cbc hc_EVP_rc2_cbc
|
||||
#define EVP_rc4 hc_EVP_rc4
|
||||
#define EVP_rc4_40 hc_EVP_rc4_40
|
||||
#define EVP_sha hc_EVP_sha
|
||||
#define EVP_sha1 hc_EVP_sha1
|
||||
#define EVP_sha256 hc_EVP_sha256
|
||||
#define PKCS5_PBKDF2_HMAC_SHA1 hc_PKCS5_PBKDF2_HMAC_SHA1
|
||||
#define EVP_BytesToKey hc_EVP_BytesToKey
|
||||
#define EVP_get_cipherbyname hc_EVP_get_cipherbyname
|
||||
#define OpenSSL_add_all_algorithms hc_OpenSSL_add_all_algorithms
|
||||
#define OpenSSL_add_all_algorithms_conf hc_OpenSSL_add_all_algorithms_conf
|
||||
#define OpenSSL_add_all_algorithms_noconf hc_OpenSSL_add_all_algorithms_noconf
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct hc_EVP_MD_CTX EVP_MD_CTX;
|
||||
typedef struct hc_evp_pkey EVP_PKEY;
|
||||
typedef struct hc_evp_md EVP_MD;
|
||||
typedef struct hc_CIPHER EVP_CIPHER;
|
||||
typedef struct hc_CIPHER_CTX EVP_CIPHER_CTX;
|
||||
|
||||
#define EVP_MAX_IV_LENGTH 16
|
||||
#define EVP_MAX_BLOCK_LENGTH 32
|
||||
|
||||
#define EVP_MAX_MD_SIZE 64
|
||||
|
||||
struct hc_CIPHER {
|
||||
int nid;
|
||||
int block_size;
|
||||
int key_len;
|
||||
int iv_len;
|
||||
unsigned long flags;
|
||||
/* The lowest 3 bits is used as integer field for the mode the
|
||||
* cipher is used in (use EVP_CIPHER.._mode() to extract the
|
||||
* mode). The rest of the flag field is a bitfield.
|
||||
*/
|
||||
#define EVP_CIPH_CBC_MODE 2
|
||||
#define EVP_CIPH_MODE 0x7
|
||||
|
||||
#define EVP_CIPH_ALWAYS_CALL_INIT 0x20
|
||||
|
||||
int (*init)(EVP_CIPHER_CTX*,const unsigned char*,const unsigned char*,int);
|
||||
int (*do_cipher)(EVP_CIPHER_CTX *, unsigned char *,
|
||||
const unsigned char *, unsigned int);
|
||||
int (*cleanup)(EVP_CIPHER_CTX *);
|
||||
int ctx_size;
|
||||
void *set_asn1_parameters;
|
||||
void *get_asn1_parameters;
|
||||
void *ctrl;
|
||||
void *app_data;
|
||||
};
|
||||
|
||||
struct hc_CIPHER_CTX {
|
||||
const EVP_CIPHER *cipher;
|
||||
ENGINE *engine;
|
||||
int encrypt;
|
||||
int buf_len;
|
||||
unsigned char oiv[EVP_MAX_IV_LENGTH];
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH];
|
||||
unsigned char buf[EVP_MAX_BLOCK_LENGTH];
|
||||
int num;
|
||||
void *app_data;
|
||||
int key_len;
|
||||
unsigned long flags;
|
||||
void *cipher_data;
|
||||
int final_used;
|
||||
int block_mask;
|
||||
unsigned char final[EVP_MAX_BLOCK_LENGTH];
|
||||
};
|
||||
|
||||
struct hc_EVP_MD_CTX {
|
||||
const EVP_MD *md;
|
||||
ENGINE *engine;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
/*
|
||||
* Avaible crypto algs
|
||||
*/
|
||||
|
||||
const EVP_MD *EVP_md_null(void);
|
||||
const EVP_MD *EVP_md2(void);
|
||||
const EVP_MD *EVP_md4(void);
|
||||
const EVP_MD *EVP_md5(void);
|
||||
const EVP_MD *EVP_sha(void);
|
||||
const EVP_MD *EVP_sha1(void);
|
||||
const EVP_MD *EVP_sha256(void);
|
||||
|
||||
const EVP_CIPHER * EVP_aes_128_cbc(void);
|
||||
const EVP_CIPHER * EVP_aes_192_cbc(void);
|
||||
const EVP_CIPHER * EVP_aes_256_cbc(void);
|
||||
const EVP_CIPHER * EVP_des_ede3_cbc(void);
|
||||
const EVP_CIPHER * EVP_enc_null(void);
|
||||
const EVP_CIPHER * EVP_rc2_40_cbc(void);
|
||||
const EVP_CIPHER * EVP_rc2_64_cbc(void);
|
||||
const EVP_CIPHER * EVP_rc2_cbc(void);
|
||||
const EVP_CIPHER * EVP_rc4(void);
|
||||
const EVP_CIPHER * EVP_rc4_40(void);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
size_t EVP_MD_size(const EVP_MD *);
|
||||
size_t EVP_MD_block_size(const EVP_MD *);
|
||||
|
||||
const EVP_MD *
|
||||
EVP_MD_CTX_md(EVP_MD_CTX *);
|
||||
size_t EVP_MD_CTX_size(EVP_MD_CTX *);
|
||||
size_t EVP_MD_CTX_block_size(EVP_MD_CTX *);
|
||||
|
||||
EVP_MD_CTX *
|
||||
EVP_MD_CTX_create(void);
|
||||
void EVP_MD_CTX_init(EVP_MD_CTX *);
|
||||
void EVP_MD_CTX_destroy(EVP_MD_CTX *);
|
||||
int EVP_MD_CTX_cleanup(EVP_MD_CTX *);
|
||||
|
||||
int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *);
|
||||
int EVP_DigestUpdate(EVP_MD_CTX *,const void *, size_t);
|
||||
int EVP_DigestFinal_ex(EVP_MD_CTX *, void *, unsigned int *);
|
||||
int EVP_Digest(const void *, size_t, void *, unsigned int *,
|
||||
const EVP_MD *, ENGINE *);
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_get_cipherbyname(const char *);
|
||||
|
||||
size_t EVP_CIPHER_block_size(const EVP_CIPHER *);
|
||||
size_t EVP_CIPHER_key_length(const EVP_CIPHER *);
|
||||
size_t EVP_CIPHER_iv_length(const EVP_CIPHER *);
|
||||
|
||||
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *);
|
||||
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *);
|
||||
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *, int);
|
||||
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *, int);
|
||||
unsigned long
|
||||
EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *);
|
||||
int EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *);
|
||||
|
||||
const EVP_CIPHER *
|
||||
EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *);
|
||||
size_t EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *);
|
||||
size_t EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *);
|
||||
size_t EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *);
|
||||
void * EVP_CIPHER_CTX_get_app_data(EVP_CIPHER_CTX *);
|
||||
void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *, void *);
|
||||
|
||||
int EVP_CipherInit_ex(EVP_CIPHER_CTX *,const EVP_CIPHER *, ENGINE *,
|
||||
const void *, const void *, int);
|
||||
|
||||
int EVP_Cipher(EVP_CIPHER_CTX *,void *,const void *,size_t);
|
||||
|
||||
int PKCS5_PBKDF2_HMAC_SHA1(const void *, size_t, const void *, size_t,
|
||||
unsigned long, size_t, void *);
|
||||
|
||||
int EVP_BytesToKey(const EVP_CIPHER *, const EVP_MD *,
|
||||
const void *, const void *, size_t,
|
||||
unsigned int, void *, void *);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
void OpenSSL_add_all_algorithms(void);
|
||||
void OpenSSL_add_all_algorithms_conf(void);
|
||||
void OpenSSL_add_all_algorithms_noconf(void);
|
||||
|
||||
#endif /* HEIM_EVP_H */
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of KTH nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
/* $Id: hash.h,v 1.4 2006/05/05 11:06:49 lha Exp $ */
|
||||
|
||||
/* stuff in common between md4, md5, and sha1 */
|
||||
|
||||
#ifndef __hash_h__
|
||||
#define __hash_h__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#ifdef KRB5
|
||||
#include <krb5-types.h>
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) (((a)>(b))?(b):(a))
|
||||
#endif
|
||||
|
||||
/* Vector Crays doesn't have a good 32-bit type, or more precisely,
|
||||
int32_t as defined by <bind/bitypes.h> isn't 32 bits, and we don't
|
||||
want to depend in being able to redefine this type. To cope with
|
||||
this we have to clamp the result in some places to [0,2^32); no
|
||||
need to do this on other machines. Did I say this was a mess?
|
||||
*/
|
||||
|
||||
#ifdef _CRAY
|
||||
#define CRAYFIX(X) ((X) & 0xffffffff)
|
||||
#else
|
||||
#define CRAYFIX(X) (X)
|
||||
#endif
|
||||
|
||||
static inline uint32_t
|
||||
cshift (uint32_t x, unsigned int n)
|
||||
{
|
||||
x = CRAYFIX(x);
|
||||
return CRAYFIX((x << n) | (x >> (32 - n)));
|
||||
}
|
||||
|
||||
#endif /* __hash_h__ */
|
||||
@@ -0,0 +1,122 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <hmac.h>
|
||||
|
||||
void
|
||||
HMAC_CTX_init(HMAC_CTX *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
void
|
||||
HMAC_CTX_cleanup(HMAC_CTX *ctx)
|
||||
{
|
||||
if (ctx->buf) {
|
||||
memset(ctx->buf, 0, ctx->key_length);
|
||||
free(ctx->buf);
|
||||
ctx->buf = NULL;
|
||||
}
|
||||
if (ctx->opad) {
|
||||
memset(ctx->ipad, 0, ctx->key_length);
|
||||
free(ctx->opad);
|
||||
ctx->opad = NULL;
|
||||
}
|
||||
if (ctx->ipad) {
|
||||
memset(ctx->ipad, 0, ctx->key_length);
|
||||
free(ctx->ipad);
|
||||
ctx->ipad = NULL;
|
||||
}
|
||||
if (ctx->ctx) {
|
||||
EVP_MD_CTX_destroy(ctx->ctx);
|
||||
ctx->ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
HMAC_size(const HMAC_CTX *ctx)
|
||||
{
|
||||
return EVP_MD_size(ctx->md);
|
||||
}
|
||||
|
||||
void
|
||||
HMAC_Init_ex(HMAC_CTX *ctx,
|
||||
const void *key,
|
||||
size_t keylen,
|
||||
const EVP_MD *md,
|
||||
ENGINE *engine)
|
||||
{
|
||||
unsigned char *p;
|
||||
size_t i;
|
||||
|
||||
if (ctx->md != md) {
|
||||
ctx->md = md;
|
||||
if (ctx->buf)
|
||||
free (ctx->buf);
|
||||
ctx->key_length = EVP_MD_size(ctx->md);
|
||||
ctx->buf = malloc(ctx->key_length);
|
||||
}
|
||||
#if 0
|
||||
ctx->engine = engine;
|
||||
#endif
|
||||
|
||||
if (keylen > EVP_MD_block_size(ctx->md)) {
|
||||
EVP_Digest(key, keylen, ctx->buf, NULL, ctx->md, engine);
|
||||
key = ctx->buf;
|
||||
keylen = EVP_MD_size(ctx->md);
|
||||
}
|
||||
|
||||
if (ctx->opad)
|
||||
free(ctx->opad);
|
||||
if (ctx->ipad)
|
||||
free(ctx->ipad);
|
||||
|
||||
ctx->opad = malloc(EVP_MD_block_size(ctx->md));
|
||||
ctx->ipad = malloc(EVP_MD_block_size(ctx->md));
|
||||
memset(ctx->ipad, 0x36, EVP_MD_block_size(ctx->md));
|
||||
memset(ctx->opad, 0x5c, EVP_MD_block_size(ctx->md));
|
||||
|
||||
for (i = 0, p = ctx->ipad; i < keylen; i++)
|
||||
p[i] ^= ((const unsigned char *)key)[i];
|
||||
for (i = 0, p = ctx->opad; i < keylen; i++)
|
||||
p[i] ^= ((const unsigned char *)key)[i];
|
||||
|
||||
ctx->ctx = EVP_MD_CTX_create();
|
||||
|
||||
EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
|
||||
EVP_DigestUpdate(ctx->ctx, ctx->ipad, EVP_MD_block_size(ctx->md));
|
||||
}
|
||||
|
||||
void
|
||||
HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len)
|
||||
{
|
||||
EVP_DigestUpdate(ctx->ctx, data, len);
|
||||
}
|
||||
|
||||
void
|
||||
HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len)
|
||||
{
|
||||
EVP_DigestFinal_ex(ctx->ctx, ctx->buf, NULL);
|
||||
|
||||
EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
|
||||
EVP_DigestUpdate(ctx->ctx, ctx->opad, EVP_MD_block_size(ctx->md));
|
||||
EVP_DigestUpdate(ctx->ctx, ctx->buf, ctx->key_length);
|
||||
EVP_DigestFinal_ex(ctx->ctx, md, len);
|
||||
}
|
||||
|
||||
void *
|
||||
HMAC(const EVP_MD *md,
|
||||
const void *key, size_t key_size,
|
||||
const void *data, size_t data_size,
|
||||
void *hash, unsigned int *hash_len)
|
||||
{
|
||||
HMAC_CTX ctx;
|
||||
|
||||
HMAC_CTX_init(&ctx);
|
||||
HMAC_Init_ex(&ctx, key, key_size, md, NULL);
|
||||
HMAC_Update(&ctx, data, data_size);
|
||||
HMAC_Final(&ctx, hash, hash_len);
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
return hash;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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: hmac.h,v 1.3 2006/01/13 15:26:52 lha Exp $ */
|
||||
|
||||
#ifndef HEIM_HMAC_H
|
||||
#define HEIM_HMAC_H 1
|
||||
|
||||
#include <hcrypto/evp.h>
|
||||
|
||||
/* symbol renaming */
|
||||
#define HMAC_CTX_init hc_HMAC_CTX_init
|
||||
#define HMAC_CTX_cleanup hc_HMAC_CTX_cleanup
|
||||
#define HMAC_size hc_HMAC_size
|
||||
#define HMAC_Init_ex hc_HMAC_Init_ex
|
||||
#define HMAC_Update hc_HMAC_Update
|
||||
#define HMAC_Final hc_HMAC_Final
|
||||
#define HMAC hc_HMAC
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#define HMAC_MAX_MD_CBLOCK 64
|
||||
|
||||
typedef struct hc_HMAC_CTX HMAC_CTX;
|
||||
|
||||
struct hc_HMAC_CTX {
|
||||
const EVP_MD *md;
|
||||
ENGINE *engine;
|
||||
EVP_MD_CTX *ctx;
|
||||
size_t key_length;
|
||||
void *opad;
|
||||
void *ipad;
|
||||
void *buf;
|
||||
};
|
||||
|
||||
|
||||
void HMAC_CTX_init(HMAC_CTX *);
|
||||
void HMAC_CTX_cleanup(HMAC_CTX *ctx);
|
||||
|
||||
size_t HMAC_size(const HMAC_CTX *ctx);
|
||||
|
||||
void HMAC_Init_ex(HMAC_CTX *, const void *, size_t,
|
||||
const EVP_MD *, ENGINE *);
|
||||
void HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len);
|
||||
void HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len);
|
||||
|
||||
void * HMAC(const EVP_MD *evp_md, const void *key, size_t key_len,
|
||||
const void *data, size_t n, void *md, unsigned int *md_len);
|
||||
|
||||
#endif /* HEIM_HMAC_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user