Make OpenSSL an hcrypto backend proper
authorNicolas Williams <nico@twosigma.com>
Wed, 13 Apr 2016 17:44:58 +0000 (12:44 -0500)
committerNicolas Williams <nico@twosigma.com>
Fri, 15 Apr 2016 05:16:17 +0000 (00:16 -0500)
This adds a new backend for libhcrypto: the OpenSSL backend.

Now libhcrypto has these backends:

 - hcrypto itself (i.e., the algorithms coded in lib/hcrypto)
 - Common Crypto (OS X)
 - PKCS#11 (specifically for Solaris, but not Solaris-specific)
 - Windows CNG (Windows)
 - OpenSSL (generic)

The ./configure --with-openssl=... option no longer disables the use of
hcrypto.  Instead it enables the use of OpenSSL as a (and the default)
backend in libhcrypto.  The libhcrypto framework is now always used.

OpenSSL should no longer be used directly within Heimdal, except in the
OpenSSL hcrypto backend itself, and files where elliptic curve (EC)
crypto is needed.

Because libhcrypto's EC support is incomplete, we can only use OpenSSL
for EC.  Currently that means separating all EC-using code so that it
does not use hcrypto, thus the libhx509/hxtool and PKINIT EC code has
been moved out of the files it used to be in.

60 files changed:
admin/Makefile.am
appl/ftp/ftp/Makefile.am
appl/otp/Makefile.am
appl/su/Makefile.am
cf/crypto.m4
include/config.h.w32
include/crypto-headers.h
include/hcrypto/Makefile.am
include/heim_threads.h
kadmin/Makefile.am
kcm/Makefile.am
kdc/Makefile.am
kdc/NTMakefile
kdc/pkinit-ec.c [new file with mode: 0644]
kdc/pkinit.c
kpasswd/Makefile.am
kuser/Makefile.am
lib/NTMakefile
lib/base/test_base.c
lib/gssapi/Makefile.am
lib/gssapi/ntlm/crypto.c
lib/hcrypto/Makefile.am
lib/hcrypto/NTMakefile
lib/hcrypto/bn.h
lib/hcrypto/dh.h
lib/hcrypto/dsa.h
lib/hcrypto/ec.h
lib/hcrypto/engine.h
lib/hcrypto/evp-openssl.c [new file with mode: 0644]
lib/hcrypto/evp-openssl.h [new file with mode: 0644]
lib/hcrypto/evp-pkcs11.c
lib/hcrypto/evp.c
lib/hcrypto/evp.h
lib/hcrypto/libhcrypto-exports.def
lib/hcrypto/mdtest.c
lib/hcrypto/rand.h
lib/hcrypto/rsa.h
lib/hcrypto/test_cipher.c
lib/hcrypto/version-script.map
lib/hdb/Makefile.am
lib/hx509/Makefile.am
lib/hx509/NTMakefile
lib/hx509/crypto-ec.c [new file with mode: 0644]
lib/hx509/crypto.c
lib/hx509/hx_locl.h
lib/hx509/hxtool.c
lib/hx509/ks_file.c
lib/kafs/Makefile.am
lib/krb5/Makefile.am
lib/krb5/NTMakefile
lib/krb5/aes-test.c
lib/krb5/crypto.h
lib/krb5/krb5_locl.h
lib/krb5/pkinit-ec.c [new file with mode: 0644]
lib/krb5/pkinit.c
lib/ntlm/Makefile.am
lib/otp/Makefile.am
tools/Makefile.am
tools/krb5-config.in
windows/NTMakefile.config

index 21d01578027b5719ab98889697aaef907c037c3a..a4a7bb4c0f911e478760fefaac1b6ea6a92e385a 100644 (file)
@@ -2,7 +2,7 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_readline) $(INCLUDE_hcrypto)
+AM_CPPFLAGS += $(INCLUDE_readline)
 
 man_MANS = ktutil.1
 
index 8bda036e5f5f0175e73c5c58ec762a3b5f8552cd..e68c7d2915048179321d6abdad8f331280e6d15d 100644 (file)
@@ -4,7 +4,7 @@ include $(top_srcdir)/Makefile.am.common
 
 WFLAGS += $(WFLAGS_LITE)
 
-AM_CPPFLAGS += -I$(srcdir)/../common $(INCLUDE_readline) $(INCLUDE_hcrypto)
+AM_CPPFLAGS += -I$(srcdir)/../common $(INCLUDE_readline)
 
 bin_PROGRAMS = ftp
 
index 07ab13882b25dbbd3705ad55e3e26ef360de8cf0..d8e5d51ddbccdfd799786df396809b5897ac75cd 100644 (file)
@@ -2,8 +2,6 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_hcrypto)
-
 bin_PROGRAMS = otp otpprint
 bin_SUIDS = otp
 otp_SOURCES = otp.c otp_locl.h
index 0a942ee7db8c335f661b762fc00343fb6634f007..605aae349bc271979fbd02a7a26992590f1d2a16 100644 (file)
@@ -2,8 +2,6 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_hcrypto)
-
 bin_PROGRAMS = su
 bin_SUIDS = su
 su_SOURCES = su.c supaths.h
index a0b033ff02136d812f45a3ed35a21468fc4e7806..b3a1bd0c31a404ba4204a6110703a309bc9e3ae6 100644 (file)
@@ -6,7 +6,7 @@ dnl - own-built libhcrypto
 
 m4_define([test_headers], [
                #undef KRB5 /* makes md4.h et al unhappy */
-               #ifdef HAVE_OPENSSL
+               #ifdef HAVE_HCRYPTO_W_OPENSSL
                #ifdef HAVE_SYS_TYPES_H
                #include <sys/types.h>
                #endif
@@ -54,7 +54,7 @@ m4_define([test_body], [
                EVP_CIPHER_iv_length(((EVP_CIPHER*)0));
                UI_UTIL_read_pw_string(0,0,0,0);
                RAND_status();
-               #ifdef HAVE_OPENSSL
+               #ifdef HAVE_HCRYPTO_W_OPENSSL
                EC_KEY_new();
                #endif
 
@@ -63,77 +63,53 @@ m4_define([test_body], [
                DES_cbc_encrypt(0, 0, 0, schedule, 0, 0);
                RC4(0, 0, 0, 0);])
 
-m4_define([bn_headers], [
-               #include <stdlib.h>
-               #include <openssl/bn.h>
-               ])
-m4_define([bn_body], [
-               BIGNUM *bn = BN_new();
-               BN_set_word(bn, 1);
-               if (BN_is_negative(bn))
-                       exit(EXIT_FAILURE);
-               BN_set_negative(bn, 1);
-               if (!BN_is_negative(bn))
-                       exit(EXIT_FAILURE);
-               exit(EXIT_SUCCESS);
-               ])
-
 AC_DEFUN([KRB_CRYPTO],[
-crypto_lib=unknown
 AC_WITH_ALL([openssl])
 
-DIR_hcrypto=
-
 AC_MSG_CHECKING([for crypto library])
 
 openssl=no
 
-if test "$crypto_lib" = "unknown" -a "$with_openssl" != "no"; then
-       save_CFLAGS="$CFLAGS"
-       save_LIBS="$LIBS"
-       INCLUDE_hcrypto=
-       LIB_hcrypto=
+if test "$with_openssl" = "yes"; then
+        with_openssl=/usr
+fi
+if test "$with_openssl" != "no"; then
+       INCLUDE_openssl_crypto=
+       LIB_openssl_crypto=
        if test "$with_openssl_include" != ""; then
-               INCLUDE_hcrypto="-I${with_openssl_include}"
+               INCLUDE_openssl_crypto="${with_openssl_include}"
+        else
+                INCLUDE_openssl_crypto="${with_openssl}/include"
        fi
        if test "$with_openssl_lib" != ""; then
-               LIB_hcrypto="-L${with_openssl_lib}"
+               LIB_openssl_crypto="-L${with_openssl_lib}"
        fi
-       CFLAGS="-DHAVE_OPENSSL ${INCLUDE_hcrypto} ${CFLAGS}"
-       saved_LIB_hcrypto="$LIB_hcrypto"
-       for lres in "" "-ldl" "-lnsl -lsocket" "-lnsl -lsocket -ldl"; do
-               LIB_hcrypto="${saved_LIB_hcrypto} -lcrypto $lres"
-               LIB_hcrypto_a="$LIB_hcrypto"
-               LIB_hcrypto_so="$LIB_hcrypto"
-               LIB_hcrypto_appl="$LIB_hcrypto"
-               LIBS="${LIBS} ${LIB_hcrypto}"
-               AC_LINK_IFELSE([AC_LANG_PROGRAM([test_headers],[test_body])], [
-                       crypto_lib=libcrypto openssl=yes
-                       AC_MSG_RESULT([libcrypto])
-                       AC_RUN_IFELSE([AC_LANG_PROGRAM([bn_headers],[bn_body])], [
-                         AC_DEFINE([HAVE_BN_IS_NEGATIVE], 1, [define if OpenSSL provides BN_is_negative])
-                       ])
-               ])
-               if test "$crypto_lib" = libcrypto ; then
-                       break;
-               fi
-       done
-       AC_CHECK_LIB(crypto, OPENSSL_init, [])
-       CFLAGS="$save_CFLAGS"
-       LIBS="$save_LIBS"
+       CFLAGS="-DHAVE_HCRYPTO_W_OPENSSL -I${INCLUDE_openssl_crypto} ${CFLAGS}"
+        # XXX What about rpath?  Yeah...
+        AC_CHECK_LIB([crypto], [OPENSSL_init],
+                     [LIB_openssl_crypto="${LIB_openssl_crypto} -lcrypto"; openssl=yes], [openssl=no], [])
+        # These cases are just for static linking on older OSes,
+        # presumably.
+        if test "$openssl" = "no"; then
+                AC_CHECK_LIB([crypto], [OPENSSL_init],
+                             [LIB_openssl_crypto="${LIB_openssl_crypto} -lcrypto -ldl"; openssl=yes], [openssl=no], [-ldl])
+        fi
+        if test "$openssl" = "no"; then
+                AC_CHECK_LIB([crypto], [OPENSSL_init],
+                             [LIB_openssl_crypto="${LIB_openssl_crypto} -lcrypto -ldl -lnsl"; openssl=yes], [openssl=no], [-ldl -lnsl])
+        fi
+        if test "$openssl" = "no"; then
+                AC_CHECK_LIB([crypto], [OPENSSL_init],
+                             [LIB_openssl_crypto="${LIB_openssl_crypto} -lcrypto -ldl -lnsl -lsocket"; openssl=yes], [openssl=no], [-ldl -lnsl -lsocket])
+        fi
 fi
 
-if test "$crypto_lib" = "unknown"; then
-
-  DIR_hcrypto='hcrypto'
-  LIB_hcrypto='$(top_builddir)/lib/hcrypto/libhcrypto.la'
-  LIB_hcrypto_a='$(top_builddir)/lib/hcrypto/.libs/libhcrypto.a'
-  LIB_hcrypto_so='$(top_builddir)/lib/hcrypto/.libs/libhcrypto.so'
-  LIB_hcrypto_appl="-lhcrypto"
+LIB_hcrypto='$(top_builddir)/lib/hcrypto/libhcrypto.la'
+LIB_hcrypto_a='$(top_builddir)/lib/hcrypto/.libs/libhcrypto.a'
+LIB_hcrypto_so='$(top_builddir)/lib/hcrypto/.libs/libhcrypto.so'
+LIB_hcrypto_appl="-lhcrypto"
 
-  AC_MSG_RESULT([included libhcrypto])
-
-fi
+AC_MSG_RESULT([included libhcrypto])
 
 AC_ARG_WITH(pkcs11-module,
                        AS_HELP_STRING([--with-pkcs11-module=path],
@@ -147,12 +123,12 @@ if test "$pkcs11_module" != ""; then
 fi
 
 if test "$openssl" = "yes"; then
-  AC_DEFINE([HAVE_OPENSSL], 1, [define to use openssl's libcrypto])
+  AC_DEFINE([HAVE_HCRYPTO_W_OPENSSL], 1, [define to use openssl's libcrypto as the default backend for libhcrypto])
 fi
-AM_CONDITIONAL(HAVE_OPENSSL, test "$openssl" = yes)dnl
+AM_CONDITIONAL(HAVE_HCRYPTO_W_OPENSSL, test "$openssl" = yes)dnl
 
-AC_SUBST(DIR_hcrypto)
-AC_SUBST(INCLUDE_hcrypto)
+AC_SUBST(INCLUDE_openssl_crypto)
+AC_SUBST(LIB_openssl_crypto)
 AC_SUBST(LIB_hcrypto)
 AC_SUBST(LIB_hcrypto_a)
 AC_SUBST(LIB_hcrypto_so)
index 3b23b26dced623ed6e4235fde15f86f9f0b9431d..b12dee9593c07c052dea868e2e668b768ef82d62 100644 (file)
@@ -1,5 +1,5 @@
 /***********************************************************************
- * Copyright (c) 2009, Secure Endpoints Inc.
+ * Copyright (c) 2009-2016, Secure Endpoints Inc.
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
@@ -652,8 +652,8 @@ static const char *const rcsid[] = { (const char *)rcsid, "@(#)" msg }
 /* Define to 1 if you have the `openpty' function. */
 /* #define HAVE_OPENPTY 1 */
 
-/* define to use openssl's libcrypto */
-/* #undef HAVE_OPENSSL */
+/* define to 1 to use openssl's libcrypto as a (default) backend for libhcrypto */
+/* #undef HAVE_HCRYPTO_W_OPENSSL */
 
 /* Define to enable basic OSF C2 support. */
 /* #undef HAVE_OSFC2 */
index d695054550707f1eefc193860f15588a1b761563..5c0b242233858a9d6764cb1e834059e626005078 100644 (file)
@@ -5,37 +5,6 @@
 #error "need config.h"
 #endif
 
-#ifdef HAVE_OPENSSL
-
-#define OPENSSL_DES_LIBDES_COMPATIBILITY
-
-#include <openssl/evp.h>
-#include <openssl/des.h>
-#include <openssl/rc4.h>
-#include <openssl/rc2.h>
-#include <openssl/md4.h>
-#include <openssl/md5.h>
-#include <openssl/sha.h>
-#include <openssl/ui.h>
-#include <openssl/rand.h>
-#include <openssl/engine.h>
-#include <openssl/pkcs12.h>
-#include <openssl/pem.h>
-#include <openssl/hmac.h>
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
-#include <openssl/ec.h>
-#include <openssl/ecdsa.h>
-#include <openssl/ecdh.h>
-#include <openssl/dh.h>
-#include <openssl/bn.h>
-#ifndef HAVE_BN_IS_NEGATIVE
-#define BN_set_negative(bn, flag) ((bn)->neg=(flag)?1:0)
-#define BN_is_negative(bn) ((bn)->neg != 0)
-#endif
-
-#else /* !HAVE_OPENSSL */
-
 #ifdef KRB5
 #include <krb5-types.h>
 #endif
 #include <hcrypto/engine.h>
 #include <hcrypto/pkcs12.h>
 #include <hcrypto/hmac.h>
-#include <hcrypto/ec.h>
-#include <hcrypto/ecdsa.h>
-#include <hcrypto/ecdh.h>
-
-#endif /* HAVE_OPENSSL */
 
 #endif /* __crypto_header__ */
index 4b76909d64686c23e308feff2f6d023baf937c0b..f15c779a8948efee3aeca0284f1b25dc55bb11d9 100644 (file)
@@ -25,6 +25,7 @@ CLEANFILES =          \
        rc4.h           \
        rsa.h           \
        sha.h           \
-       ui.h
+       ui.h            \
+       undef.h
 
 EXTRA_DIST = NTMakefile
index 8770e174def3b6618a24b00d98dc625e17b555ba..7ba845af721cae1516addf94761ac407c58cd6a7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 2003-2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
index 085a4dd624343d4a7a487a2a1b44cde17577b977..74a2d54921e38919a404b5c7f11f243da653396f 100644 (file)
@@ -2,7 +2,7 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_libintl) $(INCLUDE_readline) $(INCLUDE_hcrypto) -I$(srcdir)/../lib/krb5 -I$(top_builddir)/include/gssapi
+AM_CPPFLAGS += $(INCLUDE_libintl) $(INCLUDE_readline) -I$(srcdir)/../lib/krb5 -I$(top_builddir)/include/gssapi
 
 bin_PROGRAMS = kadmin
 
index 71f63c4042278812486ed7146fbd939194a53d2f..b9649d387142e85bb9d4c785b285bc9bb70dce39 100644 (file)
@@ -2,7 +2,7 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_libintl) $(INCLUDE_hcrypto) -I$(srcdir)/../lib/krb5
+AM_CPPFLAGS += $(INCLUDE_libintl) -I$(srcdir)/../lib/krb5
 
 libexec_PROGRAMS = kcm
 
index 64bcd20172b72d9ac9b8472c23b2676e1af3b6da..ade443ffb197ec20d992d668d0e7914c55226190 100644 (file)
@@ -2,7 +2,7 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_libintl) $(INCLUDE_hcrypto) -I$(srcdir)/../lib/krb5
+AM_CPPFLAGS += $(INCLUDE_libintl) -I$(srcdir)/../lib/krb5
 
 lib_LTLIBRARIES = libkdc.la
 
@@ -44,6 +44,7 @@ libkdc_la_SOURCES =           \
        kerberos5.c             \
        krb5tgs.c               \
        pkinit.c                \
+       pkinit-ec.c             \
        log.c                   \
        misc.c                  \
        kx509.c                 \
@@ -108,6 +109,7 @@ libkdc_la_LIBADD = \
        $(LIB_kdb)  \
        $(top_builddir)/lib/ntlm/libheimntlm.la \
        $(LIB_hcrypto) \
+       $(LIB_openssl_crypto) \
        $(top_builddir)/lib/asn1/libasn1.la \
        $(LIB_roken) \
        $(DB3LIB) $(DB1LIB) $(LMDBLIB) $(NDBMLIB)
index b0b6584c6a9f3104bb234915f4cf82f9510f92ec..c4bc69ab1cd0adcc48811b4308a4dd3ee3dcbd4b 100644 (file)
@@ -1,6 +1,6 @@
 ########################################################################
 #
-# Copyright (c) 2009, Secure Endpoints Inc.
+# Copyright (c) 2009-2016, Secure Endpoints Inc.
 # All rights reserved.
 # 
 # Redistribution and use in source and binary forms, with or without
@@ -86,7 +86,7 @@ $(BINDIR)\digest-service.exe: $(OBJ)\digest-service.obj $(BIN_LIBS)
 $(LIBEXECDIR)\kdc.exe: \
                $(OBJ)\connect.obj $(OBJ)\config.obj $(OBJ)\announce.obj \
                $(OBJ)\main.obj $(OBJ)\kdc-version.res \
-               $(LIBKDC) $(BIN_LIBS)
+               $(LIBKDC) $(BIN_LIBS) $(LIB_openssl_crypto)
        $(EXECONLINK)
        $(EXEPREP)
 
@@ -98,6 +98,7 @@ LIBKDC_OBJS=\
        $(OBJ)\kerberos5.obj    \
        $(OBJ)\krb5tgs.obj      \
        $(OBJ)\pkinit.obj       \
+       $(OBJ)\pkinit-ec.obj    \
        $(OBJ)\log.obj          \
        $(OBJ)\misc.obj         \
        $(OBJ)\kx509.obj        \
@@ -105,10 +106,11 @@ LIBKDC_OBJS=\
        $(OBJ)\windc.obj
 
 LIBKDC_LIBS=\
-       $(LIBHDB)       \
-       $(LIBHEIMBASE)  \
-       $(LIBHEIMDAL)   \
-       $(LIBHEIMNTLM)  \
+       $(LIBHDB)               \
+       $(LIBHEIMBASE)          \
+       $(LIBHEIMDAL)           \
+       $(LIBHEIMNTLM)          \
+       $(LIB_openssl_crypto)   \
        $(LIBROKEN)
 
 LIBKDCRES=$(OBJ)\libkdc-version.res
@@ -131,6 +133,7 @@ libkdc_la_SOURCES =                 \
        kerberos5.c             \
        krb5tgs.c               \
        pkinit.c                \
+       pkinit-ec.c             \
        log.c                   \
        misc.c                  \
        kx509.c                 \
diff --git a/kdc/pkinit-ec.c b/kdc/pkinit-ec.c
new file mode 100644 (file)
index 0000000..cbc85bd
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2016 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef PKINIT
+
+/*
+ * As with the other *-ec.c files in Heimdal, this is a bit of a hack.
+ *
+ * The idea is to use OpenSSL for EC because hcrypto doesn't have the
+ * required functionality at this time.  To do this we segregate
+ * EC-using code into separate source files and then we arrange for them
+ * to get the OpenSSL headers and not the conflicting hcrypto ones.
+ *
+ * Because of auto-generated *-private.h headers, we end up needing to
+ * make sure various types are defined before we include them, thus the
+ * strange header include order here.
+ */
+
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+#include <openssl/ec.h>
+#include <openssl/ecdh.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#define HEIM_NO_CRYPTO_HDRS
+#endif /* HAVE_HCRYPTO_W_OPENSSL */
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#define NO_HCRYPTO_POLLUTION
+
+#include <hcrypto/des.h>
+
+#include "kdc_locl.h"
+
+#include <heim_asn1.h>
+#include <rfc2459_asn1.h>
+#include <cms_asn1.h>
+#include <pkinit_asn1.h>
+
+#include <hx509.h>
+
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+static void
+free_client_ec_param(krb5_context context,
+                     EC_KEY *ec_key_pk,
+                     EC_KEY *ec_key_key)
+{
+    if (ec_key_pk != NULL)
+        EC_KEY_free(ec_key_pk);
+    if (ec_key_key != NULL)
+        EC_KEY_free(ec_key_key);
+}
+#endif
+
+void
+_kdc_pk_free_client_ec_param(krb5_context context,
+                             void *ec_key_pk,
+                             void *ec_key_key)
+{
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    free_client_ec_param(context, ec_key_pk, ec_key_key);
+#endif
+}
+
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+static krb5_error_code
+generate_ecdh_keyblock(krb5_context context,
+                       EC_KEY *ec_key_pk,    /* the client's public key */
+                       EC_KEY **ec_key_key,  /* the KDC's ephemeral private */
+                       unsigned char **dh_gen_key, /* shared secret */
+                       size_t *dh_gen_keylen)
+{
+    const EC_GROUP *group;
+    EC_KEY *ephemeral;
+    krb5_keyblock key;
+    krb5_error_code ret;
+    unsigned char *p;
+    size_t size;
+    int len;
+
+    *dh_gen_key = NULL;
+    *dh_gen_keylen = 0;
+    *ec_key_key = NULL;
+
+    memset(&key, 0, sizeof(key));
+
+    if (ec_key_pk == NULL) {
+        ret = KRB5KRB_ERR_GENERIC;
+        krb5_set_error_message(context, ret, "public_key");
+        return ret;
+    }
+
+    group = EC_KEY_get0_group(ec_key_pk);
+    if (group == NULL) {
+        ret = KRB5KRB_ERR_GENERIC;
+        krb5_set_error_message(context, ret, "failed to get the group of "
+                               "the client's public key");
+        return ret;
+    }
+
+    ephemeral = EC_KEY_new();
+    if (ephemeral == NULL)
+        return krb5_enomem(context);
+
+    EC_KEY_set_group(ephemeral, group);
+
+    if (EC_KEY_generate_key(ephemeral) != 1) {
+       EC_KEY_free(ephemeral);
+        return krb5_enomem(context);
+    }
+
+    size = (EC_GROUP_get_degree(group) + 7) / 8;
+    p = malloc(size);
+    if (p == NULL) {
+        EC_KEY_free(ephemeral);
+        return krb5_enomem(context);
+    }
+
+    len = ECDH_compute_key(p, size,
+                           EC_KEY_get0_public_key(ec_key_pk),
+                           ephemeral, NULL);
+    if (len <= 0) {
+        free(p);
+        EC_KEY_free(ephemeral);
+        ret = KRB5KRB_ERR_GENERIC;
+        krb5_set_error_message(context, ret, "Failed to compute ECDH "
+                               "public shared secret");
+        return ret;
+    }
+
+    *ec_key_key = ephemeral;
+    *dh_gen_key = p;
+    *dh_gen_keylen = len;
+
+    return 0;
+}
+#endif /* HAVE_HCRYPTO_W_OPENSSL */
+
+krb5_error_code
+_kdc_generate_ecdh_keyblock(krb5_context context,
+                            void *ec_key_pk,    /* the client's public key */
+                            void **ec_key_key,  /* the KDC's ephemeral private */
+                            unsigned char **dh_gen_key, /* shared secret */
+                            size_t *dh_gen_keylen)
+{
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    return generate_ecdh_keyblock(context, ec_key_pk,
+                                  (EC_KEY **)ec_key_key,
+                                  dh_gen_key, dh_gen_keylen);
+#else
+    return ENOTSUP;
+#endif /* HAVE_HCRYPTO_W_OPENSSL */
+}
+
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+static krb5_error_code
+get_ecdh_param(krb5_context context,
+               krb5_kdc_configuration *config,
+               SubjectPublicKeyInfo *dh_key_info,
+               EC_KEY **out)
+{
+    ECParameters ecp;
+    EC_KEY *public = NULL;
+    krb5_error_code ret;
+    const unsigned char *p;
+    size_t len;
+    int nid;
+
+    if (dh_key_info->algorithm.parameters == NULL) {
+       krb5_set_error_message(context, KRB5_BADMSGTYPE,
+                              "PKINIT missing algorithm parameter "
+                              "in clientPublicValue");
+       return KRB5_BADMSGTYPE;
+    }
+
+    memset(&ecp, 0, sizeof(ecp));
+
+    ret = decode_ECParameters(dh_key_info->algorithm.parameters->data,
+                             dh_key_info->algorithm.parameters->length, &ecp, &len);
+    if (ret)
+       goto out;
+
+    if (ecp.element != choice_ECParameters_namedCurve) {
+       ret = KRB5_BADMSGTYPE;
+       goto out;
+    }
+
+    if (der_heim_oid_cmp(&ecp.u.namedCurve, &asn1_oid_id_ec_group_secp256r1) == 0)
+       nid = NID_X9_62_prime256v1;
+    else {
+       ret = KRB5_BADMSGTYPE;
+       goto out;
+    }
+
+    /* XXX verify group is ok */
+
+    public = EC_KEY_new_by_curve_name(nid);
+
+    p = dh_key_info->subjectPublicKey.data;
+    len = dh_key_info->subjectPublicKey.length / 8;
+    if (o2i_ECPublicKey(&public, &p, len) == NULL) {
+       ret = KRB5_BADMSGTYPE;
+       krb5_set_error_message(context, ret,
+                              "PKINIT failed to decode ECDH key");
+       goto out;
+    }
+    *out = public;
+    public = NULL;
+
+ out:
+    if (public)
+       EC_KEY_free(public);
+    free_ECParameters(&ecp);
+    return ret;
+}
+#endif /* HAVE_HCRYPTO_W_OPENSSL */
+
+krb5_error_code
+_kdc_get_ecdh_param(krb5_context context,
+                    krb5_kdc_configuration *config,
+                    SubjectPublicKeyInfo *dh_key_info,
+                    void **out)
+{
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    return get_ecdh_param(context, config, dh_key_info, (EC_KEY **)out);
+#else
+    return ENOTSUP;
+#endif /* HAVE_HCRYPTO_W_OPENSSL */
+}
+
+
+/*
+ *
+ */
+
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+static krb5_error_code
+serialize_ecdh_key(krb5_context context,
+                   EC_KEY *key,
+                   unsigned char **out,
+                   size_t *out_len)
+{
+    krb5_error_code ret = 0;
+    unsigned char *p;
+    int len;
+
+    *out = NULL;
+    *out_len = 0;
+
+    len = i2o_ECPublicKey(key, NULL);
+    if (len <= 0)
+        return EOVERFLOW;
+
+    *out = malloc(len);
+    if (*out == NULL)
+        return krb5_enomem(context);
+
+    p = *out;
+    len = i2o_ECPublicKey(key, &p);
+    if (len <= 0) {
+        free(*out);
+        *out = NULL;
+        ret = EINVAL; /* XXX Better error please */
+       krb5_set_error_message(context, ret,
+                              "PKINIT failed to encode ECDH key");
+        return ret;
+    }
+
+    *out_len = len * 8;
+    return ret;
+}
+#endif
+
+krb5_error_code
+_kdc_serialize_ecdh_key(krb5_context context,
+                        void *key,
+                        unsigned char **out,
+                        size_t *out_len)
+{
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    return serialize_ecdh_key(context, key, out, out_len);
+#else
+    return ENOTSUP;
+#endif
+}
+
+#endif
index 4e35fa681d7666e906c39741c7c8d7bd54980db1..d92304ae98464b8245273ff3ae3636a115eceece 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 - 2008 Kungliga Tekniska Högskolan
+ * Copyright (c) 2003 - 2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -53,12 +53,10 @@ struct pk_client_params {
            BIGNUM *public_key;
            DH *key;
        } dh;
-#ifdef HAVE_OPENSSL
        struct {
-           EC_KEY *public_key;
-           EC_KEY *key;
+           void *public_key;
+           void *key;
        } ecdh;
-#endif
     } u;
     hx509_cert cert;
     unsigned nonce;
@@ -181,14 +179,9 @@ _kdc_pk_free_client_param(krb5_context context, pk_client_params *cp)
        if (cp->u.dh.public_key)
            BN_free(cp->u.dh.public_key);
     }
-#ifdef HAVE_OPENSSL
-    if (cp->keyex == USE_ECDH) {
-       if (cp->u.ecdh.key)
-           EC_KEY_free(cp->u.ecdh.key);
-       if (cp->u.ecdh.public_key)
-           EC_KEY_free(cp->u.ecdh.public_key);
-    }
-#endif
+    if (cp->keyex == USE_ECDH)
+        _kdc_pk_free_client_ec_param(context, cp->u.ecdh.key,
+                                     cp->u.ecdh.public_key);
     krb5_free_keyblock_contents(context, &cp->reply_key);
     if (cp->dh_group_name)
        free(cp->dh_group_name);
@@ -216,7 +209,7 @@ generate_dh_keyblock(krb5_context context,
 
        if (client_params->u.dh.public_key == NULL) {
            ret = KRB5KRB_ERR_GENERIC;
-           krb5_set_error_message(context, ret, "public_key");
+           krb5_set_error_message(context, ret, "missing DH public_key");
            goto out;
        }
 
@@ -250,42 +243,18 @@ generate_dh_keyblock(krb5_context context,
        }
 
        ret = 0;
-#ifdef HAVE_OPENSSL
     } else if (client_params->keyex == USE_ECDH) {
-
        if (client_params->u.ecdh.public_key == NULL) {
            ret = KRB5KRB_ERR_GENERIC;
-           krb5_set_error_message(context, ret, "public_key");
-           goto out;
-       }
-
-       client_params->u.ecdh.key = EC_KEY_new();
-       if (client_params->u.ecdh.key == NULL) {
-           ret = ENOMEM;
+           krb5_set_error_message(context, ret, "missing ECDH public_key");
            goto out;
        }
-       EC_KEY_set_group(client_params->u.ecdh.key,
-                        EC_KEY_get0_group(client_params->u.ecdh.public_key));
-
-       if (EC_KEY_generate_key(client_params->u.ecdh.key) != 1) {
-           ret = ENOMEM;
-           goto out;
-       }
-
-       size = (EC_GROUP_get_degree(EC_KEY_get0_group(client_params->u.ecdh.key)) + 7) / 8;
-       dh_gen_key = malloc(size);
-       if (dh_gen_key == NULL) {
-           ret = ENOMEM;
-           krb5_set_error_message(context, ret,
-                                  N_("malloc: out of memory", ""));
-           goto out;
-       }
-
-       dh_gen_keylen = ECDH_compute_key(dh_gen_key, size,
-                                        EC_KEY_get0_public_key(client_params->u.ecdh.public_key),
-                                        client_params->u.ecdh.key, NULL);
-
-#endif /* HAVE_OPENSSL */
+        ret = _kdc_generate_ecdh_keyblock(context,
+                                          client_params->u.ecdh.public_key,
+                                          &client_params->u.ecdh.key,
+                                          &dh_gen_key, &dh_gen_keylen);
+        if (ret)
+            goto out;
     } else {
        ret = KRB5KRB_ERR_GENERIC;
        krb5_set_error_message(context, ret,
@@ -422,71 +391,6 @@ get_dh_param(krb5_context context,
     return ret;
 }
 
-#ifdef HAVE_OPENSSL
-
-static krb5_error_code
-get_ecdh_param(krb5_context context,
-              krb5_kdc_configuration *config,
-              SubjectPublicKeyInfo *dh_key_info,
-              pk_client_params *client_params)
-{
-    ECParameters ecp;
-    EC_KEY *public = NULL;
-    krb5_error_code ret;
-    const unsigned char *p;
-    size_t len;
-    int nid;
-
-    if (dh_key_info->algorithm.parameters == NULL) {
-       krb5_set_error_message(context, KRB5_BADMSGTYPE,
-                              "PKINIT missing algorithm parameter "
-                              "in clientPublicValue");
-       return KRB5_BADMSGTYPE;
-    }
-
-    memset(&ecp, 0, sizeof(ecp));
-
-    ret = decode_ECParameters(dh_key_info->algorithm.parameters->data,
-                             dh_key_info->algorithm.parameters->length, &ecp, &len);
-    if (ret)
-       goto out;
-
-    if (ecp.element != choice_ECParameters_namedCurve) {
-       ret = KRB5_BADMSGTYPE;
-       goto out;
-    }
-
-    if (der_heim_oid_cmp(&ecp.u.namedCurve, &asn1_oid_id_ec_group_secp256r1) == 0)
-       nid = NID_X9_62_prime256v1;
-    else {
-       ret = KRB5_BADMSGTYPE;
-       goto out;
-    }
-
-    /* XXX verify group is ok */
-
-    public = EC_KEY_new_by_curve_name(nid);
-
-    p = dh_key_info->subjectPublicKey.data;
-    len = dh_key_info->subjectPublicKey.length / 8;
-    if (o2i_ECPublicKey(&public, &p, len) == NULL) {
-       ret = KRB5_BADMSGTYPE;
-       krb5_set_error_message(context, ret,
-                              "PKINIT failed to decode ECDH key");
-       goto out;
-    }
-    client_params->u.ecdh.public_key = public;
-    public = NULL;
-
- out:
-    if (public)
-       EC_KEY_free(public);
-    free_ECParameters(&ecp);
-    return ret;
-}
-
-#endif /* HAVE_OPENSSL */
-
 krb5_error_code
 _kdc_pk_rd_padata(krb5_context context,
                  krb5_kdc_configuration *config,
@@ -829,12 +733,11 @@ _kdc_pk_rd_padata(krb5_context context,
                cp->keyex = USE_DH;
                ret = get_dh_param(context, config,
                                   ap.clientPublicValue, cp);
-#ifdef HAVE_OPENSSL
            } else if (der_heim_oid_cmp(&ap.clientPublicValue->algorithm.algorithm, &asn1_oid_id_ecPublicKey) == 0) {
                cp->keyex = USE_ECDH;
-               ret = get_ecdh_param(context, config,
-                                    ap.clientPublicValue, cp);
-#endif /* HAVE_OPENSSL */
+                ret = _kdc_get_ecdh_param(context, config,
+                                          ap.clientPublicValue,
+                                          &cp->u.ecdh.public_key);
            } else {
                ret = KRB5_BADMSGTYPE;
                krb5_set_error_message(context, ret, "PKINIT unknown DH mechanism");
@@ -1134,26 +1037,13 @@ pk_mk_pa_reply_dh(krb5_context context,
        dh_info.subjectPublicKey.length = buf.length * 8;
        dh_info.subjectPublicKey.data = buf.data;
        krb5_data_zero(&buf);
-#ifdef HAVE_OPENSSL
     } else if (cp->keyex == USE_ECDH) {
-       unsigned char *p;
-       int len;
-
-       len = i2o_ECPublicKey(cp->u.ecdh.key, NULL);
-       if (len <= 0)
-           abort();
-
-       p = malloc(len);
-       if (p == NULL)
-           abort();
-
-       dh_info.subjectPublicKey.length = len * 8;
-       dh_info.subjectPublicKey.data = p;
-
-       len = i2o_ECPublicKey(cp->u.ecdh.key, &p);
-       if (len <= 0)
-           abort();
-#endif
+        unsigned char *p;
+        ret = _kdc_serialize_ecdh_key(context, cp->u.ecdh.key, &p,
+                                      &dh_info.subjectPublicKey.length);
+        dh_info.subjectPublicKey.data = p;
+        if (ret)
+            goto out;
     } else
        krb5_abortx(context, "no keyex selected ?");
 
@@ -1329,9 +1219,7 @@ _kdc_pk_mk_pa_reply(krb5_context context,
 
            switch (cp->keyex) {
            case USE_DH: type = "dh"; break;
-#ifdef HAVE_OPENSSL
            case USE_ECDH: type = "ecdh"; break;
-#endif
            default: krb5_abortx(context, "unknown keyex"); break;
            }
 
index c2bfb6588ada66cd6c37d7e21b90ecf25f3ad0ec..88132df6a7e9c2fb023911ead288a901e1184399 100644 (file)
@@ -2,8 +2,6 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_hcrypto)
-
 man_MANS = kpasswd.1 kpasswdd.8
 
 bin_PROGRAMS = kpasswd
index 64b23be5338bd156dd6c22d0b4df81515869ac18..c62b203fce624e712d902a74c7b1ab2d30901092 100644 (file)
@@ -2,7 +2,7 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_hcrypto) -I$(srcdir)/../lib/krb5 \
+AM_CPPFLAGS += -I$(srcdir)/../lib/krb5 \
        $(INCLUDE_libintl) \
        -DHEIMDAL_LOCALEDIR='"$(localedir)"'
 
index f97c4c0d770f72a0b98b55c92f6b6b74bda29d81..4a6d2543d6501513cbe6e036582fd0112c2a885a 100644 (file)
@@ -1,6 +1,6 @@
 ########################################################################
 #
-# Copyright (c) 2009,2011, Secure Endpoints Inc.
+# Copyright (c) 2009-2016, Secure Endpoints Inc.
 # All rights reserved.
 # 
 # Redistribution and use in source and binary forms, with or without
index b12e778a0ce6e9ece3f1eb755ca0079b44d2873d..250708df2ef4bc2b6133187cc0a0f0a156fafae2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Kungliga Tekniska Högskolan
+ * Copyright (c) 2010-2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
index 3158bb022b0a58023deafba9db7df07187be7ab9..c2be0b3dc6c859c63ce77c7c3494dbbbb72801eb 100644 (file)
@@ -12,8 +12,7 @@ AM_CPPFLAGS += \
        -I$(srcdir)/ntlm \
        -I$(srcdir)/krb5 \
        -I$(srcdir)/spnego \
-       $(INCLUDE_libintl) \
-       $(INCLUDE_hcrypto)
+       $(INCLUDE_libintl)
 
 lib_LTLIBRARIES = libgssapi.la
 
index 80373a007eef90abe740405c22648ba6045c8957..40469a7a7bdadb861c7e5eef10ada04a6d4e52dd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006-2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
index c24f72bfa36efde1b356cdc5cdaf49feae4cbb7c..d2bb42494e099dec82a60b449d3ae57b3bde9293 100644 (file)
@@ -2,8 +2,12 @@
 
 include $(top_srcdir)/Makefile.am.common
 
+if HAVE_HCRYPTO_W_OPENSSL
+AM_CPPFLAGS += -I$(INCLUDE_openssl_crypto)
+endif
+
 AM_CPPFLAGS += -I$(top_srcdir)/lib/hx509 \
-        -I$(srcdir)/libtommath -DUSE_HCRYPTO_LTM=1
+              -I$(srcdir)/libtommath -DUSE_HCRYPTO_LTM=1
 
 lib_LTLIBRARIES = libhcrypto.la
 check_LTLIBRARIES = libhctest.la
@@ -15,6 +19,10 @@ libhcrypto_la_LIBADD = \
        $(LIB_heimbase) \
        $(LIBADD_roken)
 
+if HAVE_HCRYPTO_W_OPENSSL
+libhcrypto_la_LIBADD += $(LIB_openssl_crypto)
+endif
+
 hcryptoincludedir = $(includedir)/hcrypto
 buildhcryptoinclude = $(buildinclude)/hcrypto
 
@@ -31,6 +39,7 @@ hcryptoinclude_HEADERS =      \
        evp.h                   \
        evp-hcrypto.h           \
        evp-cc.h                \
+       evp-openssl.h           \
        evp-pkcs11.h            \
        hmac.h                  \
        md2.h                   \
@@ -42,7 +51,8 @@ hcryptoinclude_HEADERS =      \
        rc4.h                   \
        rsa.h                   \
        sha.h                   \
-       ui.h
+       ui.h                    \
+       undef.h
 
 install-build-headers:: $(hcryptoinclude_HEADERS)
        @foo='$(hcryptoinclude_HEADERS)'; \
@@ -117,6 +127,7 @@ libhcrypto_la_SOURCES =     \
        evp.h           \
        evp-hcrypto.c   \
        evp-cc.c        \
+       evp-openssl.c   \
        evp-pkcs11.c    \
        engine.c        \
        engine.h        \
@@ -154,7 +165,8 @@ libhcrypto_la_SOURCES =     \
        sha512.c        \
        validate.c      \
        ui.c            \
-       ui.h
+       ui.h            \
+       undef.h
 
 ltmsources = \
        libtommath/tommath.h \
index 9d0fe74b1cf5decafcfe263c42bf4a54b71e7566..c35059517c812707b4e023303ad9bf83a814b77f 100644 (file)
@@ -1,6 +1,6 @@
 ########################################################################
 #
-# Copyright (c) 2009, Secure Endpoints Inc.
+# Copyright (c) 2009-2016, Secure Endpoints Inc.
 # All rights reserved.
 # 
 # Redistribution and use in source and binary forms, with or without
@@ -41,8 +41,12 @@ HEIMBASEDIR = $(SRC)\lib\base
 
 HX509DIR = $(SRC)\lib\hx509
 
+!if INCLUDE_openssl_crypto
+openssl_inc=-I$(INCLUDE_openssl_crypto)
+!endif
+
 intcflags=-DKRB5 -DASN1_LIB -I$(HCRYPTOINCLUDEDIR) -DUSE_HCRYPTO_LTM=1 \
-       -I$(HX509DIR)
+       -I$(HX509DIR) $(openssl_inc)
 
 # Do dependencies first
 
@@ -67,6 +71,7 @@ INCFILES=     \
        $(HCRYPTOINCLUDEDIR)\evp.h      \
        $(HCRYPTOINCLUDEDIR)\evp-hcrypto.h      \
        $(HCRYPTOINCLUDEDIR)\evp-cc.h   \
+       $(HCRYPTOINCLUDEDIR)\evp-openssl.h      \
        $(HCRYPTOINCLUDEDIR)\evp-pkcs11.h       \
        $(HCRYPTOINCLUDEDIR)\evp-wincng.h       \
        $(HCRYPTOINCLUDEDIR)\evp-w32.h  \
@@ -81,7 +86,8 @@ INCFILES=     \
        $(HCRYPTOINCLUDEDIR)\rc4.h      \
        $(HCRYPTOINCLUDEDIR)\rsa.h      \
        $(HCRYPTOINCLUDEDIR)\sha.h      \
-       $(HCRYPTOINCLUDEDIR)\ui.h
+       $(HCRYPTOINCLUDEDIR)\ui.h       \
+       $(HCRYPTOINCLUDEDIR)\undef.h
 
 mkincdir:
 !if !exist($(HCRYPTOINCLUDEDIR))
@@ -111,6 +117,7 @@ libhcrypto_OBJs =                   \
        $(OBJ)\evp.obj                  \
        $(OBJ)\evp-hcrypto.obj          \
        $(OBJ)\evp-cc.obj               \
+       $(OBJ)\evp-openssl.obj          \
        $(OBJ)\evp-pkcs11.obj           \
        $(OBJ)\evp-wincng.obj           \
        $(OBJ)\evp-w32.obj              \
index 3b78c220dec620f8528305aabc59ae31ec46793e..727b919a3e65412324536bb843585a42991b643c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006-2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -72,6 +72,8 @@
 #define BN_GENCB hc_BN_GENCB
 #define BN_CTX hc_BN_CTX
 #define BN_BLINDING hc_BN_BLINDING
+#define BN_MONT_CTX hc_BN_MONT_CTX
+
 
 /*
  *
index 637f218bcf8222cae503a97d16398d9d2c94b02e..61868054b65bd0d8b4d89ae9461df8131aaf1bec 100644 (file)
@@ -39,6 +39,8 @@
 #define _HEIM_DH_H 1
 
 /* symbol renaming */
+#define DH hc_DH
+#define DH_METHOD hc_DH_METHOD
 #define DH_null_method hc_DH_null_method
 #define DH_tfm_method hc_DH_tfm_method
 #define DH_ltm_method hc_DH_ltm_method
index 686d05087448b0c038193c5f71cab362b05c41b9..a8f087f79af018b4f3b39054971847f93744bdd4 100644 (file)
@@ -41,6 +41,8 @@
 #include <hcrypto/bn.h>
 
 /* symbol renaming */
+#define DSA hc_DSA
+#define DSA_METHOD hc_DSA_METHOD
 #define DSA_null_method hc_DSA_null_method
 #define DSA_new hc_DSA_new
 #define DSA_free hc_DSA_free
index ac6e8778834345ab9abc1402620bbce93f83724d..726deec6169f0aacc4048543807d485eeb4e43d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Kungliga Tekniska Högskolan
+ * Copyright (c) 2009-2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
index 2ee745e4e8b89c4b9107c7763a18ff4eb3b444e9..e6fc5b92e4155b4e8bc9de7f9c704b203e52347f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006-2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
diff --git a/lib/hcrypto/evp-openssl.c b/lib/hcrypto/evp-openssl.c
new file mode 100644 (file)
index 0000000..188c097
--- /dev/null
@@ -0,0 +1,627 @@
+/*
+ * Copyright (c) 2016, 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:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* OpenSSL provider */
+
+#include "config.h"
+#include <roken.h>
+#include <heimbase.h>
+
+#include <assert.h>
+
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+
+/*
+ * This is the OpenSSL 1.x backend for hcrypto.  It has been tested with
+ * OpenSSL 1.0.1f and OpenSSL 1.1.0-pre3-dev.
+ *
+ * NOTE: In order for this to work with OpenSSL 1.1.x and up, it is
+ *       critical to use opaque OpenSSL type accessors everywhere /
+ *       never use knowledge of opaque OpenSSL type internals.
+ */
+
+#include <evp.h>
+#include <evp-openssl.h>
+
+/*
+ * This being an OpenSSL backend for hcrypto... we need to be able to
+ * refer to types and objects (functions) from both, OpenSSL and
+ * hcrypto.
+ *
+ * The hcrypto API is *very* similar to the OpenSSL 1.0.x API, with the
+ * same type and symbol names in many cases, except that the hcrypto
+ * names are prefixed with hc_*.  hcrypto has convenience macros that
+ * provide OpenSSL aliases for the hcrypto interfaces, and hcrypto
+ * applications are expected to use the OpenSSL names.
+ *
+ * Since here we must be able to refer to types and objects from both
+ * OpenSSL and from hcrypto, we disable the hcrypto renaming for the
+ * rest of this file.  These #undefs could be collected into an
+ * <hcrypto/undef.h> for the purpose of permitting other applications to
+ * use both, hcrypto and OpenSSL in the same source files (provided that
+ * such applications refer to hcrypto types and objects by their proper
+ * hc_-prefixed names).
+ */
+#include <undef.h>
+
+/* Now it's safe to include OpenSSL headers */
+#include <openssl/evp.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define EVP_MD_CTX_new EVP_MD_CTX_create
+#define EVP_MD_CTX_free EVP_MD_CTX_destroy
+#endif
+
+/* A HEIM_BASE_ONCE argument struct for per-EVP one-time initialization */
+struct once_init_cipher_ctx {
+    hc_EVP_CIPHER **hc_memoizep;    /* ptr to static ptr to hc_EVP_CIPHER */
+    hc_EVP_CIPHER *hc_memoize;      /* ptr to static hc_EVP_CIPHER */
+    unsigned long flags;
+    unsigned char *initialized;
+    int nid;
+};
+
+/* Our wrapper for OpenSSL EVP_CIPHER_CTXs */
+struct ossl_cipher_ctx {
+    EVP_CIPHER_CTX      *ossl_cipher_ctx;   /* OpenSSL cipher ctx */
+    const EVP_CIPHER    *ossl_cipher;       /* OpenSSL cipher */
+    int                 initialized;
+};
+
+/*
+ * Our hc_EVP_CIPHER init() method; wraps around OpenSSL
+ * EVP_CipherInit_ex().
+ *
+ * This is very similar to the init() function pointer in an OpenSSL
+ * EVP_CIPHER, but a) we can't access them in 1.1, and b) the method
+ * invocation protocols in hcrypto and OpenSSL are similar but not the
+ * same, thus we must have this wrapper.
+ */
+static int
+cipher_ctx_init(hc_EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                const unsigned char *iv, int enc)
+{
+    struct ossl_cipher_ctx *ossl_ctx = ctx->cipher_data; /* EVP_CIPHER_CTX wrapper */
+    const EVP_CIPHER *c;
+
+    assert(ossl_ctx != NULL);
+    assert(ctx->cipher != NULL);
+    assert(ctx->cipher->app_data != NULL);
+
+    /*
+     * Here be dragons.
+     *
+     * We need to make sure that the OpenSSL EVP_CipherInit_ex() is
+     * called with cipher!=NULL just once per EVP_CIPHER_CTX, otherwise
+     * state in the OpenSSL EVP_CIPHER_CTX will get cleaned up and then
+     * we'll segfault.
+     *
+     * hcrypto applications can re-initialize an (hc_)EVP_CIPHER_CTX as
+     * usual by calling (hc)EVP_CipherInit_ex() with a non-NULL cipher
+     * argument, and that will cause cipher_cleanup() (below) to be
+     * called.
+     */
+    c = ossl_ctx->ossl_cipher = ctx->cipher->app_data; /* OpenSSL's EVP_CIPHER * */
+    if (!ossl_ctx->initialized) {
+        ossl_ctx->ossl_cipher_ctx = EVP_CIPHER_CTX_new();
+        if (ossl_ctx->ossl_cipher_ctx == NULL)
+            return 0;
+        /*
+         * So we always call EVP_CipherInit_ex() with c!=NULL, but other
+         * things NULL...
+         */
+        if (!EVP_CipherInit_ex(ossl_ctx->ossl_cipher_ctx, c, NULL, NULL, NULL, enc))
+            return 0;
+        ossl_ctx->initialized = 1;
+    }
+
+    /* ...and from here on always call EVP_CipherInit_ex() with c=NULL */
+    if ((ctx->cipher->flags & hc_EVP_CIPH_VARIABLE_LENGTH) &&
+        ctx->key_len > 0)
+        EVP_CIPHER_CTX_set_key_length(ossl_ctx->ossl_cipher_ctx, ctx->key_len);
+
+    return EVP_CipherInit_ex(ossl_ctx->ossl_cipher_ctx, NULL, NULL, key, iv, enc);
+}
+
+static int
+cipher_do_cipher(hc_EVP_CIPHER_CTX *ctx, unsigned char *out,
+                 const unsigned char *in, unsigned int len)
+{
+    struct ossl_cipher_ctx *ossl_ctx = ctx->cipher_data;
+
+    assert(ossl_ctx != NULL);
+    return EVP_Cipher(ossl_ctx->ossl_cipher_ctx, out, in, len);
+}
+
+static int
+cipher_cleanup(hc_EVP_CIPHER_CTX *ctx)
+{
+    struct ossl_cipher_ctx *ossl_ctx = ctx->cipher_data;
+
+    if (ossl_ctx == NULL || !ossl_ctx->initialized)
+        return 1;
+
+    if (ossl_ctx->ossl_cipher_ctx != NULL)
+        EVP_CIPHER_CTX_free(ossl_ctx->ossl_cipher_ctx);
+
+    ossl_ctx->ossl_cipher_ctx = NULL;
+    ossl_ctx->ossl_cipher = NULL;
+    ossl_ctx->initialized = 0;
+    return 1;
+}
+
+static int
+cipher_ctrl(hc_EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+    struct ossl_cipher_ctx *ossl_ctx = ctx->cipher_data;
+
+    assert(ossl_ctx != NULL);
+    return EVP_CIPHER_CTX_ctrl(ossl_ctx->ossl_cipher_ctx, type, arg, ptr);
+}
+
+
+static void
+get_EVP_CIPHER_once_cb(void *d)
+{
+    struct once_init_cipher_ctx *arg = d;
+    const EVP_CIPHER *ossl_evp;
+    hc_EVP_CIPHER *hc_evp;
+
+    hc_evp = arg->hc_memoize;
+
+    /*
+     * We lookup EVP_CIPHER *s by NID so that we don't fail to find a
+     * symbol such as EVP_aes...() when libcrypto changes after build
+     * time (e.g., updates, LD_LIBRARY_PATH/LD_PRELOAD).
+     */
+    ossl_evp = EVP_get_cipherbynid(arg->nid);
+    if (ossl_evp == NULL) {
+        (void) memset(hc_evp, 0, sizeof(*hc_evp));
+        *arg->hc_memoizep = NULL;
+        *arg->initialized = 1;
+        return;
+    }
+
+    /* Build the hc_EVP_CIPHER */
+    hc_evp->nid = EVP_CIPHER_nid(ossl_evp); /* We would an hcrypto NIDs if we had them */
+    hc_evp->block_size = EVP_CIPHER_block_size(ossl_evp);
+    hc_evp->key_len = EVP_CIPHER_key_length(ossl_evp);
+    hc_evp->iv_len = EVP_CIPHER_iv_length(ossl_evp);
+
+    /*
+     * We force hc_EVP_CipherInit_ex to always call our init() function,
+     * otherwise we don't get a chance to call EVP_CipherInit_ex()
+     * correctly.
+     */
+    hc_evp->flags = hc_EVP_CIPH_ALWAYS_CALL_INIT | arg->flags;
+
+    /* Our cipher context */
+    hc_evp->ctx_size = sizeof(struct ossl_cipher_ctx);
+
+    /* Our wrappers */
+    hc_evp->init = cipher_ctx_init;
+    hc_evp->do_cipher = cipher_do_cipher;
+    hc_evp->cleanup = cipher_cleanup;
+    hc_evp->set_asn1_parameters = NULL;
+    hc_evp->get_asn1_parameters = NULL;
+    hc_evp->ctrl = cipher_ctrl;
+
+    /* Our link to the OpenSSL EVP_CIPHER */
+    hc_evp->app_data = (void *)ossl_evp;
+
+    /* Finally, set the static hc_EVP_CIPHER * to the one we just built */
+    *arg->hc_memoizep = hc_evp;
+    *arg->initialized = 1;
+}
+
+static hc_EVP_CIPHER *
+get_EVP_CIPHER(heim_base_once_t *once, hc_EVP_CIPHER *hc_memoize,
+               hc_EVP_CIPHER **hc_memoizep, unsigned long flags,
+               unsigned char *initialized, int nid)
+{
+    struct once_init_cipher_ctx arg;
+
+    arg.flags = flags;
+    arg.hc_memoizep = hc_memoizep;
+    arg.hc_memoize = hc_memoize;
+    arg.initialized = initialized;
+    arg.nid = nid;
+    heim_base_once_f(once, &arg, get_EVP_CIPHER_once_cb);
+    return *hc_memoizep; /* May be NULL */
+}
+
+#define OSSL_CIPHER_ALGORITHM(name, flags)                              \
+    const hc_EVP_CIPHER *hc_EVP_ossl_##name(void)                       \
+    {                                                                   \
+        static hc_EVP_CIPHER ossl_##name##_st;                          \
+        static hc_EVP_CIPHER *ossl_##name;                              \
+        static heim_base_once_t once = HEIM_BASE_ONCE_INIT;             \
+        static unsigned char initialized;                               \
+        if (initialized)                                                \
+            return ossl_##name;                                         \
+        return get_EVP_CIPHER(&once, &ossl_##name##_st, &ossl_##name,   \
+                              flags, &initialized, NID_##name);         \
+    }
+
+/* As above, but for EVP_MDs */
+
+struct ossl_md_ctx {
+    EVP_MD_CTX          *ossl_md_ctx;       /* OpenSSL md ctx */
+    const EVP_MD        *ossl_md;           /* OpenSSL md */
+    int                 initialized;
+};
+
+static int
+ossl_md_init(struct ossl_md_ctx *ctx, const EVP_MD *md)
+{
+    if (ctx->initialized)
+        EVP_MD_CTX_free(ctx->ossl_md_ctx);
+    ctx->initialized = 0;
+
+    ctx->ossl_md = md;
+    ctx->ossl_md_ctx = EVP_MD_CTX_new();
+    if (!EVP_DigestInit(ctx->ossl_md_ctx, md)) {
+        EVP_MD_CTX_free(ctx->ossl_md_ctx);
+        ctx->ossl_md_ctx = NULL;
+        ctx->ossl_md = NULL;
+        return 0;
+    }
+    ctx->initialized = 1;
+    return 1;
+}
+
+static int
+ossl_md_update(hc_EVP_MD_CTX *d, const void *data, size_t count)
+{
+    struct ossl_md_ctx *ctx = (void *)d;
+
+    return EVP_DigestUpdate(ctx->ossl_md_ctx, data, count);
+}
+
+static int
+ossl_md_final(void *md_data, hc_EVP_MD_CTX *d)
+{
+    struct ossl_md_ctx *ctx = (void *)d;
+
+    return EVP_DigestFinal(ctx->ossl_md_ctx, md_data, NULL);
+}
+
+static int
+ossl_md_cleanup(hc_EVP_MD_CTX *d)
+{
+    struct ossl_md_ctx *ctx = (void *)d;
+
+    if (!ctx->initialized)
+        return 1;
+    EVP_MD_CTX_free(ctx->ossl_md_ctx);
+    ctx->ossl_md = NULL;
+    ctx->initialized = 0;
+
+    return 1;
+}
+
+struct once_init_md_ctx {
+    const EVP_MD **ossl_memoizep;
+    hc_EVP_MD **hc_memoizep;
+    hc_EVP_MD *hc_memoize;
+    hc_evp_md_init md_init;
+    int nid;
+    unsigned char *initialized;
+};
+
+static void
+get_EVP_MD_once_cb(void *d)
+{
+    struct once_init_md_ctx *arg = d;
+    const EVP_MD *ossl_evp;
+    hc_EVP_MD *hc_evp;
+
+    hc_evp = arg->hc_memoize;
+    *arg->ossl_memoizep = ossl_evp = EVP_get_digestbynid(arg->nid);
+
+    if (ossl_evp == NULL) {
+        (void) memset(hc_evp, 0, sizeof(*hc_evp));
+        *arg->hc_memoizep = NULL;
+        *arg->initialized = 1;
+        return;
+    }
+
+    /* Build the hc_EVP_MD */
+    hc_evp->ctx_size = sizeof(struct ossl_md_ctx);
+    hc_evp->init = arg->md_init;
+    hc_evp->update = ossl_md_update;
+    hc_evp->final = ossl_md_final;
+    hc_evp->cleanup = ossl_md_cleanup;
+
+    *arg->hc_memoizep = hc_evp;
+    *arg->initialized = 1;
+}
+
+static hc_EVP_MD *
+get_EVP_MD(heim_base_once_t *once, hc_EVP_MD *hc_memoize,
+           hc_EVP_MD **hc_memoizep, const EVP_MD **ossl_memoizep,
+           hc_evp_md_init md_init, unsigned char *initialized, int nid)
+{
+    struct once_init_md_ctx ctx;
+
+    ctx.ossl_memoizep = ossl_memoizep;
+    ctx.hc_memoizep = hc_memoizep;
+    ctx.hc_memoize = hc_memoize;
+    ctx.md_init = md_init;
+    ctx.initialized = initialized;
+    ctx.nid = nid;
+    heim_base_once_f(once, &ctx, get_EVP_MD_once_cb);
+    return *hc_memoizep; /* May be NULL */
+}
+
+#define OSSL_MD_ALGORITHM(name)                                         \
+    static const EVP_MD *ossl_EVP_##name;                               \
+    static hc_EVP_MD *ossl_##name;                                      \
+    static int ossl_init_##name(hc_EVP_MD_CTX *d)                       \
+    {                                                                   \
+        return ossl_md_init((void *)d, ossl_EVP_##name);                \
+    }                                                                   \
+    const hc_EVP_MD *hc_EVP_ossl_##name(void)                           \
+    {                                                                   \
+        static hc_EVP_MD ossl_##name##_st;                              \
+        static heim_base_once_t once = HEIM_BASE_ONCE_INIT;             \
+        static unsigned char initialized;                               \
+        if (initialized)                                                \
+            return ossl_##name;                                         \
+        return get_EVP_MD(&once, &ossl_##name##_st, &ossl_##name,       \
+                          &ossl_EVP_##name, ossl_init_##name,           \
+                          &initialized, NID_##name);                    \
+    }
+
+/**
+ * The triple DES cipher type (OpenSSL provider)
+ *
+ * @return the DES-EDE3-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(des_ede3_cbc, hc_EVP_CIPH_CBC_MODE)
+
+/**
+ * The DES cipher type (OpenSSL provider)
+ *
+ * @return the DES-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(des_cbc, hc_EVP_CIPH_CBC_MODE)
+
+/**
+ * The AES-128 cipher type (OpenSSL provider)
+ *
+ * @return the AES-128-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(aes_128_cbc, hc_EVP_CIPH_CBC_MODE)
+
+/**
+ * The AES-192 cipher type (OpenSSL provider)
+ *
+ * @return the AES-192-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(aes_192_cbc, hc_EVP_CIPH_CBC_MODE)
+
+/**
+ * The AES-256 cipher type (OpenSSL provider)
+ *
+ * @return the AES-256-CBC EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(aes_256_cbc, hc_EVP_CIPH_CBC_MODE)
+
+/**
+ * The AES-128 CFB8 cipher type (OpenSSL provider)
+ *
+ * @return the AES-128-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(aes_128_cfb8, hc_EVP_CIPH_CFB8_MODE)
+
+/**
+ * The AES-192 CFB8 cipher type (OpenSSL provider)
+ *
+ * @return the AES-192-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(aes_192_cfb8, hc_EVP_CIPH_CFB8_MODE)
+
+/**
+ * The AES-256 CFB8 cipher type (OpenSSL provider)
+ *
+ * @return the AES-256-CFB8 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(aes_256_cfb8, hc_EVP_CIPH_CFB8_MODE)
+
+/*
+ * RC2 is only needed for tests of PKCS#12 support, which currently uses
+ * the RC2 PBE.  So no RC2 -> tests fail.
+ */
+
+/**
+ * The RC2 cipher type - OpenSSL
+ *
+ * @return the RC2 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(rc2_cbc,
+                      hc_EVP_CIPH_CBC_MODE |
+                      hc_EVP_CIPH_VARIABLE_LENGTH)
+
+/**
+ * The RC2-40 cipher type - OpenSSL
+ *
+ * @return the RC2-40 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(rc2_40_cbc,
+                      hc_EVP_CIPH_CBC_MODE)
+
+/**
+ * The RC2-64 cipher type - OpenSSL
+ *
+ * @return the RC2-64 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(rc2_64_cbc,
+                      hc_EVP_CIPH_CBC_MODE |
+                      hc_EVP_CIPH_VARIABLE_LENGTH)
+
+/**
+ * The Camellia-128 cipher type - OpenSSL
+ *
+ * @return the Camellia-128 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(camellia_128_cbc, hc_EVP_CIPH_CBC_MODE)
+
+/**
+ * The Camellia-198 cipher type - OpenSSL
+ *
+ * @return the Camellia-198 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(camellia_192_cbc, hc_EVP_CIPH_CBC_MODE)
+
+/**
+ * The Camellia-256 cipher type - OpenSSL
+ *
+ * @return the Camellia-256 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(camellia_256_cbc, hc_EVP_CIPH_CBC_MODE)
+
+/**
+ * The RC4 cipher type (OpenSSL provider)
+ *
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(rc4,
+                      hc_EVP_CIPH_STREAM_CIPHER |
+                      hc_EVP_CIPH_VARIABLE_LENGTH)
+
+/**
+ * The RC4-40 cipher type (OpenSSL provider)
+ *
+ * @return the RC4 EVP_CIPHER pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_CIPHER_ALGORITHM(rc4_40,
+                      hc_EVP_CIPH_STREAM_CIPHER |
+                      hc_EVP_CIPH_VARIABLE_LENGTH)
+
+/**
+ * The MD2 hash algorithm (OpenSSL provider)
+ *
+ * @return the MD2 EVP_MD pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_MD_ALGORITHM(md2)
+
+/**
+ * The MD4 hash algorithm (OpenSSL provider)
+ *
+ * @return the MD4 EVP_MD pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_MD_ALGORITHM(md4)
+
+/**
+ * The MD5 hash algorithm (OpenSSL provider)
+ *
+ * @return the MD5 EVP_MD pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_MD_ALGORITHM(md5)
+
+/**
+ * The SHA-1 hash algorithm (OpenSSL provider)
+ *
+ * @return the SHA-1 EVP_MD pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_MD_ALGORITHM(sha1)
+
+/**
+ * The SHA-256 hash algorithm (OpenSSL provider)
+ *
+ * @return the SHA-256 EVP_MD pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_MD_ALGORITHM(sha256)
+
+/**
+ * The SHA-384 hash algorithm (OpenSSL provider)
+ *
+ * @return the SHA-384 EVP_MD pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_MD_ALGORITHM(sha384)
+
+/**
+ * The SHA-512 hash algorithm (OpenSSL provider)
+ *
+ * @return the SHA-512 EVP_MD pointer.
+ *
+ * @ingroup hcrypto_evp
+ */
+OSSL_MD_ALGORITHM(sha512)
+
+#else /* HAVE_HCRYPTO_W_OPENSSL */
+static char dummy;
+#endif /* HAVE_HCRYPTO_W_OPENSSL */
diff --git a/lib/hcrypto/evp-openssl.h b/lib/hcrypto/evp-openssl.h
new file mode 100644 (file)
index 0000000..225ff45
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2009-2016 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#ifndef HEIM_EVP_OSSL_H
+#define HEIM_EVP_OSSL_H 1
+
+/* symbol renaming */
+#define EVP_ossl_md2 hc_EVP_ossl_md2
+#define EVP_ossl_md4 hc_EVP_ossl_md4
+#define EVP_ossl_md5 hc_EVP_ossl_md5
+#define EVP_ossl_sha1 hc_EVP_ossl_sha1
+#define EVP_ossl_sha256 hc_EVP_ossl_sha256
+#define EVP_ossl_sha384 hc_EVP_ossl_sha384
+#define EVP_ossl_sha512 hc_EVP_ossl_sha512
+#define EVP_ossl_des_cbc hc_EVP_ossl_des_cbc
+#define EVP_ossl_des_ede3_cbc hc_EVP_ossl_des_ede3_cbc
+#define EVP_ossl_aes_128_cbc hc_EVP_ossl_aes_128_cbc
+#define EVP_ossl_aes_192_cbc hc_EVP_ossl_aes_192_cbc
+#define EVP_ossl_aes_256_cbc hc_EVP_ossl_aes_256_cbc
+#define EVP_ossl_aes_128_cfb8 hc_EVP_ossl_aes_128_cfb8
+#define EVP_ossl_aes_192_cfb8 hc_EVP_ossl_aes_192_cfb8
+#define EVP_ossl_aes_256_cfb8 hc_EVP_ossl_aes_256_cfb8
+#define EVP_ossl_rc4 hc_EVP_ossl_rc4
+#define EVP_ossl_rc4_40 hc_EVP_ossl_rc4_40
+#define EVP_ossl_rc2_40_cbc hc_EVP_ossl_rc2_40_cbc
+#define EVP_ossl_rc2_64_cbc hc_EVP_ossl_rc2_64_cbc
+#define EVP_ossl_rc2_cbc hc_EVP_ossl_rc2_cbc
+#define EVP_ossl_camellia_128_cbc hc_EVP_ossl_camellia_128_cbc
+#define EVP_ossl_camellia_192_cbc hc_EVP_ossl_camellia_192_cbc
+#define EVP_ossl_camellia_256_cbc hc_EVP_ossl_camellia_256_cbc
+
+/*
+ *
+ */
+
+HC_CPP_BEGIN
+
+const hc_EVP_MD * hc_EVP_ossl_md2(void);
+const hc_EVP_MD * hc_EVP_ossl_md4(void);
+const hc_EVP_MD * hc_EVP_ossl_md5(void);
+const hc_EVP_MD * hc_EVP_ossl_sha1(void);
+const hc_EVP_MD * hc_EVP_ossl_sha256(void);
+const hc_EVP_MD * hc_EVP_ossl_sha384(void);
+const hc_EVP_MD * hc_EVP_ossl_sha512(void);
+
+const hc_EVP_CIPHER * hc_EVP_ossl_rc2_cbc(void);
+const hc_EVP_CIPHER * hc_EVP_ossl_rc2_40_cbc(void);
+const hc_EVP_CIPHER * hc_EVP_ossl_rc2_64_cbc(void);
+
+const hc_EVP_CIPHER * hc_EVP_ossl_rc4(void);
+const hc_EVP_CIPHER * hc_EVP_ossl_rc4_40(void);
+
+const hc_EVP_CIPHER * hc_EVP_ossl_des_cbc(void);
+const hc_EVP_CIPHER * hc_EVP_ossl_des_ede3_cbc(void);
+
+const hc_EVP_CIPHER * hc_EVP_ossl_aes_128_cbc(void);
+const hc_EVP_CIPHER * hc_EVP_ossl_aes_192_cbc(void);
+const hc_EVP_CIPHER * hc_EVP_ossl_aes_256_cbc(void);
+
+const hc_EVP_CIPHER * hc_EVP_ossl_aes_128_cfb8(void);
+const hc_EVP_CIPHER * hc_EVP_ossl_aes_192_cfb8(void);
+const hc_EVP_CIPHER * hc_EVP_ossl_aes_256_cfb8(void);
+
+const hc_EVP_CIPHER * hc_EVP_ossl_camellia_128_cbc(void);
+const hc_EVP_CIPHER * hc_EVP_ossl_camellia_192_cbc(void);
+const hc_EVP_CIPHER * hc_EVP_ossl_camellia_256_cbc(void);
+
+HC_CPP_END
+
+#endif /* HEIM_EVP_OSSL_H */
index 5c1bc6c18d47749fc04d0ec242bc1a51bd985215..ed0d2fc492ffc8ece862fe8757e2aee6c05d6962 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Secure Endpoints Inc.
+ * Copyright (c) 2015-2016, Secure Endpoints Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
index a8aeb53bf95c4bb6627dd4dc7fe1abf799191d72..5e7c2e83f42bba85dedc07c5cdfaeb0380a6bce3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006 - 2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -46,6 +46,7 @@
 #include <evp-cc.h>
 #include <evp-w32.h>
 #include <evp-pkcs11.h>
+#include <evp-openssl.h>
 
 #include <krb5-types.h>
 
@@ -54,6 +55,8 @@
 #  define HCRYPTO_DEF_PROVIDER cc
 # elif __sun
 #  define HCRYPTO_DEF_PROVIDER pkcs11_hcrypto
+# elif HAVE_HCRYPTO_W_OPENSSL
+#  define HCRYPTO_DEF_PROVIDER ossl
 # else
 #  define HCRYPTO_DEF_PROVIDER hcrypto
 # endif
index 8c5be7916be6b9ae15a233d2f09a3b378092285d..22e8f4d048e64b19eaa08ebd9043b33aac84833f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005 - 2008 Kungliga Tekniska Högskolan
+ * Copyright (c) 2005 - 2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -154,7 +154,7 @@ struct hc_CIPHER {
      * cipher is used in (use EVP_CIPHER.._mode() to extract the
      * mode). The rest of the flag field is a bitfield.
      */
-#define hc_EVP_CIPH_STREAM_CIPHER               1
+#define hc_EVP_CIPH_STREAM_CIPHER               0
 #define hc_EVP_CIPH_CBC_MODE                    2
 #define hc_EVP_CIPH_CFB8_MODE                   4
 #define hc_EVP_CIPH_MODE                        0x7
@@ -171,8 +171,8 @@ struct hc_CIPHER {
                     const unsigned char *, unsigned int);
     int (*cleanup)(EVP_CIPHER_CTX *);
     int ctx_size;
-    void *set_asn1_parameters;
-    void *get_asn1_parameters;
+    int (*set_asn1_parameters)(void);
+    int (*get_asn1_parameters)(void);
     int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr);
 #define EVP_CTRL_RAND_KEY              0x6
 
@@ -197,6 +197,10 @@ struct hc_CIPHER_CTX {
     unsigned char final[EVP_MAX_BLOCK_LENGTH];
 };
 
+/*
+ * LIES.  It's not an EVP_MD_CTX that gets passed to these functions
+ * here in hcrypto, but an object of ctx_size.
+ */
 typedef int (*hc_evp_md_init)(EVP_MD_CTX *);
 typedef int (*hc_evp_md_update)(EVP_MD_CTX *,const void *, size_t);
 typedef int (*hc_evp_md_final)(void *, EVP_MD_CTX *);
index ef58e46387bf9dd2fbde55e2c242c81a884a4a31..366270f6c74eb1c3023b4a1ec10a8c7e52a049b1 100644 (file)
@@ -177,6 +177,25 @@ EXPORTS
 ;!     hc_EVP_cc_aes_192_cfb8
 ;!     hc_EVP_cc_aes_256_cfb8
 
+       hc_EVP_ossl_md2
+       hc_EVP_ossl_md4
+       hc_EVP_ossl_md5
+       hc_EVP_ossl_sha1
+       hc_EVP_ossl_sha256
+       hc_EVP_ossl_sha384
+       hc_EVP_ossl_sha512
+       hc_EVP_ossl_des_ede3_cbc
+       hc_EVP_ossl_aes_128_cbc
+       hc_EVP_ossl_aes_192_cbc
+       hc_EVP_ossl_aes_256_cbc
+       hc_EVP_ossl_aes_128_cfb8
+       hc_EVP_ossl_aes_192_cfb8
+       hc_EVP_ossl_aes_256_cfb8
+       hc_EVP_ossl_rc2_cbc
+       hc_EVP_ossl_rc2_40_cbc
+       hc_EVP_ossl_rc4
+       hc_EVP_ossl_rc4_40
+
        hc_EVP_pkcs11_md2
        hc_EVP_pkcs11_md4
        hc_EVP_pkcs11_md5
index afde93820843cda31fce3b1bfc902909bc7c035e..d301c5c4a422d5a3195494f1e774d4129164169a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995 - 2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -274,6 +274,10 @@ hash_test (struct hash_foo *hash, struct test *tests)
        char buf[1000];
 
        ectx = EVP_MD_CTX_create();
+        if (hash->evp() == NULL) {
+            printf("unavailable\n");
+            continue;
+        }
        EVP_DigestInit_ex(ectx, hash->evp(), NULL);
 
        (*hash->init)(ctx);
index 1c9df8a1802561df24b918cac65570c2c7a2313a..7b5553803fc933cddb18ab8b33bc4fa52f52da6c 100644 (file)
@@ -39,6 +39,8 @@
 #ifndef _HEIM_RAND_H
 #define _HEIM_RAND_H 1
 
+#define RAND_METHOD hc_RAND_METHOD
+
 typedef struct RAND_METHOD RAND_METHOD;
 
 #include <hcrypto/engine.h>
index a5bf51395c68227e4b55faf7cb3977af96992abc..d59213b3923e4331e9fd2717ec8e07d84edbd149 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006-2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
index 717e50b17671076d81911a529a48b2fd3b9df79e..357e90e5b15d1e2ee92d313299859f5d13d64281 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 2006-2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -43,6 +43,7 @@
 #include <evp-cc.h>
 #include <evp-w32.h>
 #include <evp-pkcs11.h>
+#include <evp-openssl.h>
 #include <hex.h>
 #include <err.h>
 
@@ -410,5 +411,21 @@ main(int argc, char **argv)
        ret += test_cipher(i, EVP_pkcs11_rc4(), &rc4_tests[i]);
 #endif /* PKCS11_MODULE_PATH */
 
+    /* OpenSSL */
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    for (i = 0; i < sizeof(aes_tests)/sizeof(aes_tests[0]); i++)
+       ret += test_cipher(i, EVP_ossl_aes_256_cbc(), &aes_tests[i]);
+    for (i = 0; i < sizeof(aes_cfb_tests)/sizeof(aes_cfb_tests[0]); i++)
+       ret += test_cipher(i, EVP_ossl_aes_128_cfb8(), &aes_cfb_tests[i]);
+    for (i = 0; i < sizeof(rc2_tests)/sizeof(rc2_tests[0]); i++)
+       ret += test_cipher(i, EVP_ossl_rc2_cbc(), &rc2_tests[i]);
+    for (i = 0; i < sizeof(rc2_40_tests)/sizeof(rc2_40_tests[0]); i++)
+       ret += test_cipher(i, EVP_ossl_rc2_40_cbc(), &rc2_40_tests[i]);
+    for (i = 0; i < sizeof(des_ede3_tests)/sizeof(des_ede3_tests[0]); i++)
+       ret += test_cipher(i, EVP_ossl_des_ede3_cbc(), &des_ede3_tests[i]);
+    for (i = 0; i < sizeof(rc4_tests)/sizeof(rc4_tests[0]); i++)
+       ret += test_cipher(i, EVP_ossl_rc4(), &rc4_tests[i]);
+#endif /* PKCS11_MODULE_PATH */
+
     return ret;
 }
index 177e27981c2046bd1b6b480e43068eabed2dd9ef..e94048baf4e9474ef866e25d5ebbe46b3b44015a 100644 (file)
@@ -201,6 +201,25 @@ HEIMDAL_CRYPTO_1.0 {
                hc_EVP_hcrypto_rc4;
                hc_EVP_hcrypto_rc4_40;
 
+               hc_EVP_ossl_md2;
+               hc_EVP_ossl_md4;
+               hc_EVP_ossl_md5;
+               hc_EVP_ossl_sha1;
+               hc_EVP_ossl_sha256;
+               hc_EVP_ossl_sha384;
+               hc_EVP_ossl_sha512;
+               hc_EVP_ossl_des_ede3_cbc;
+               hc_EVP_ossl_aes_128_cbc;
+               hc_EVP_ossl_aes_192_cbc;
+               hc_EVP_ossl_aes_256_cbc;
+               hc_EVP_ossl_aes_128_cfb8;
+               hc_EVP_ossl_aes_192_cfb8;
+               hc_EVP_ossl_aes_256_cfb8;
+               hc_EVP_ossl_rc2_cbc;
+               hc_EVP_ossl_rc2_40_cbc;
+               hc_EVP_ossl_rc4;
+               hc_EVP_ossl_rc4_40;
+
                hc_EVP_pkcs11_md2;
                hc_EVP_pkcs11_md4;
                hc_EVP_pkcs11_md5;
index b8c50cce421703f7ab0fc2bcc40c1f9ae540244c..140d5d7ca52526b25282130d8ab153259eecd8e7 100644 (file)
@@ -2,7 +2,7 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += -I../asn1 -I$(srcdir)/../asn1 $(INCLUDE_hcrypto)
+AM_CPPFLAGS += -I../asn1 -I$(srcdir)/../asn1
 AM_CPPFLAGS += $(INCLUDE_openldap) -DHDB_DB_DIR=\"$(DIR_hdbdir)\"
 AM_CPPFLAGS += -I$(srcdir)/../krb5
 AM_CPPFLAGS += $(INCLUDE_sqlite3)
index f093cbb10b0804c8c1cde6089b0b925bf1e4e673..cd8ccc55365f247423da28a4f6b23fbc558281ea 100644 (file)
@@ -58,6 +58,7 @@ dist_libhx509_la_SOURCES = \
        cms.c \
        collector.c \
        crypto.c \
+       crypto-ec.c \
        doxygen.c \
        error.c \
        env.c \
@@ -92,6 +93,7 @@ libhx509_la_DEPENDENCIES = version-script.map
 libhx509_la_LIBADD = \
        $(LIB_com_err) \
        $(LIB_hcrypto) \
+       $(LIB_openssl_crypto) \
        $(top_builddir)/lib/asn1/libasn1.la \
        $(top_builddir)/lib/wind/libwind.la \
        $(top_builddir)/lib/base/libheimbase.la \
@@ -107,7 +109,6 @@ libhx509_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map
 endif
 $(libhx509_la_OBJECTS): $(srcdir)/version-script.map $(nodist_include_HEADERS) $(priv_headers)
 
-libhx509_la_CPPFLAGS = $(INCLUDE_hcrypto)
 nodist_libhx509_la_SOURCES = $(BUILT_SOURCES)
 
 $(gen_files_ocsp) ocsp_asn1.hx ocsp_asn1-priv.hx: ocsp_asn1_files
@@ -163,7 +164,6 @@ nodist_hxtool_SOURCES = hxtool-commands.c hxtool-commands.h
 
 $(hxtool_OBJECTS): hxtool-commands.h hx509_err.h
 
-hxtool_CPPFLAGS = $(INCLUDE_hcrypto)
 hxtool_LDADD = \
        libhx509.la \
        $(top_builddir)/lib/asn1/libasn1.la \
@@ -207,11 +207,8 @@ check_PROGRAMS = $(PROGRAM_TESTS) test_soft_pkcs11
 LDADD = libhx509.la
 
 test_soft_pkcs11_LDADD = libhx509.la
-test_soft_pkcs11_CPPFLAGS = $(INCLUDE_hcrypto)
 
-test_name_CPPFLAGS = $(INCLUDE_hcrypto)
 test_name_LDADD = libhx509.la $(LIB_roken)
-test_expr_CPPFLAGS = $(INCLUDE_hcrypto)
 test_expr_LDADD = libhx509.la $(LIB_roken)
 
 TESTS = $(SCRIPT_TESTS) $(PROGRAM_TESTS)
index 91f5f4c73f7fab76b8844c52ee699b54ca76139b..871c4ee5a452b47c23a0c0a0a2befd876246988e 100644 (file)
@@ -1,6 +1,6 @@
 ########################################################################
 #
-# Copyright (c) 2009, Secure Endpoints Inc.
+# Copyright (c) 2009-2016, Secure Endpoints Inc.
 # All rights reserved.
 # 
 # Redistribution and use in source and binary forms, with or without
@@ -47,6 +47,7 @@ libhx509_la_OBJS =                    \
        $(OBJ)\cms.obj                  \
        $(OBJ)\collector.obj            \
        $(OBJ)\crypto.obj               \
+       $(OBJ)\crypto-ec.obj            \
        $(OBJ)\error.obj                \
        $(OBJ)\env.obj                  \
        $(OBJ)\file.obj                 \
@@ -81,6 +82,7 @@ dist_libhx509_la_SOURCES =    \
        $(SRCDIR)\cms.c         \
        $(SRCDIR)\collector.c   \
        $(SRCDIR)\crypto.c      \
+       $(SRCDIR)\crypto-ec.c   \
        $(SRCDIR)\doxygen.c     \
        $(SRCDIR)\error.c       \
        $(SRCDIR)\env.c         \
@@ -162,7 +164,7 @@ $(OBJ)\hxtool-commands.c $(OBJ)\hxtool-commands.h: hxtool-commands.in $(SLC)
        cd $(SRCDIR)
 
 $(BINDIR)\hxtool.exe: $(OBJ)\tool\hxtool.obj $(OBJ)\tool\hxtool-commands.obj $(LIBHEIMDAL) $(OBJ)\hxtool-version.res
-       $(EXECONLINK) $(LIBHEIMDAL) $(LIBROKEN) $(LIBSL) $(LIBVERS) $(LIBCOMERR)
+       $(EXECONLINK) $(LIBHEIMDAL) $(LIBROKEN) $(LIBSL) $(LIBVERS) $(LIBCOMERR) $(LIB_openssl_crypto)
        $(EXEPREP)
 
 $(OBJ)\hx509-protos.h:
diff --git a/lib/hx509/crypto-ec.c b/lib/hx509/crypto-ec.c
new file mode 100644 (file)
index 0000000..698e52c
--- /dev/null
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 2016 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 <config.h>
+
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#define HEIM_NO_CRYPTO_HDRS
+#endif /* HAVE_HCRYPTO_W_OPENSSL */
+
+#include "hx_locl.h"
+
+extern const AlgorithmIdentifier _hx509_signature_sha256_data;
+extern const AlgorithmIdentifier _hx509_signature_sha1_data;
+
+void
+_hx509_private_eckey_free(void *eckey)
+{
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    EC_KEY_free(eckey);
+#endif
+}
+
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+static int
+heim_oid2ecnid(heim_oid *oid)
+{
+    /*
+     * Now map to openssl OID fun
+     */
+
+    if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP256R1) == 0)
+       return NID_X9_62_prime256v1;
+    else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R1) == 0)
+       return NID_secp160r1;
+    else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R2) == 0)
+       return NID_secp160r2;
+
+    return NID_undef;
+}
+
+static int
+parse_ECParameters(hx509_context context,
+                  heim_octet_string *parameters, int *nid)
+{
+    ECParameters ecparam;
+    size_t size;
+    int ret;
+
+    if (parameters == NULL) {
+       ret = HX509_PARSING_KEY_FAILED;
+       hx509_set_error_string(context, 0, ret,
+                              "EC parameters missing");
+       return ret;
+    }
+
+    ret = decode_ECParameters(parameters->data, parameters->length,
+                             &ecparam, &size);
+    if (ret) {
+       hx509_set_error_string(context, 0, ret,
+                              "Failed to decode EC parameters");
+       return ret;
+    }
+
+    if (ecparam.element != choice_ECParameters_namedCurve) {
+       free_ECParameters(&ecparam);
+       hx509_set_error_string(context, 0, ret,
+                              "EC parameters is not a named curve");
+       return HX509_CRYPTO_SIG_INVALID_FORMAT;
+    }
+
+    *nid = heim_oid2ecnid(&ecparam.u.namedCurve);
+    free_ECParameters(&ecparam);
+    if (*nid == NID_undef) {
+       hx509_set_error_string(context, 0, ret,
+                              "Failed to find matcing NID for EC curve");
+       return HX509_CRYPTO_SIG_INVALID_FORMAT;
+    }
+    return 0;
+}
+
+
+/*
+ *
+ */
+
+static int
+ecdsa_verify_signature(hx509_context context,
+                      const struct signature_alg *sig_alg,
+                      const Certificate *signer,
+                      const AlgorithmIdentifier *alg,
+                      const heim_octet_string *data,
+                      const heim_octet_string *sig)
+{
+    const AlgorithmIdentifier *digest_alg;
+    const SubjectPublicKeyInfo *spi;
+    heim_octet_string digest;
+    int ret;
+    EC_KEY *key = NULL;
+    int groupnid;
+    EC_GROUP *group;
+    const unsigned char *p;
+    long len;
+
+    digest_alg = sig_alg->digest_alg;
+
+    ret = _hx509_create_signature(context,
+                                 NULL,
+                                 digest_alg,
+                                 data,
+                                 NULL,
+                                 &digest);
+    if (ret)
+       return ret;
+
+    /* set up EC KEY */
+    spi = &signer->tbsCertificate.subjectPublicKeyInfo;
+
+    if (der_heim_oid_cmp(&spi->algorithm.algorithm, ASN1_OID_ID_ECPUBLICKEY) != 0)
+       return HX509_CRYPTO_SIG_INVALID_FORMAT;
+
+    /*
+     * Find the group id
+     */
+
+    ret = parse_ECParameters(context, spi->algorithm.parameters, &groupnid);
+    if (ret) {
+       der_free_octet_string(&digest);
+       return ret;
+    }
+
+    /*
+     * Create group, key, parse key
+     */
+
+    key = EC_KEY_new();
+    group = EC_GROUP_new_by_curve_name(groupnid);
+    EC_KEY_set_group(key, group);
+    EC_GROUP_free(group);
+
+    p = spi->subjectPublicKey.data;
+    len = spi->subjectPublicKey.length / 8;
+
+    if (o2i_ECPublicKey(&key, &p, len) == NULL) {
+       EC_KEY_free(key);
+       return HX509_CRYPTO_SIG_INVALID_FORMAT;
+    }
+
+    ret = ECDSA_verify(-1, digest.data, digest.length,
+                      sig->data, sig->length, key);
+    der_free_octet_string(&digest);
+    EC_KEY_free(key);
+    if (ret != 1) {
+       ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
+       return ret;
+    }
+
+    return 0;
+}
+
+static int
+ecdsa_create_signature(hx509_context context,
+                      const struct signature_alg *sig_alg,
+                      const hx509_private_key signer,
+                      const AlgorithmIdentifier *alg,
+                      const heim_octet_string *data,
+                      AlgorithmIdentifier *signatureAlgorithm,
+                      heim_octet_string *sig)
+{
+    const AlgorithmIdentifier *digest_alg;
+    heim_octet_string indata;
+    const heim_oid *sig_oid;
+    unsigned int siglen;
+    int ret;
+
+    if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) != 0)
+       _hx509_abort("internal error passing private key to wrong ops");
+
+    sig_oid = sig_alg->sig_oid;
+    digest_alg = sig_alg->digest_alg;
+
+    if (signatureAlgorithm) {
+        ret = _hx509_set_digest_alg(signatureAlgorithm, sig_oid,
+                                    "\x05\x00", 2);
+       if (ret) {
+           hx509_clear_error_string(context);
+           return ret;
+       }
+    }
+
+    ret = _hx509_create_signature(context,
+                                 NULL,
+                                 digest_alg,
+                                 data,
+                                 NULL,
+                                 &indata);
+    if (ret)
+       goto error;
+
+    sig->length = ECDSA_size(signer->private_key.ecdsa);
+    sig->data = malloc(sig->length);
+    if (sig->data == NULL) {
+       der_free_octet_string(&indata);
+       ret = ENOMEM;
+       hx509_set_error_string(context, 0, ret, "out of memory");
+       goto error;
+    }
+
+    siglen = sig->length;
+
+    ret = ECDSA_sign(-1, indata.data, indata.length,
+                    sig->data, &siglen, signer->private_key.ecdsa);
+    der_free_octet_string(&indata);
+    if (ret != 1) {
+       ret = HX509_CMS_FAILED_CREATE_SIGATURE;
+       hx509_set_error_string(context, 0, ret,
+                              "ECDSA sign failed: %d", ret);
+       goto error;
+    }
+    if (siglen > sig->length)
+       _hx509_abort("ECDSA signature prelen longer the output len");
+
+    sig->length = siglen;
+
+    return 0;
+ error:
+    if (signatureAlgorithm)
+       free_AlgorithmIdentifier(signatureAlgorithm);
+    return ret;
+}
+
+static int
+ecdsa_available(const hx509_private_key signer,
+               const AlgorithmIdentifier *sig_alg)
+{
+    const struct signature_alg *sig;
+    const EC_GROUP *group;
+    BN_CTX *bnctx = NULL;
+    BIGNUM *order = NULL;
+    int ret = 0;
+
+    if (der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
+       _hx509_abort("internal error passing private key to wrong ops");
+
+    sig = _hx509_find_sig_alg(&sig_alg->algorithm);
+
+    if (sig == NULL || sig->digest_size == 0)
+       return 0;
+
+    group = EC_KEY_get0_group(signer->private_key.ecdsa);
+    if (group == NULL)
+       return 0;
+
+    bnctx = BN_CTX_new();
+    order = BN_new();
+    if (order == NULL)
+       goto err;
+
+    if (EC_GROUP_get_order(group, order, bnctx) != 1)
+       goto err;
+
+    if (BN_num_bytes(order) > sig->digest_size)
+       ret = 1;
+ err:
+    if (bnctx)
+       BN_CTX_free(bnctx);
+    if (order)
+       BN_clear_free(order);
+
+    return ret;
+}
+
+static int
+ecdsa_private_key2SPKI(hx509_context context,
+                      hx509_private_key private_key,
+                      SubjectPublicKeyInfo *spki)
+{
+    memset(spki, 0, sizeof(*spki));
+    return ENOMEM;
+}
+
+static int
+ecdsa_private_key_export(hx509_context context,
+                        const hx509_private_key key,
+                        hx509_key_format_t format,
+                        heim_octet_string *data)
+{
+    return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
+}
+
+static int
+ecdsa_private_key_import(hx509_context context,
+                        const AlgorithmIdentifier *keyai,
+                        const void *data,
+                        size_t len,
+                        hx509_key_format_t format,
+                        hx509_private_key private_key)
+{
+    const unsigned char *p = data;
+    EC_KEY **pkey = NULL;
+    EC_KEY *key;
+
+    if (keyai->parameters) {
+       EC_GROUP *group;
+       int groupnid;
+       int ret;
+
+       ret = parse_ECParameters(context, keyai->parameters, &groupnid);
+       if (ret)
+           return ret;
+
+       key = EC_KEY_new();
+       if (key == NULL)
+           return ENOMEM;
+
+       group = EC_GROUP_new_by_curve_name(groupnid);
+       if (group == NULL) {
+           EC_KEY_free(key);
+           return ENOMEM;
+       }
+       EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+       if (EC_KEY_set_group(key, group) == 0) {
+           EC_KEY_free(key);
+           EC_GROUP_free(group);
+           return ENOMEM;
+       }
+       EC_GROUP_free(group);
+       pkey = &key;
+    }
+
+    switch (format) {
+    case HX509_KEY_FORMAT_DER:
+
+       private_key->private_key.ecdsa = d2i_ECPrivateKey(pkey, &p, len);
+       if (private_key->private_key.ecdsa == NULL) {
+           hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
+                                  "Failed to parse EC private key");
+           return HX509_PARSING_KEY_FAILED;
+       }
+       private_key->signature_alg = ASN1_OID_ID_ECDSA_WITH_SHA256;
+       break;
+
+    default:
+       return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
+    }
+
+    return 0;
+}
+
+static int
+ecdsa_generate_private_key(hx509_context context,
+                          struct hx509_generate_private_context *ctx,
+                          hx509_private_key private_key)
+{
+    return ENOMEM;
+}
+
+static BIGNUM *
+ecdsa_get_internal(hx509_context context,
+                  hx509_private_key key,
+                  const char *type)
+{
+    return NULL;
+}
+
+static const unsigned ecPublicKey[] ={ 1, 2, 840, 10045, 2, 1 };
+const AlgorithmIdentifier _hx509_signature_ecPublicKey = {
+    { 6, rk_UNCONST(ecPublicKey) }, NULL
+};
+
+static const unsigned ecdsa_with_sha256_oid[] ={ 1, 2, 840, 10045, 4, 3, 2 };
+const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha256_data = {
+    { 7, rk_UNCONST(ecdsa_with_sha256_oid) }, NULL
+};
+
+static const unsigned ecdsa_with_sha1_oid[] ={ 1, 2, 840, 10045, 4, 1 };
+const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha1_data = {
+    { 6, rk_UNCONST(ecdsa_with_sha1_oid) }, NULL
+};
+
+
+const AlgorithmIdentifier *
+hx509_signature_ecdsa_with_sha1(void)
+{ return &_hx509_signature_ecdsa_with_sha1_data; }
+
+
+hx509_private_key_ops ecdsa_private_key_ops = {
+    "EC PRIVATE KEY",
+    ASN1_OID_ID_ECPUBLICKEY,
+    ecdsa_available,
+    ecdsa_private_key2SPKI,
+    ecdsa_private_key_export,
+    ecdsa_private_key_import,
+    ecdsa_generate_private_key,
+    ecdsa_get_internal
+};
+
+const struct signature_alg ecdsa_with_sha256_alg = {
+    "ecdsa-with-sha256",
+    ASN1_OID_ID_ECDSA_WITH_SHA256,
+    &_hx509_signature_ecdsa_with_sha256_data,
+    ASN1_OID_ID_ECPUBLICKEY,
+    &_hx509_signature_sha256_data,
+    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|
+        SIG_PUBLIC_SIG|SELF_SIGNED_OK,
+    0,
+    NULL,
+    ecdsa_verify_signature,
+    ecdsa_create_signature,
+    32
+};
+
+const struct signature_alg ecdsa_with_sha1_alg = {
+    "ecdsa-with-sha1",
+    ASN1_OID_ID_ECDSA_WITH_SHA1,
+    &_hx509_signature_ecdsa_with_sha1_data,
+    ASN1_OID_ID_ECPUBLICKEY,
+    &_hx509_signature_sha1_data,
+    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|
+        SIG_PUBLIC_SIG|SELF_SIGNED_OK,
+    0,
+    NULL,
+    ecdsa_verify_signature,
+    ecdsa_create_signature,
+    20
+};
+
+#endif /* HAVE_HCRYPTO_W_OPENSSL */
+
+const AlgorithmIdentifier *
+hx509_signature_ecPublicKey(void)
+{
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    return &_hx509_signature_ecPublicKey;
+#else
+    return NULL;
+#endif /* HAVE_HCRYPTO_W_OPENSSL */
+}
+
+const AlgorithmIdentifier *
+hx509_signature_ecdsa_with_sha256(void)
+{
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    return &_hx509_signature_ecdsa_with_sha256_data;
+#else
+    return NULL;
+#endif /* HAVE_HCRYPTO_W_OPENSSL */
+}
index 1949588a3a2d43388805950bc2c785eb297a9f76..5296686acbe2b953a7488c42c64faf7fc216dc77 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 2004 - 2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
 
 #include "hx_locl.h"
 
-struct hx509_crypto;
-
-struct signature_alg;
-
-struct hx509_generate_private_context {
-    const heim_oid *key_oid;
-    int isCA;
-    unsigned long num_bits;
-};
-
-struct hx509_private_key_ops {
-    const char *pemtype;
-    const heim_oid *key_oid;
-    int (*available)(const hx509_private_key,
-                    const AlgorithmIdentifier *);
-    int (*get_spki)(hx509_context,
-                   const hx509_private_key,
-                   SubjectPublicKeyInfo *);
-    int (*export)(hx509_context context,
-                 const hx509_private_key,
-                 hx509_key_format_t,
-                 heim_octet_string *);
-    int (*import)(hx509_context, const AlgorithmIdentifier *,
-                 const void *, size_t, hx509_key_format_t,
-                 hx509_private_key);
-    int (*generate_private_key)(hx509_context,
-                               struct hx509_generate_private_context *,
-                               hx509_private_key);
-    BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
-};
-
-struct hx509_private_key {
-    unsigned int ref;
-    const struct signature_alg *md;
-    const heim_oid *signature_alg;
-    union {
-       RSA *rsa;
-       void *keydata;
-#ifdef HAVE_OPENSSL
-       EC_KEY *ecdsa;
-#endif
-    } private_key;
-    hx509_private_key_ops *ops;
-};
-
-/*
- *
- */
-
-struct signature_alg {
-    const char *name;
-    const heim_oid *sig_oid;
-    const AlgorithmIdentifier *sig_alg;
-    const heim_oid *key_oid;
-    const AlgorithmIdentifier *digest_alg;
-    int flags;
-#define PROVIDE_CONF   0x1
-#define REQUIRE_SIGNER 0x2
-#define SELF_SIGNED_OK 0x4
-#define WEAK_SIG_ALG   0x8
-
-#define SIG_DIGEST     0x100
-#define SIG_PUBLIC_SIG 0x200
-#define SIG_SECRET     0x400
-
-#define RA_RSA_USES_DIGEST_INFO 0x1000000
-
-    time_t best_before; /* refuse signature made after best before date */
-    const EVP_MD *(*evp_md)(void);
-    int (*verify_signature)(hx509_context context,
-                           const struct signature_alg *,
-                           const Certificate *,
-                           const AlgorithmIdentifier *,
-                           const heim_octet_string *,
-                           const heim_octet_string *);
-    int (*create_signature)(hx509_context,
-                           const struct signature_alg *,
-                           const hx509_private_key,
-                           const AlgorithmIdentifier *,
-                           const heim_octet_string *,
-                           AlgorithmIdentifier *,
-                           heim_octet_string *);
-    int digest_size;
-};
-
-static const struct signature_alg *
-find_sig_alg(const heim_oid *oid);
-
 /*-
  * RFC5758 specifies no parameters for ecdsa-with-SHA<N> signatures
  * RFC5754 specifies NULL parameters for sha<N>WithRSAEncryption signatures
@@ -156,21 +68,6 @@ const AlgorithmIdentifier _hx509_signature_md5_data = {
     { 6, rk_UNCONST(md5_oid_tree) }, rk_UNCONST(&null_entry_oid)
 };
 
-static const unsigned ecPublicKey[] ={ 1, 2, 840, 10045, 2, 1 };
-const AlgorithmIdentifier _hx509_signature_ecPublicKey = {
-    { 6, rk_UNCONST(ecPublicKey) }, NULL
-};
-
-static const unsigned ecdsa_with_sha256_oid[] ={ 1, 2, 840, 10045, 4, 3, 2 };
-const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha256_data = {
-    { 7, rk_UNCONST(ecdsa_with_sha256_oid) }, NULL
-};
-
-static const unsigned ecdsa_with_sha1_oid[] ={ 1, 2, 840, 10045, 4, 1 };
-const AlgorithmIdentifier _hx509_signature_ecdsa_with_sha1_data = {
-    { 6, rk_UNCONST(ecdsa_with_sha1_oid) }, NULL
-};
-
 static const unsigned rsa_with_sha512_oid[] ={ 1, 2, 840, 113549, 1, 1, 13 };
 const AlgorithmIdentifier _hx509_signature_rsa_with_sha512_data = {
     { 7, rk_UNCONST(rsa_with_sha512_oid) }, rk_UNCONST(&null_entry_oid)
@@ -239,10 +136,10 @@ heim_int2BN(const heim_integer *i)
  *
  */
 
-static int
-set_digest_alg(DigestAlgorithmIdentifier *id,
-              const heim_oid *oid,
-              const void *param, size_t length)
+int
+_hx509_set_digest_alg(DigestAlgorithmIdentifier *id,
+                      const heim_oid *oid,
+                      const void *param, size_t length)
 {
     int ret;
     if (param) {
@@ -271,262 +168,6 @@ set_digest_alg(DigestAlgorithmIdentifier *id,
     return 0;
 }
 
-#ifdef HAVE_OPENSSL
-
-static int
-heim_oid2ecnid(heim_oid *oid)
-{
-    /*
-     * Now map to openssl OID fun
-     */
-
-    if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP256R1) == 0)
-       return NID_X9_62_prime256v1;
-    else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R1) == 0)
-       return NID_secp160r1;
-    else if (der_heim_oid_cmp(oid, ASN1_OID_ID_EC_GROUP_SECP160R2) == 0)
-       return NID_secp160r2;
-
-    return -1;
-}
-
-static int
-parse_ECParameters(hx509_context context,
-                  heim_octet_string *parameters, int *nid)
-{
-    ECParameters ecparam;
-    size_t size;
-    int ret;
-
-    if (parameters == NULL) {
-       ret = HX509_PARSING_KEY_FAILED;
-       hx509_set_error_string(context, 0, ret,
-                              "EC parameters missing");
-       return ret;
-    }
-
-    ret = decode_ECParameters(parameters->data, parameters->length,
-                             &ecparam, &size);
-    if (ret) {
-       hx509_set_error_string(context, 0, ret,
-                              "Failed to decode EC parameters");
-       return ret;
-    }
-
-    if (ecparam.element != choice_ECParameters_namedCurve) {
-       free_ECParameters(&ecparam);
-       hx509_set_error_string(context, 0, ret,
-                              "EC parameters is not a named curve");
-       return HX509_CRYPTO_SIG_INVALID_FORMAT;
-    }
-
-    *nid = heim_oid2ecnid(&ecparam.u.namedCurve);
-    free_ECParameters(&ecparam);
-    if (*nid == -1) {
-       hx509_set_error_string(context, 0, ret,
-                              "Failed to find matcing NID for EC curve");
-       return HX509_CRYPTO_SIG_INVALID_FORMAT;
-    }
-    return 0;
-}
-
-
-/*
- *
- */
-
-static int
-ecdsa_verify_signature(hx509_context context,
-                      const struct signature_alg *sig_alg,
-                      const Certificate *signer,
-                      const AlgorithmIdentifier *alg,
-                      const heim_octet_string *data,
-                      const heim_octet_string *sig)
-{
-    const AlgorithmIdentifier *digest_alg;
-    const SubjectPublicKeyInfo *spi;
-    heim_octet_string digest;
-    int ret;
-    EC_KEY *key = NULL;
-    int groupnid;
-    EC_GROUP *group;
-    const unsigned char *p;
-    long len;
-
-    digest_alg = sig_alg->digest_alg;
-
-    ret = _hx509_create_signature(context,
-                                 NULL,
-                                 digest_alg,
-                                 data,
-                                 NULL,
-                                 &digest);
-    if (ret)
-       return ret;
-
-    /* set up EC KEY */
-    spi = &signer->tbsCertificate.subjectPublicKeyInfo;
-
-    if (der_heim_oid_cmp(&spi->algorithm.algorithm, ASN1_OID_ID_ECPUBLICKEY) != 0)
-       return HX509_CRYPTO_SIG_INVALID_FORMAT;
-
-#ifdef HAVE_OPENSSL
-    /*
-     * Find the group id
-     */
-
-    ret = parse_ECParameters(context, spi->algorithm.parameters, &groupnid);
-    if (ret) {
-       der_free_octet_string(&digest);
-       return ret;
-    }
-
-    /*
-     * Create group, key, parse key
-     */
-
-    key = EC_KEY_new();
-    group = EC_GROUP_new_by_curve_name(groupnid);
-    EC_KEY_set_group(key, group);
-    EC_GROUP_free(group);
-
-    p = spi->subjectPublicKey.data;
-    len = spi->subjectPublicKey.length / 8;
-
-    if (o2i_ECPublicKey(&key, &p, len) == NULL) {
-       EC_KEY_free(key);
-       return HX509_CRYPTO_SIG_INVALID_FORMAT;
-    }
-#else
-    key = SubjectPublicKeyInfo2EC_KEY(spi);
-#endif
-
-    ret = ECDSA_verify(-1, digest.data, digest.length,
-                      sig->data, sig->length, key);
-    der_free_octet_string(&digest);
-    EC_KEY_free(key);
-    if (ret != 1) {
-       ret = HX509_CRYPTO_SIG_INVALID_FORMAT;
-       return ret;
-    }
-
-    return 0;
-}
-
-static int
-ecdsa_create_signature(hx509_context context,
-                      const struct signature_alg *sig_alg,
-                      const hx509_private_key signer,
-                      const AlgorithmIdentifier *alg,
-                      const heim_octet_string *data,
-                      AlgorithmIdentifier *signatureAlgorithm,
-                      heim_octet_string *sig)
-{
-    const AlgorithmIdentifier *digest_alg;
-    heim_octet_string indata;
-    const heim_oid *sig_oid;
-    unsigned int siglen;
-    int ret;
-
-    if (signer->ops && der_heim_oid_cmp(signer->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) != 0)
-       _hx509_abort("internal error passing private key to wrong ops");
-
-    sig_oid = sig_alg->sig_oid;
-    digest_alg = sig_alg->digest_alg;
-
-    if (signatureAlgorithm) {
-       ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
-       if (ret) {
-           hx509_clear_error_string(context);
-           return ret;
-       }
-    }
-
-    ret = _hx509_create_signature(context,
-                                 NULL,
-                                 digest_alg,
-                                 data,
-                                 NULL,
-                                 &indata);
-    if (ret)
-       goto error;
-
-    sig->length = ECDSA_size(signer->private_key.ecdsa);
-    sig->data = malloc(sig->length);
-    if (sig->data == NULL) {
-       der_free_octet_string(&indata);
-       ret = ENOMEM;
-       hx509_set_error_string(context, 0, ret, "out of memory");
-       goto error;
-    }
-
-    siglen = sig->length;
-
-    ret = ECDSA_sign(-1, indata.data, indata.length,
-                    sig->data, &siglen, signer->private_key.ecdsa);
-    der_free_octet_string(&indata);
-    if (ret != 1) {
-       ret = HX509_CMS_FAILED_CREATE_SIGATURE;
-       hx509_set_error_string(context, 0, ret,
-                              "ECDSA sign failed: %d", ret);
-       goto error;
-    }
-    if (siglen > sig->length)
-       _hx509_abort("ECDSA signature prelen longer the output len");
-
-    sig->length = siglen;
-
-    return 0;
- error:
-    if (signatureAlgorithm)
-       free_AlgorithmIdentifier(signatureAlgorithm);
-    return ret;
-}
-
-static int
-ecdsa_available(const hx509_private_key signer,
-               const AlgorithmIdentifier *sig_alg)
-{
-    const struct signature_alg *sig;
-    const EC_GROUP *group;
-    BN_CTX *bnctx = NULL;
-    BIGNUM *order = NULL;
-    int ret = 0;
-
-    if (der_heim_oid_cmp(signer->ops->key_oid, &asn1_oid_id_ecPublicKey) != 0)
-       _hx509_abort("internal error passing private key to wrong ops");
-
-    sig = find_sig_alg(&sig_alg->algorithm);
-
-    if (sig == NULL || sig->digest_size == 0)
-       return 0;
-
-    group = EC_KEY_get0_group(signer->private_key.ecdsa);
-    if (group == NULL)
-       return 0;
-
-    bnctx = BN_CTX_new();
-    order = BN_new();
-    if (order == NULL)
-       goto err;
-
-    if (EC_GROUP_get_order(group, order, bnctx) != 1)
-       goto err;
-
-    if (BN_num_bytes(order) > sig->digest_size)
-       ret = 1;
- err:
-    if (bnctx)
-       BN_CTX_free(bnctx);
-    if (order)
-       BN_clear_free(order);
-
-    return ret;
-}
-
-
-#endif /* HAVE_OPENSSL */
-
 /*
  *
  */
@@ -688,7 +329,8 @@ rsa_create_signature(hx509_context context,
        return HX509_ALG_NOT_SUPP;
 
     if (signatureAlgorithm) {
-       ret = set_digest_alg(signatureAlgorithm, sig_oid, "\x05\x00", 2);
+        ret = _hx509_set_digest_alg(signatureAlgorithm, sig_oid,
+                                    "\x05\x00", 2);
        if (ret) {
            hx509_clear_error_string(context);
            return ret;
@@ -802,8 +444,9 @@ rsa_private_key2SPKI(hx509_context context,
     }
     spki->subjectPublicKey.length = len * 8;
 
-    ret = set_digest_alg(&spki->algorithm, ASN1_OID_ID_PKCS1_RSAENCRYPTION,
-                        "\x05\x00", 2);
+    ret = _hx509_set_digest_alg(&spki->algorithm,
+                                ASN1_OID_ID_PKCS1_RSAENCRYPTION,
+                                "\x05\x00", 2);
     if (ret) {
        hx509_set_error_string(context, 0, ret, "malloc - out of memory");
        free(spki->subjectPublicKey.data);
@@ -927,115 +570,6 @@ static hx509_private_key_ops rsa_private_key_ops = {
     rsa_get_internal
 };
 
-#ifdef HAVE_OPENSSL
-
-static int
-ecdsa_private_key2SPKI(hx509_context context,
-                      hx509_private_key private_key,
-                      SubjectPublicKeyInfo *spki)
-{
-    memset(spki, 0, sizeof(*spki));
-    return ENOMEM;
-}
-
-static int
-ecdsa_private_key_export(hx509_context context,
-                        const hx509_private_key key,
-                        hx509_key_format_t format,
-                        heim_octet_string *data)
-{
-    return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
-}
-
-static int
-ecdsa_private_key_import(hx509_context context,
-                        const AlgorithmIdentifier *keyai,
-                        const void *data,
-                        size_t len,
-                        hx509_key_format_t format,
-                        hx509_private_key private_key)
-{
-    const unsigned char *p = data;
-    EC_KEY **pkey = NULL;
-    EC_KEY *key;
-
-    if (keyai->parameters) {
-       EC_GROUP *group;
-       int groupnid;
-       int ret;
-
-       ret = parse_ECParameters(context, keyai->parameters, &groupnid);
-       if (ret)
-           return ret;
-
-       key = EC_KEY_new();
-       if (key == NULL)
-           return ENOMEM;
-
-       group = EC_GROUP_new_by_curve_name(groupnid);
-       if (group == NULL) {
-           EC_KEY_free(key);
-           return ENOMEM;
-       }
-       EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
-       if (EC_KEY_set_group(key, group) == 0) {
-           EC_KEY_free(key);
-           EC_GROUP_free(group);
-           return ENOMEM;
-       }
-       EC_GROUP_free(group);
-       pkey = &key;
-    }
-
-    switch (format) {
-    case HX509_KEY_FORMAT_DER:
-
-       private_key->private_key.ecdsa = d2i_ECPrivateKey(pkey, &p, len);
-       if (private_key->private_key.ecdsa == NULL) {
-           hx509_set_error_string(context, 0, HX509_PARSING_KEY_FAILED,
-                                  "Failed to parse EC private key");
-           return HX509_PARSING_KEY_FAILED;
-       }
-       private_key->signature_alg = ASN1_OID_ID_ECDSA_WITH_SHA256;
-       break;
-
-    default:
-       return HX509_CRYPTO_KEY_FORMAT_UNSUPPORTED;
-    }
-
-    return 0;
-}
-
-static int
-ecdsa_generate_private_key(hx509_context context,
-                          struct hx509_generate_private_context *ctx,
-                          hx509_private_key private_key)
-{
-    return ENOMEM;
-}
-
-static BIGNUM *
-ecdsa_get_internal(hx509_context context,
-                  hx509_private_key key,
-                  const char *type)
-{
-    return NULL;
-}
-
-
-static hx509_private_key_ops ecdsa_private_key_ops = {
-    "EC PRIVATE KEY",
-    ASN1_OID_ID_ECPUBLICKEY,
-    ecdsa_available,
-    ecdsa_private_key2SPKI,
-    ecdsa_private_key_export,
-    ecdsa_private_key_import,
-    ecdsa_generate_private_key,
-    ecdsa_get_internal
-};
-
-#endif /* HAVE_OPENSSL */
-
 /*
  *
  */
@@ -1164,8 +698,8 @@ evp_md_create_signature(hx509_context context,
 
     if (signatureAlgorithm) {
        int ret;
-       ret = set_digest_alg(signatureAlgorithm, sig_alg->sig_oid,
-                            "\x05\x00", 2);
+        ret = _hx509_set_digest_alg(signatureAlgorithm,
+                                    sig_alg->sig_oid, "\x05\x00", 2);
        if (ret)
            return ret;
     }
@@ -1221,36 +755,9 @@ evp_md_verify_signature(hx509_context context,
     return 0;
 }
 
-#ifdef HAVE_OPENSSL
-
-static const struct signature_alg ecdsa_with_sha256_alg = {
-    "ecdsa-with-sha256",
-    ASN1_OID_ID_ECDSA_WITH_SHA256,
-    &_hx509_signature_ecdsa_with_sha256_data,
-    ASN1_OID_ID_ECPUBLICKEY,
-    &_hx509_signature_sha256_data,
-    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
-    0,
-    NULL,
-    ecdsa_verify_signature,
-    ecdsa_create_signature,
-    32
-};
-
-static const struct signature_alg ecdsa_with_sha1_alg = {
-    "ecdsa-with-sha1",
-    ASN1_OID_ID_ECDSA_WITH_SHA1,
-    &_hx509_signature_ecdsa_with_sha1_data,
-    ASN1_OID_ID_ECPUBLICKEY,
-    &_hx509_signature_sha1_data,
-    PROVIDE_CONF|REQUIRE_SIGNER|RA_RSA_USES_DIGEST_INFO|SIG_PUBLIC_SIG|SELF_SIGNED_OK,
-    0,
-    NULL,
-    ecdsa_verify_signature,
-    ecdsa_create_signature,
-    20
-};
-
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+extern const struct signature_alg ecdsa_with_sha256_alg;
+extern const struct signature_alg ecdsa_with_sha1_alg;
 #endif
 
 static const struct signature_alg heim_rsa_pkcs1_x509 = {
@@ -1455,7 +962,7 @@ static const struct signature_alg md5_alg = {
  */
 
 static const struct signature_alg *sig_algs[] = {
-#ifdef HAVE_OPENSSL
+#ifdef HAVE_HCRYPTO_W_OPENSSL
     &ecdsa_with_sha256_alg,
     &ecdsa_with_sha1_alg,
 #endif
@@ -1476,8 +983,8 @@ static const struct signature_alg *sig_algs[] = {
     NULL
 };
 
-static const struct signature_alg *
-find_sig_alg(const heim_oid *oid)
+const struct signature_alg *
+_hx509_find_sig_alg(const heim_oid *oid)
 {
     unsigned int i;
     for (i = 0; sig_algs[i]; i++)
@@ -1518,10 +1025,13 @@ alg_for_privatekey(const hx509_private_key pk, int type)
 /*
  *
  */
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+extern hx509_private_key_ops ecdsa_private_key_ops;
+#endif
 
 static struct hx509_private_key_ops *private_algs[] = {
     &rsa_private_key_ops,
-#ifdef HAVE_OPENSSL
+#ifdef HAVE_HCRYPTO_W_OPENSSL
     &ecdsa_private_key_ops,
 #endif
     NULL
@@ -1550,7 +1060,7 @@ _hx509_signature_is_weak(hx509_context context, const AlgorithmIdentifier *alg)
 {
     const struct signature_alg *md;
 
-    md = find_sig_alg(&alg->algorithm);
+    md = _hx509_find_sig_alg(&alg->algorithm);
     if (md == NULL) {
        hx509_clear_error_string(context);
        return HX509_SIG_ALG_NO_SUPPORTED;
@@ -1569,7 +1079,7 @@ _hx509_self_signed_valid(hx509_context context,
 {
     const struct signature_alg *md;
 
-    md = find_sig_alg(&alg->algorithm);
+    md = _hx509_find_sig_alg(&alg->algorithm);
     if (md == NULL) {
        hx509_clear_error_string(context);
        return HX509_SIG_ALG_NO_SUPPORTED;
@@ -1597,7 +1107,7 @@ _hx509_verify_signature(hx509_context context,
     if (cert)
        signer = _hx509_get_cert(cert);
 
-    md = find_sig_alg(&alg->algorithm);
+    md = _hx509_find_sig_alg(&alg->algorithm);
     if (md == NULL) {
        hx509_clear_error_string(context);
        return HX509_SIG_ALG_NO_SUPPORTED;
@@ -1632,7 +1142,7 @@ _hx509_create_signature(hx509_context context,
 {
     const struct signature_alg *md;
 
-    md = find_sig_alg(&alg->algorithm);
+    md = _hx509_find_sig_alg(&alg->algorithm);
     if (md == NULL) {
        hx509_set_error_string(context, 0, HX509_SIG_ALG_NO_SUPPORTED,
            "algorithm no supported");
@@ -1926,18 +1436,6 @@ const AlgorithmIdentifier *
 hx509_signature_md5(void)
 { return &_hx509_signature_md5_data; }
 
-const AlgorithmIdentifier *
-hx509_signature_ecPublicKey(void)
-{ return &_hx509_signature_ecPublicKey; }
-
-const AlgorithmIdentifier *
-hx509_signature_ecdsa_with_sha256(void)
-{ return &_hx509_signature_ecdsa_with_sha256_data; }
-
-const AlgorithmIdentifier *
-hx509_signature_ecdsa_with_sha1(void)
-{ return &_hx509_signature_ecdsa_with_sha1_data; }
-
 const AlgorithmIdentifier *
 hx509_signature_rsa_with_sha512(void)
 { return &_hx509_signature_rsa_with_sha512_data; }
@@ -2038,11 +1536,10 @@ hx509_private_key_free(hx509_private_key *key)
     if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_PKCS1_RSAENCRYPTION) == 0) {
        if ((*key)->private_key.rsa)
            RSA_free((*key)->private_key.rsa);
-#ifdef HAVE_OPENSSL
-    } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid, ASN1_OID_ID_ECPUBLICKEY) == 0) {
-       if ((*key)->private_key.ecdsa)
-           EC_KEY_free((*key)->private_key.ecdsa);
-#endif
+    } else if ((*key)->ops && der_heim_oid_cmp((*key)->ops->key_oid,
+                                               ASN1_OID_ID_ECPUBLICKEY) == 0 &&
+               (*key)->private_key.ecdsa != NULL) {
+      _hx509_private_eckey_free((*key)->private_key.ecdsa);
     }
     (*key)->private_key.rsa = NULL;
     free(*key);
@@ -2810,29 +2307,49 @@ find_string2key(const heim_oid *oid,
 {
     if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC2_CBC) == 0) {
        *c = EVP_rc2_40_cbc();
+        if (*c == NULL)
+            return NULL;
        *md = EVP_sha1();
+        if (*md == NULL)
+            return NULL;
        *s2k = PBE_string2key;
        return &asn1_oid_private_rc2_40;
     } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC2_CBC) == 0) {
        *c = EVP_rc2_cbc();
+        if (*c == NULL)
+            return NULL;
        *md = EVP_sha1();
+        if (*md == NULL)
+            return NULL;
        *s2k = PBE_string2key;
        return ASN1_OID_ID_PKCS3_RC2_CBC;
 #if 0
     } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND40BITRC4) == 0) {
        *c = EVP_rc4_40();
+        if (*c == NULL)
+            return NULL;
        *md = EVP_sha1();
+        if (*md == NULL)
+            return NULL;
        *s2k = PBE_string2key;
        return NULL;
     } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND128BITRC4) == 0) {
        *c = EVP_rc4();
+        if (*c == NULL)
+            return NULL;
        *md = EVP_sha1();
+        if (*md == NULL)
+            return NULL;
        *s2k = PBE_string2key;
        return ASN1_OID_ID_PKCS3_RC4;
 #endif
     } else if (der_heim_oid_cmp(oid, ASN1_OID_ID_PBEWITHSHAAND3_KEYTRIPLEDES_CBC) == 0) {
        *c = EVP_des_ede3_cbc();
+        if (*c == NULL)
+            return NULL;
        *md = EVP_sha1();
+        if (*md == NULL)
+            return NULL;
        *s2k = PBE_string2key;
        return ASN1_OID_ID_PKCS3_DES_EDE3_CBC;
     }
@@ -3031,7 +2548,7 @@ find_keytype(const hx509_private_key key)
     if (key == NULL)
        return NULL;
 
-    md = find_sig_alg(key->signature_alg);
+    md = _hx509_find_sig_alg(key->signature_alg);
     if (md == NULL)
        return NULL;
     return md->key_oid;
index 101e968aa83768579d50d5c896e5ea4c20189fee..44d241f350aee2984338d6bea9a76b1635c5118e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 - 2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 2004 - 2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
 
 #include <der.h>
 
+/*
+ * We use OpenSSL for EC, but to do this we need to disable cross-references
+ * between OpenSSL and hcrypto bn.h and such.  Source files that use OpenSSL EC
+ * must define HEIM_NO_CRYPTO_HDRS before including this file.
+ */
+
 #define HC_DEPRECATED_CRYPTO
+#ifndef HEIM_NO_CRYPTO_HDRS
 #include "crypto-headers.h"
+#endif
 
 struct hx509_keyset_ops;
 struct hx509_collector;
@@ -213,6 +221,95 @@ extern const AlgorithmIdentifier * _hx509_crypto_default_sig_alg;
 extern const AlgorithmIdentifier * _hx509_crypto_default_digest_alg;
 extern const AlgorithmIdentifier * _hx509_crypto_default_secret_alg;
 
+/*
+ * Private bits from crypto.c, so crypto-ec.c can also see them.
+ *
+ * This is part of the use-OpenSSL-for-EC hack.
+ */
+
+struct hx509_crypto;
+
+struct signature_alg;
+
+struct hx509_generate_private_context {
+    const heim_oid *key_oid;
+    int isCA;
+    unsigned long num_bits;
+};
+
+struct hx509_private_key_ops {
+    const char *pemtype;
+    const heim_oid *key_oid;
+    int (*available)(const hx509_private_key,
+                    const AlgorithmIdentifier *);
+    int (*get_spki)(hx509_context,
+                   const hx509_private_key,
+                   SubjectPublicKeyInfo *);
+    int (*export)(hx509_context context,
+                 const hx509_private_key,
+                 hx509_key_format_t,
+                 heim_octet_string *);
+    int (*import)(hx509_context, const AlgorithmIdentifier *,
+                 const void *, size_t, hx509_key_format_t,
+                 hx509_private_key);
+    int (*generate_private_key)(hx509_context,
+                               struct hx509_generate_private_context *,
+                               hx509_private_key);
+    BIGNUM *(*get_internal)(hx509_context, hx509_private_key, const char *);
+};
+
+struct hx509_private_key {
+    unsigned int ref;
+    const struct signature_alg *md;
+    const heim_oid *signature_alg;
+    union {
+       RSA *rsa;
+       void *keydata;
+        void *ecdsa; /* EC_KEY */
+    } private_key;
+    hx509_private_key_ops *ops;
+};
+
+/*
+ *
+ */
+
+struct signature_alg {
+    const char *name;
+    const heim_oid *sig_oid;
+    const AlgorithmIdentifier *sig_alg;
+    const heim_oid *key_oid;
+    const AlgorithmIdentifier *digest_alg;
+    int flags;
+#define PROVIDE_CONF   0x1
+#define REQUIRE_SIGNER 0x2
+#define SELF_SIGNED_OK 0x4
+#define WEAK_SIG_ALG   0x8
+
+#define SIG_DIGEST     0x100
+#define SIG_PUBLIC_SIG 0x200
+#define SIG_SECRET     0x400
+
+#define RA_RSA_USES_DIGEST_INFO 0x1000000
+
+    time_t best_before; /* refuse signature made after best before date */
+    const EVP_MD *(*evp_md)(void);
+    int (*verify_signature)(hx509_context context,
+                           const struct signature_alg *,
+                           const Certificate *,
+                           const AlgorithmIdentifier *,
+                           const heim_octet_string *,
+                           const heim_octet_string *);
+    int (*create_signature)(hx509_context,
+                           const struct signature_alg *,
+                           const hx509_private_key,
+                           const AlgorithmIdentifier *,
+                           const heim_octet_string *,
+                           AlgorithmIdentifier *,
+                           heim_octet_string *);
+    int digest_size;
+};
+
 /*
  * Configurable options
  */
index 54cc0630020ade726753a00a9539ff983a9a6e93..0a7048bdf4282f308db4ff7f3ed66f5c62e26952 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 2004 - 2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -1433,7 +1433,7 @@ info(void *opt, int argc, char **argv)
        if (m != NULL)
            printf("dh: %s\n", m->name);
     }
-#ifdef HAVE_OPENSSL
+#ifdef HAVE_HCRYPTO_W_OPENSSL
     {
        printf("ecdsa: ECDSA_METHOD-not-export\n");
     }
index 3eaf695157b24b49001d1823fde080c170332681..a487da393bde75b890e87c410711f2f1e301ad3a 100644 (file)
@@ -319,7 +319,9 @@ struct pem_formats {
     { "CERTIFICATE", parse_certificate, NULL },
     { "PRIVATE KEY", parse_pkcs8_private_key, NULL },
     { "RSA PRIVATE KEY", parse_pem_private_key, hx509_signature_rsa },
+#ifdef HAVE_HCRYPTO_W_OPENSSL
     { "EC PRIVATE KEY", parse_pem_private_key, hx509_signature_ecPublicKey }
+#endif
 };
 
 
index 8c1983ef7491f1894b9e5c517b54c6ead67caacb..dd23aef7665a23c1c1d77009fc5debaaedb31303 100644 (file)
@@ -6,7 +6,7 @@ AM_CPPFLAGS += $(AFS_EXTRA_DEFS) $(ROKEN_RENAME)
 
 if KRB5
 DEPLIB_krb5 = ../krb5/libkrb5.la $(LIB_hcrypto)
-krb5_am_workaround = $(INCLUDE_hcrypto) -I$(top_srcdir)/lib/krb5
+krb5_am_workaround = -I$(top_srcdir)/lib/krb5
 else
 DEPLIB_krb5  =
 krb5_am_workaround = 
index a2058e44f9cb211fa59deef89988e2f759a42d08..57ee89a7426e5e8b7e8a59786ce7cb33871179a1 100644 (file)
@@ -2,7 +2,7 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_hcrypto) -I../com_err -I$(srcdir)/../com_err $(INCLUDE_sqlite3) $(INCLUDE_libintl)
+AM_CPPFLAGS += -I../com_err -I$(srcdir)/../com_err $(INCLUDE_sqlite3) $(INCLUDE_libintl)
 
 bin_PROGRAMS = verify_krb5_conf
 
@@ -71,6 +71,7 @@ libkrb5_la_LIBADD = \
        $(top_builddir)/lib/wind/libwind.la \
        $(top_builddir)/lib/base/libheimbase.la \
        $(LIB_pkinit) \
+       $(LIB_openssl_crypto) \
        $(use_sqlite) \
        $(LIB_com_err) \
        $(LIB_hcrypto) \
@@ -200,6 +201,7 @@ dist_libkrb5_la_SOURCES =                   \
        padata.c                                \
        pcache.c                                \
        pkinit.c                                \
+       pkinit-ec.c                             \
        principal.c                             \
        prog_setup.c                            \
        prompter_posix.c                        \
index 89a0aef933de45567a74ed20afbc1eb3a5a29685..8c5064b11d4b232fb515163d0932846ea642ccba 100644 (file)
@@ -1,6 +1,6 @@
 ########################################################################
 #
-# Copyright (c) 2009 - 2013, Secure Endpoints Inc.
+# Copyright (c) 2009 - 2016, Secure Endpoints Inc.
 # All rights reserved.
 # 
 # Redistribution and use in source and binary forms, with or without
@@ -119,6 +119,7 @@ libkrb5_OBJS =                      \
        $(OBJ)\padata.obj                   \
        $(OBJ)\pcache.obj                   \
        $(OBJ)\pkinit.obj                   \
+       $(OBJ)\pkinit-ec.obj                \
        $(OBJ)\plugin.obj                   \
        $(OBJ)\principal.obj                \
        $(OBJ)\prog_setup.obj               \
@@ -269,6 +270,7 @@ dist_libkrb5_la_SOURCES =                   \
        pac.c                                   \
        padata.c                                \
        pkinit.c                                \
+       pkinit-ec.c                             \
        plugin.c                                \
        principal.c                             \
        prog_setup.c                            \
@@ -340,7 +342,7 @@ $(OBJ)\k524_err.c $(OBJ)\k524_err.h: k524_err.et
 # libkrb5
 
 $(LIBKRB5): $(libkrb5_OBJS)  $(libkrb5_gen_OBJS)
-       $(LIBCON_C) -OUT:$@ $(LIBHEIMBASE) @<<
+       $(LIBCON_C) -OUT:$@ $(LIBHEIMBASE) $(LIB_openssl_crypto) @<<
 $(libkrb5_OBJS: =
 )
 $(libkrb5_gen_OBJS: =
index 1ff197dcf76887189e693d269b7a6aff2d0912b9..da66af04de7055fabc5662006c53572070ff92b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 2003-2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
 #include <err.h>
 #include <assert.h>
 
-#ifdef HAVE_OPENSSL
-#include <openssl/evp.h>
-#endif
-
 static int verbose = 0;
 
 static void
index 201a1d3eef7dcf124386e86b3a394241bd11ad74..368d4f5dbfb159851a9f1dc1b2075c6974d685b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -173,8 +173,15 @@ extern struct _krb5_encryption_type _krb5_enctype_null;
 extern struct _krb5_encryption_type *_krb5_etypes[];
 extern int _krb5_num_etypes;
 
+/* NO_HCRYPTO_POLLUTION is defined in pkinit-ec.c.  See commentary there. */
+#ifndef NO_HCRYPTO_POLLUTION
 /* Interface to the EVP crypto layer provided by hcrypto */
 struct _krb5_evp_schedule {
+    /*
+     * Normally we'd say EVP_CIPHER_CTX here, but!  this header gets
+     * included in lib/krb5/pkinit-ec.ck
+     */
     EVP_CIPHER_CTX ectx;
     EVP_CIPHER_CTX dctx;
 };
+#endif
index 5e0987fef2844c232c778f89b63bf12abcc15e73..cc39b861216dbc4ab1e7f920aa6d423ebfd3b3a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -59,6 +59,9 @@
 #ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h>
 #endif
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -154,11 +157,19 @@ struct sockaddr_dl;
 
 #include <wind.h>
 
+/*
+ * We use OpenSSL for EC, but to do this we need to disable cross-references
+ * between OpenSSL and hcrypto bn.h and such.  Source files that use OpenSSL EC
+ * must define HEIM_NO_CRYPTO_HDRS before including this file.
+ */
 #define HC_DEPRECATED_CRYPTO
+#ifndef HEIM_NO_CRYPTO_HDRS
 #include "crypto-headers.h"
+#endif
 
 
 #include <krb5_asn1.h>
+#include <pkinit_asn1.h>
 
 struct send_to_kdc;
 
@@ -378,6 +389,25 @@ enum krb5_pk_type {
     PKINIT_27 = 2
 };
 
+struct krb5_pk_init_ctx_data {
+    struct krb5_pk_identity *id;
+    enum { USE_RSA, USE_DH, USE_ECDH } keyex;
+    union {
+       DH *dh;
+        void *eckey;
+    } u;
+    krb5_data *clientDHNonce;
+    struct krb5_dh_moduli **m;
+    hx509_peer_info peer;
+    enum krb5_pk_type type;
+    unsigned int require_binding:1;
+    unsigned int require_eku:1;
+    unsigned int require_krbtgt_otherName:1;
+    unsigned int require_hostname_match:1;
+    unsigned int trustedCertifiers:1;
+    unsigned int anonymous:1;
+};
+
 #endif /* PKINIT */
 
 #define ISTILDE(x) (x == '~')
diff --git a/lib/krb5/pkinit-ec.c b/lib/krb5/pkinit-ec.c
new file mode 100644 (file)
index 0000000..33d7dea
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2016 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef PKINIT
+
+/*
+ * As with the other *-ec.c files in Heimdal, this is a bit of a hack.
+ *
+ * The idea is to use OpenSSL for EC because hcrypto doesn't have the
+ * required functionality at this time.  To do this we segregate
+ * EC-using code into separate source files and then we arrange for them
+ * to get the OpenSSL headers and not the conflicting hcrypto ones.
+ *
+ * Because of auto-generated *-private.h headers, we end up needing to
+ * make sure various types are defined before we include them, thus the
+ * strange header include order here.
+ */
+
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+#include <openssl/ec.h>
+#include <openssl/ecdh.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#define HEIM_NO_CRYPTO_HDRS
+#endif
+
+#include <config.h>
+
+/*
+ * NO_HCRYPTO_POLLUTION -> don't refer to hcrypto type/function names
+ * that we don't need in this file and which would clash with OpenSSL's
+ * in ways that are difficult to address in cleaner ways.
+ *
+ * In the medium- to long-term what we should do is move all PK in
+ * Heimdal to the newer EVP interfaces for PK and then nothing outside
+ * lib/hcrypto should ever have to include OpenSSL headers, and -more
+ * specifically- the only thing that should ever have to include OpenSSL
+ * headers is the OpenSSL backend to hcrypto.
+ */
+#define NO_HCRYPTO_POLLUTION
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <hcrypto/des.h>
+#include "krb5_locl.h"
+
+#include <cms_asn1.h>
+#include <pkcs8_asn1.h>
+#include <pkcs9_asn1.h>
+#include <pkcs12_asn1.h>
+#include <pkinit_asn1.h>
+#include <asn1_err.h>
+
+#include <der.h>
+
+krb5_error_code
+_krb5_build_authpack_subjectPK_EC(krb5_context context,
+                                  krb5_pk_init_ctx ctx,
+                                  AuthPack *a)
+{
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    krb5_error_code ret;
+    ECParameters ecp;
+    unsigned char *p;
+    size_t size;
+    int xlen;
+
+    /* copy in public key, XXX find the best curve that the server support or use the clients curve if possible */
+
+    ecp.element = choice_ECParameters_namedCurve;
+    ret = der_copy_oid(&asn1_oid_id_ec_group_secp256r1,
+                       &ecp.u.namedCurve);
+    if (ret)
+        return ret;
+
+    ALLOC(a->clientPublicValue->algorithm.parameters, 1);
+    if (a->clientPublicValue->algorithm.parameters == NULL) {
+        free_ECParameters(&ecp);
+        return krb5_enomem(context);
+    }
+    ASN1_MALLOC_ENCODE(ECParameters, p, xlen, &ecp, &size, ret);
+    free_ECParameters(&ecp);
+    if (ret)
+        return ret;
+    if ((int)size != xlen)
+        krb5_abortx(context, "asn1 internal error");
+
+    a->clientPublicValue->algorithm.parameters->data = p;
+    a->clientPublicValue->algorithm.parameters->length = size;
+
+    /* copy in public key */
+
+    ret = der_copy_oid(&asn1_oid_id_ecPublicKey,
+                       &a->clientPublicValue->algorithm.algorithm);
+    if (ret)
+        return ret;
+
+    ctx->u.eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+    if (ctx->u.eckey == NULL)
+        return krb5_enomem(context);
+
+    ret = EC_KEY_generate_key(ctx->u.eckey);
+    if (ret != 1)
+        return EINVAL;
+
+    xlen = i2o_ECPublicKey(ctx->u.eckey, NULL);
+    if (xlen <= 0)
+        return EINVAL;
+
+    p = malloc(xlen);
+    if (p == NULL)
+        return krb5_enomem(context);
+
+    a->clientPublicValue->subjectPublicKey.data = p;
+
+    xlen = i2o_ECPublicKey(ctx->u.eckey, &p);
+    if (xlen <= 0) {
+        a->clientPublicValue->subjectPublicKey.data = NULL;
+        free(p);
+        return EINVAL;
+    }
+
+    a->clientPublicValue->subjectPublicKey.length = xlen * 8;
+
+    return 0;
+
+    /* XXX verify that this is right with RFC3279 */
+#else
+    krb5_set_error_message(context, ENOTSUP,
+                           N_("PKINIT: ECDH not supported", ""));
+    return ENOTSUP;
+#endif
+}
+
+krb5_error_code
+_krb5_pk_rd_pa_reply_ecdh_compute_key(krb5_context context,
+                                      krb5_pk_init_ctx ctx,
+                                      const unsigned char *in,
+                                      size_t in_sz,
+                                      unsigned char **out,
+                                      int *out_sz)
+{
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    krb5_error_code ret = 0;
+    int dh_gen_keylen;
+
+    const EC_GROUP *group;
+    EC_KEY *public = NULL;
+
+    group = EC_KEY_get0_group(ctx->u.eckey);
+
+    public = EC_KEY_new();
+    if (public == NULL)
+        return krb5_enomem(context);
+    if (EC_KEY_set_group(public, group) != 1) {
+        EC_KEY_free(public);
+        return krb5_enomem(context);
+    }
+
+    if (o2i_ECPublicKey(&public, &in, in_sz) == NULL) {
+        EC_KEY_free(public);
+        ret = KRB5KRB_ERR_GENERIC;
+        krb5_set_error_message(context, ret,
+                               N_("PKINIT: Can't parse ECDH public key", ""));
+        return ret;
+    }
+
+    *out_sz = (EC_GROUP_get_degree(group) + 7) / 8;
+    if (*out_sz < 0)
+        return EOVERFLOW;
+    *out = malloc(*out_sz);
+    if (*out == NULL) {
+        EC_KEY_free(public);
+        return krb5_enomem(context);
+    }
+    dh_gen_keylen = ECDH_compute_key(*out, *out_sz,
+                                     EC_KEY_get0_public_key(public),
+                                     ctx->u.eckey, NULL);
+    EC_KEY_free(public);
+    if (dh_gen_keylen <= 0) {
+        ret = KRB5KRB_ERR_GENERIC;
+        dh_gen_keylen = 0;
+        krb5_set_error_message(context, ret,
+                               N_("PKINIT: Can't compute ECDH public key", ""));
+        free(*out);
+        *out = NULL;
+        *out_sz = 0;
+    }
+    *out_sz = dh_gen_keylen;
+
+    return ret;
+#else
+    krb5_set_error_message(context, ENOTSUP,
+                           N_("PKINIT: ECDH not supported", ""));
+    return ENOTSUP;
+#endif
+}
+
+void
+_krb5_pk_eckey_free(void *eckey)
+{
+#ifdef HAVE_HCRYPTO_W_OPENSSL
+    EC_KEY_free(eckey);
+#endif
+}
+
+#else
+
+static char lib_krb5_pkinit_ec_c = '\0';
+
+#endif
index c0bd40bfd2f26bdc0615cd147da13715e38da217..7cc630d8dd040326bf23579165c6067bf9528c1a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 - 2007 Kungliga Tekniska Högskolan
+ * Copyright (c) 2003 - 2016 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  *
@@ -58,27 +58,6 @@ struct krb5_pk_cert {
     hx509_cert cert;
 };
 
-struct krb5_pk_init_ctx_data {
-    struct krb5_pk_identity *id;
-    enum { USE_RSA, USE_DH, USE_ECDH } keyex;
-    union {
-       DH *dh;
-#ifdef HAVE_OPENSSL
-       EC_KEY *eckey;
-#endif
-    } u;
-    krb5_data *clientDHNonce;
-    struct krb5_dh_moduli **m;
-    hx509_peer_info peer;
-    enum krb5_pk_type type;
-    unsigned int require_binding:1;
-    unsigned int require_eku:1;
-    unsigned int require_krbtgt_otherName:1;
-    unsigned int require_hostname_match:1;
-    unsigned int trustedCertifiers:1;
-    unsigned int anonymous:1;
-};
-
 static void
 pk_copy_error(krb5_context context,
              hx509_context hx509ctx,
@@ -533,74 +512,14 @@ build_auth_pack(krb5_context context,
                return ret;
            if (size != dhbuf.length)
                krb5_abortx(context, "asn1 internal error");
+            a->clientPublicValue->subjectPublicKey.length = dhbuf.length * 8;
+            a->clientPublicValue->subjectPublicKey.data = dhbuf.data;
        } else if (ctx->keyex == USE_ECDH) {
-#ifdef HAVE_OPENSSL
-           ECParameters ecp;
-           unsigned char *p;
-           int xlen;
-
-           /* copy in public key, XXX find the best curve that the server support or use the clients curve if possible */
-
-           ecp.element = choice_ECParameters_namedCurve;
-           ret = der_copy_oid(&asn1_oid_id_ec_group_secp256r1,
-                              &ecp.u.namedCurve);
-           if (ret)
-               return ret;
-
-           ALLOC(a->clientPublicValue->algorithm.parameters, 1);
-           if (a->clientPublicValue->algorithm.parameters == NULL) {
-               free_ECParameters(&ecp);
-               return ENOMEM;
-           }
-           ASN1_MALLOC_ENCODE(ECParameters, p, xlen, &ecp, &size, ret);
-           free_ECParameters(&ecp);
-           if (ret)
-               return ret;
-           if ((int)size != xlen)
-               krb5_abortx(context, "asn1 internal error");
-
-           a->clientPublicValue->algorithm.parameters->data = p;
-           a->clientPublicValue->algorithm.parameters->length = size;
-
-           /* copy in public key */
-
-           ret = der_copy_oid(&asn1_oid_id_ecPublicKey,
-                              &a->clientPublicValue->algorithm.algorithm);
-           if (ret)
-               return ret;
-
-           ctx->u.eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
-           if (ctx->u.eckey == NULL)
-               return ENOMEM;
-
-           ret = EC_KEY_generate_key(ctx->u.eckey);
-           if (ret != 1)
-               return EINVAL;
-
-           /* encode onto dhkey */
-
-           xlen = i2o_ECPublicKey(ctx->u.eckey, NULL);
-           if (xlen <= 0)
-               abort();
-
-           dhbuf.data = malloc(xlen);
-           if (dhbuf.data == NULL)
-               abort();
-           dhbuf.length = xlen;
-           p = dhbuf.data;
-
-           xlen = i2o_ECPublicKey(ctx->u.eckey, &p);
-           if (xlen <= 0)
-               abort();
-
-           /* XXX verify that this is right with RFC3279 */
-#else
-           return EINVAL;
-#endif
+            ret = _krb5_build_authpack_subjectPK_EC(context, ctx, a);
+            if (ret)
+                return ret;
        } else
            krb5_abortx(context, "internal error");
-       a->clientPublicValue->subjectPublicKey.length = dhbuf.length * 8;
-       a->clientPublicValue->subjectPublicKey.data = dhbuf.data;
     }
 
     {
@@ -1443,51 +1362,11 @@ pk_rd_pa_reply_dh(krb5_context context,
        }
 
     } else {
-#ifdef HAVE_OPENSSL
-       const EC_GROUP *group;
-       EC_KEY *public = NULL;
-
-       group = EC_KEY_get0_group(ctx->u.eckey);
-
-       public = EC_KEY_new();
-       if (public == NULL) {
-           ret = ENOMEM;
-           goto out;
-       }
-       if (EC_KEY_set_group(public, group) != 1) {
-           EC_KEY_free(public);
-           ret = ENOMEM;
-           goto out;
-       }
-
-       if (o2i_ECPublicKey(&public, &p, size) == NULL) {
-           EC_KEY_free(public);
-           ret = KRB5KRB_ERR_GENERIC;
-           krb5_set_error_message(context, ret,
-                                  N_("PKINIT: Can't parse ECDH public key", ""));
-           goto out;
-       }
-
-       size = (EC_GROUP_get_degree(group) + 7) / 8;
-       dh_gen_key = malloc(size);
-       if (dh_gen_key == NULL) {
-           EC_KEY_free(public);
-           ret = krb5_enomem(context);
-           goto out;
-       }
-       dh_gen_keylen = ECDH_compute_key(dh_gen_key, size,
-                                        EC_KEY_get0_public_key(public), ctx->u.eckey, NULL);
-       EC_KEY_free(public);
-       if (dh_gen_keylen == -1) {
-           ret = KRB5KRB_ERR_GENERIC;
-           dh_gen_keylen = 0;
-           krb5_set_error_message(context, ret,
-                                  N_("PKINIT: Can't compute ECDH public key", ""));
-           goto out;
-       }
-#else
-       ret = EINVAL;
-#endif
+        ret = _krb5_pk_rd_pa_reply_ecdh_compute_key(context, ctx, p,
+                                                    size, &dh_gen_key,
+                                                    &dh_gen_keylen);
+        if (ret)
+          goto out;
     }
 
     if (dh_gen_keylen <= 0) {
@@ -2309,10 +2188,8 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt)
     case USE_RSA:
        break;
     case USE_ECDH:
-#ifdef HAVE_OPENSSL
        if (ctx->u.eckey)
-           EC_KEY_free(ctx->u.eckey);
-#endif
+            _krb5_pk_eckey_free(ctx->u.eckey);
        break;
     }
     if (ctx->id) {
index e37f53cea5061d79fd963ea13ce5c09b4ff890c6..d33efd2b679abd8a802b1a347f88b581c09a75c7 100644 (file)
@@ -2,8 +2,6 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_hcrypto)
-
 lib_LTLIBRARIES = libheimntlm.la
 
 dist_include_HEADERS = heimntlm.h $(srcdir)/heimntlm-protos.h
index 38681ef0c6e37d023414e04deb3798c683b6947e..371a61ae3f65ff78ab9da67129ef3c2fcaed554f 100644 (file)
@@ -2,7 +2,7 @@
 
 include $(top_srcdir)/Makefile.am.common
 
-AM_CPPFLAGS += $(INCLUDE_hcrypto) $(ROKEN_RENAME)
+AM_CPPFLAGS += $(ROKEN_RENAME)
 if HAVE_DBHEADER
 AM_CPPFLAGS += -I$(DBHEADER)
 endif
index aa3e2768694401ec98cbe6d8e6dcc7ac954eb71c..f2efe9b62f36a21b83198120a0446212e4779a69 100644 (file)
@@ -33,7 +33,6 @@ subst = sed   -e "s!@PACKAGE\@!$(PACKAGE)!g" \
                -e "s!@PTHREAD_LIBADD\@!$(PTHREAD_LIBADD)!g" \
                -e "s!@LIB_crypt\@!$(LIB_crypt)!g" \
                -e "s!@LIB_dbopen\@!$(LIB_dbopen)!g" \
-               -e "s!@INCLUDE_hcrypto\@!$(INCLUDE_hcrypto)!g" \
                -e "s!@LIB_hcrypto_appl\@!$(LIB_hcrypto_appl)!g" \
                -e "s!@LIB_dlopen\@!$(LIB_dlopen)!g" \
                -e "s!@LIB_door_create\@!$(LIB_door_create)!g" \
index 9e72161e6efaaa22c055e48dcd4c1fc4a65bac3e..77652d3bc8f414fc9354ab76b65e324e6dea5171 100644 (file)
@@ -246,7 +246,7 @@ if test "$do_libs" = "yes"; then
     echo ${lib_flags}
 fi
 if test "$do_cflags" = "yes"; then
-    cflags="@INCLUDE_hcrypto@"
+    cflags=""
     if test X"${includedir}" != X/usr/include; then
        cflags="-I${includedir} $cflags"
     fi
index 4da9cb53ae298e5b7763e3146b41537da9e2a602..adde4b649659e72ebb5b95b2f2a14b349f9009ed 100644 (file)
@@ -39,6 +39,10 @@ PKINIT=1
 # Disable AFS support
 NO_AFS=1
 
+# OpenSSL (mostly not needed on Windows, but should work)
+# INCLUDE_openssl_crypto=
+# LIB_openssl_crypto=
+
 # OpenLDAP package is available
 # OPENLDAP=1