summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/openssl
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/openssl')
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.in143
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.c42
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.h4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c46
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c64
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.c461
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.h23
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.c413
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.h11
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.c28
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.h4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c106
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c462
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h36
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c356
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h10
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.c33
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.h10
20 files changed, 1014 insertions, 1246 deletions
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
index e6d7b479b..aa8ecf06c 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.in
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -1,8 +1,9 @@
-# Makefile.in generated by automake 1.10.2 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -16,8 +17,9 @@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
@@ -35,19 +37,41 @@ host_triplet = @host@
subdir = src/libstrongswan/plugins/openssl
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
-am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
-pluginLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(plugin_LTLIBRARIES)
libstrongswan_openssl_la_DEPENDENCIES =
am_libstrongswan_openssl_la_OBJECTS = openssl_plugin.lo \
@@ -63,6 +87,7 @@ libstrongswan_openssl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
+am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -110,25 +135,22 @@ INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
-IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
-LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
-LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
-LINUX_HEADERS = @LINUX_HEADERS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
@@ -140,11 +162,14 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
+RTLIB = @RTLIB@
RUBY = @RUBY@
RUBYINCLUDE = @RUBYINCLUDE@
SED = @SED@
@@ -173,9 +198,9 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
-confdir = @confdir@
datadir = @datadir@
datarootdir = @datarootdir@
+default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
@@ -198,7 +223,7 @@ ipsecuser = @ipsecuser@
libdir = @libdir@
libexecdir = @libexecdir@
libstrongswan_plugins = @libstrongswan_plugins@
-linuxdir = @linuxdir@
+linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
@@ -206,6 +231,7 @@ mandir = @mandir@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
piddir = @piddir@
@@ -214,10 +240,12 @@ pluto_plugins = @pluto_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+random_device = @random_device@
resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
-simreader = @simreader@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
@@ -225,6 +253,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
INCLUDES = -I$(top_srcdir)/src/libstrongswan
@@ -256,9 +285,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/Makefile
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/openssl/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -276,23 +305,28 @@ $(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
- @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
if test -f $$p; then \
- f=$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \
+ list2="$$list2 $$p"; \
else :; fi; \
- done
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
uninstall-pluginLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
- p=$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
done
clean-pluginLTLIBRARIES:
@@ -325,21 +359,21 @@ distclean-compile:
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
@@ -362,7 +396,7 @@ tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
- tags=; \
+ set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
@@ -370,29 +404,34 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
- tags=; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
+ $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -413,13 +452,17 @@ distdir: $(DISTFILES)
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@@ -450,6 +493,7 @@ clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -471,6 +515,8 @@ dvi-am:
html: html-am
+html-am:
+
info: info-am
info-am:
@@ -479,18 +525,28 @@ install-data-am: install-pluginLTLIBRARIES
install-dvi: install-dvi-am
+install-dvi-am:
+
install-exec-am:
install-html: install-html-am
+install-html-am:
+
install-info: install-info-am
+install-info-am:
+
install-man:
install-pdf: install-pdf-am
+install-pdf-am:
+
install-ps: install-ps-am
+install-ps-am:
+
installcheck-am:
maintainer-clean: maintainer-clean-am
@@ -529,6 +585,7 @@ uninstall-am: uninstall-pluginLTLIBRARIES
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-pluginLTLIBRARIES
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c
index 424fec60a..a8923ab56 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crypter.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -23,17 +23,17 @@ typedef struct private_openssl_crypter_t private_openssl_crypter_t;
* Private data of openssl_crypter_t
*/
struct private_openssl_crypter_t {
-
+
/**
* Public part of this class.
*/
openssl_crypter_t public;
-
+
/*
* the key
*/
chunk_t key;
-
+
/*
* the cipher to use
*/
@@ -49,17 +49,17 @@ typedef struct {
* Identifier specified in IKEv2
*/
int ikev2_id;
-
+
/**
* Name of the algorithm, as used in OpenSSL
*/
char *name;
-
+
/**
* Minimum valid key length in bytes
*/
size_t key_size_min;
-
+
/**
* Maximum valid key length in bytes
*/
@@ -91,7 +91,7 @@ static openssl_algorithm_t encryption_algs[] = {
/**
* Look up an OpenSSL algorithm name and validate its key size
*/
-static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
+static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
u_int16_t ikev2_algo, size_t *key_size)
{
while (openssl_algo->ikev2_id != END_OF_LIST)
@@ -104,7 +104,7 @@ static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
{
*key_size = openssl_algo->key_size_min;
}
-
+
/* validate key size */
if (*key_size < openssl_algo->key_size_min ||
*key_size > openssl_algo->key_size_max)
@@ -123,7 +123,7 @@ static void crypt(private_openssl_crypter_t *this, chunk_t data,
{
int len;
u_char *out;
-
+
out = data.ptr;
if (dst)
{
@@ -144,7 +144,7 @@ static void crypt(private_openssl_crypter_t *this, chunk_t data,
/**
* Implementation of crypter_t.decrypt.
*/
-static void decrypt(private_openssl_crypter_t *this, chunk_t data,
+static void decrypt(private_openssl_crypter_t *this, chunk_t data,
chunk_t iv, chunk_t *dst)
{
crypt(this, data, iv, dst, 0);
@@ -154,7 +154,7 @@ static void decrypt(private_openssl_crypter_t *this, chunk_t data,
/**
* Implementation of crypter_t.encrypt.
*/
-static void encrypt (private_openssl_crypter_t *this, chunk_t data,
+static void encrypt (private_openssl_crypter_t *this, chunk_t data,
chunk_t iv, chunk_t *dst)
{
crypt(this, data, iv, dst, 1);
@@ -196,13 +196,13 @@ static void destroy (private_openssl_crypter_t *this)
/*
* Described in header
*/
-openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
+openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
size_t key_size)
{
private_openssl_crypter_t *this;
-
+
this = malloc_thing(private_openssl_crypter_t);
-
+
switch (algo)
{
case ENCR_NULL:
@@ -218,7 +218,7 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
this->cipher = EVP_get_cipherbyname("aes192");
break;
case 32: /* AES-256 */
- this->cipher = EVP_get_cipherbyname("aes256");
+ this->cipher = EVP_get_cipherbyname("aes256");
break;
default:
free(this);
@@ -235,7 +235,7 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
this->cipher = EVP_get_cipherbyname("camellia192");
break;
case 32: /* CAMELLIA 256 */
- this->cipher = EVP_get_cipherbyname("camellia256");
+ this->cipher = EVP_get_cipherbyname("camellia256");
break;
default:
free(this);
@@ -258,22 +258,22 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
break;
}
}
-
+
if (!this->cipher)
{
/* OpenSSL does not support the requested algo */
free(this);
return NULL;
}
-
+
this->key = chunk_alloc(key_size);
-
+
this->public.crypter_interface.encrypt = (void (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
this->public.crypter_interface.decrypt = (void (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
this->public.crypter_interface.set_key = (void (*) (crypter_t *,chunk_t)) set_key;
this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
-
+
return &this->public;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.h b/src/libstrongswan/plugins/openssl/openssl_crypter.h
index e5a899418..7e30ae03c 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crypter.h
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.h
@@ -29,7 +29,7 @@ typedef struct openssl_crypter_t openssl_crypter_t;
* Implementation of crypters using OpenSSL.
*/
struct openssl_crypter_t {
-
+
/**
* The crypter_t interface.
*/
@@ -38,7 +38,7 @@ struct openssl_crypter_t {
/**
* Constructor to create openssl_crypter_t.
- *
+ *
* @param algo algorithm to implement
* @param key_size key size in bytes
* @return openssl_crypter_t, NULL if not supported
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
index fe042efdc..80a1ee878 100644
--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
@@ -22,7 +22,7 @@
typedef struct modulus_entry_t modulus_entry_t;
-/**
+/**
* Entry of the modulus list.
*/
struct modulus_entry_t {
@@ -30,20 +30,20 @@ struct modulus_entry_t {
* Group number as it is defined in file transform_substructure.h.
*/
diffie_hellman_group_t group;
-
+
/**
* Pointer to the function to get the modulus.
*/
BIGNUM *(*get_prime)(BIGNUM *bn);
-
- /*
+
+ /*
* Optimum length of exponent in bits.
- */
+ */
long opt_exponent_len;
-
- /*
+
+ /*
* Generator value.
- */
+ */
u_int16_t generator;
};
@@ -71,27 +71,27 @@ struct private_openssl_diffie_hellman_t {
* Public openssl_diffie_hellman_t interface.
*/
openssl_diffie_hellman_t public;
-
+
/**
* Diffie Hellman group number.
*/
u_int16_t group;
-
+
/**
* Diffie Hellman object
*/
DH *dh;
-
+
/**
* Other public value
*/
BIGNUM *pub_key;
-
+
/**
* Shared secret
*/
chunk_t shared_secret;
-
+
/**
* True if shared secret is computed
*/
@@ -123,7 +123,7 @@ static status_t get_shared_secret(private_openssl_diffie_hellman_t *this,
/* shared secret should requires a len according the DH group */
*secret = chunk_alloc(DH_size(this->dh));
memset(secret->ptr, 0, secret->len);
- memcpy(secret->ptr + secret->len - this->shared_secret.len,
+ memcpy(secret->ptr + secret->len - this->shared_secret.len,
this->shared_secret.ptr, this->shared_secret.len);
return SUCCESS;
@@ -137,7 +137,7 @@ static void set_other_public_value(private_openssl_diffie_hellman_t *this,
chunk_t value)
{
int len;
-
+
BN_bin2bn(value.ptr, value.len, this->pub_key);
chunk_clear(&this->shared_secret);
this->shared_secret.ptr = malloc(DH_size(this->dh));
@@ -167,10 +167,10 @@ static status_t set_modulus(private_openssl_diffie_hellman_t *this)
{
int i;
bool ansi_x9_42;
-
+
ansi_x9_42 = lib->settings->get_bool(lib->settings,
"libstrongswan.dh_exponent_ansi_x9_42", TRUE);
-
+
for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
{
if (modulus_entries[i].group == this->group)
@@ -205,32 +205,32 @@ static void destroy(private_openssl_diffie_hellman_t *this)
openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t group)
{
private_openssl_diffie_hellman_t *this = malloc_thing(private_openssl_diffie_hellman_t);
-
+
this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy;
-
+
this->dh = DH_new();
if (!this->dh)
{
free(this);
return NULL;
}
-
+
this->group = group;
this->computed = FALSE;
this->pub_key = BN_new();
this->shared_secret = chunk_empty;
-
+
/* find a modulus according to group */
if (set_modulus(this) != SUCCESS)
{
destroy(this);
return NULL;
}
-
+
/* generate my public and private values */
if (!DH_generate_key(this->dh))
{
@@ -238,6 +238,6 @@ openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t g
return NULL;
}
DBG2("size of DH secret exponent: %d bits", BN_num_bits(this->dh->priv_key));
-
+
return &this->public;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
index bdc153812..6c4b4fe81 100644
--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
@@ -29,7 +29,7 @@ typedef struct openssl_diffie_hellman_t openssl_diffie_hellman_t;
* Implementation of the Diffie-Hellman algorithm using OpenSSL.
*/
struct openssl_diffie_hellman_t {
-
+
/**
* Implements diffie_hellman_t interface.
*/
@@ -38,7 +38,7 @@ struct openssl_diffie_hellman_t {
/**
* Creates a new openssl_diffie_hellman_t object.
- *
+ *
* @param group Diffie Hellman group number to use
* @return openssl_diffie_hellman_t object, NULL if not supported
*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
index 082aed9ca..671fa41e2 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
@@ -31,27 +31,27 @@ struct private_openssl_ec_diffie_hellman_t {
* Public openssl_ec_diffie_hellman_t interface.
*/
openssl_ec_diffie_hellman_t public;
-
+
/**
* Diffie Hellman group number.
*/
u_int16_t group;
-
+
/**
* EC private (public) key
*/
EC_KEY *key;
-
+
/**
* EC group
*/
const EC_GROUP *ec_group;
-
+
/**
* Other public key
*/
EC_POINT *pub_key;
-
+
/**
* Shared secret
*/
@@ -72,13 +72,13 @@ static bool chunk2ecp(const EC_GROUP *group, chunk_t chunk, EC_POINT *point)
BN_CTX *ctx;
BIGNUM *x, *y;
bool ret = FALSE;
-
+
ctx = BN_CTX_new();
if (!ctx)
{
return FALSE;
}
-
+
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
@@ -86,17 +86,17 @@ static bool chunk2ecp(const EC_GROUP *group, chunk_t chunk, EC_POINT *point)
{
goto error;
}
-
+
if (!openssl_bn_split(chunk, x, y))
{
goto error;
}
-
+
if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
{
goto error;
}
-
+
ret = TRUE;
error:
BN_CTX_end(ctx);
@@ -114,13 +114,13 @@ static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point,
BN_CTX *ctx;
BIGNUM *x, *y;
bool ret = FALSE;
-
+
ctx = BN_CTX_new();
if (!ctx)
{
return FALSE;
}
-
+
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
@@ -128,12 +128,12 @@ static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point,
{
goto error;
}
-
+
if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
{
goto error;
}
-
+
if (x_coordinate_only)
{
y = NULL;
@@ -142,7 +142,7 @@ static bool ecp2chunk(const EC_GROUP *group, const EC_POINT *point,
{
goto error;
}
-
+
ret = TRUE;
error:
BN_CTX_end(ctx);
@@ -152,7 +152,7 @@ error:
/**
* Compute the shared secret.
- *
+ *
* We cannot use the function ECDH_compute_key() because that returns only the
* x coordinate of the shared secret point (which is defined, for instance, in
* 'NIST SP 800-56A').
@@ -166,13 +166,13 @@ static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_
const BIGNUM *priv_key;
EC_POINT *secret = NULL;
bool x_coordinate_only, ret = FALSE;
-
+
priv_key = EC_KEY_get0_private_key(this->key);
if (!priv_key)
{
goto error;
}
-
+
secret = EC_POINT_new(this->ec_group);
if (!secret)
{
@@ -183,7 +183,7 @@ static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_
{
goto error;
}
-
+
/*
* The default setting ecp_x_coordinate_only = TRUE
* applies the following errata for RFC 4753:
@@ -195,7 +195,7 @@ static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_
{
goto error;
}
-
+
ret = TRUE;
error:
if (secret)
@@ -215,14 +215,14 @@ static void set_other_public_value(private_openssl_ec_diffie_hellman_t *this, ch
DBG1("ECDH public value is malformed");
return;
}
-
+
chunk_free(&this->shared_secret);
-
+
if (!compute_shared_key(this, &this->shared_secret)) {
DBG1("ECDH shared secret computation failed");
return;
}
-
+
this->computed = TRUE;
}
@@ -272,13 +272,13 @@ static void destroy(private_openssl_ec_diffie_hellman_t *this)
openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_group_t group)
{
private_openssl_ec_diffie_hellman_t *this = malloc_thing(private_openssl_ec_diffie_hellman_t);
-
+
this->public.dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
this->public.dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
this->public.dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
this->public.dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
this->public.dh.destroy = (void (*)(diffie_hellman_t *)) destroy;
-
+
switch (group)
{
case ECP_192_BIT:
@@ -300,34 +300,34 @@ openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_gro
this->key = NULL;
break;
}
-
+
if (!this->key)
{
free(this);
return NULL;
}
-
+
/* caching the EC group */
this->ec_group = EC_KEY_get0_group(this->key);
-
+
this->pub_key = EC_POINT_new(this->ec_group);
if (!this->pub_key)
{
free(this);
return NULL;
}
-
+
/* generate an EC private (public) key */
if (!EC_KEY_generate_key(this->key))
{
free(this);
return NULL;
}
-
+
this->group = group;
this->computed = FALSE;
-
+
this->shared_secret = chunk_empty;
-
+
return &this->public;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h
index 9d17aed57..fd60732b9 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.h
@@ -29,7 +29,7 @@ typedef struct openssl_ec_diffie_hellman_t openssl_ec_diffie_hellman_t;
* Implementation of the EC Diffie-Hellman algorithm using OpenSSL.
*/
struct openssl_ec_diffie_hellman_t {
-
+
/**
* Implements diffie_hellman_t interface.
*/
@@ -38,7 +38,7 @@ struct openssl_ec_diffie_hellman_t {
/**
* Creates a new openssl_ec_diffie_hellman_t object.
- *
+ *
* @param group EC Diffie Hellman group number to use
* @return openssl_ec_diffie_hellman_t object, NULL if not supported
*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
index d6b442ae9..89ced5a9a 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2009 Martin Willi
* Copyright (C) 2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
@@ -21,6 +22,7 @@
#include <openssl/evp.h>
#include <openssl/ecdsa.h>
+#include <openssl/x509.h>
typedef struct private_openssl_ec_private_key_t private_openssl_ec_private_key_t;
@@ -32,175 +34,138 @@ struct private_openssl_ec_private_key_t {
* Public interface for this signer.
*/
openssl_ec_private_key_t public;
-
+
/**
* EC key object
*/
EC_KEY *ec;
/**
- * Keyid formed as a SHA-1 hash of a privateKey object
- */
- identification_t* keyid;
-
- /**
- * Keyid formed as a SHA-1 hash of a privateKeyInfo object
- */
- identification_t* keyid_info;
-
- /**
* reference count
*/
- refcount_t ref;
+ refcount_t ref;
};
-/**
- * Mapping from the signature scheme defined in (RFC 4754) to the elliptic
- * curve and the hash algorithm
- */
-typedef struct {
- /**
- * Scheme specified in RFC 4754
- */
- int scheme;
-
- /**
- * NID of the hash
- */
- int hash;
-
- /**
- * NID of the curve
- */
- int curve;
-} openssl_ecdsa_scheme_t;
-
-#define END_OF_LIST -1
+/* from ec public key */
+bool openssl_ec_fingerprint(EC_KEY *ec, key_encoding_type_t type, chunk_t *fp);
/**
- * Signature schemes
+ * Build a signature as in RFC 4754
*/
-static openssl_ecdsa_scheme_t ecdsa_schemes[] = {
- {SIGN_ECDSA_256, NID_sha256, NID_X9_62_prime256v1},
- {SIGN_ECDSA_384, NID_sha384, NID_secp384r1},
- {SIGN_ECDSA_521, NID_sha512, NID_secp521r1},
- {END_OF_LIST, 0, 0},
-};
-
-/**
- * Look up the hash and curve of a signature scheme
- */
-static bool lookup_scheme(int scheme, int *hash, int *curve)
+static bool build_signature(private_openssl_ec_private_key_t *this,
+ chunk_t hash, chunk_t *signature)
{
- openssl_ecdsa_scheme_t *ecdsa_scheme = ecdsa_schemes;
- while (ecdsa_scheme->scheme != END_OF_LIST)
+ bool built = FALSE;
+ ECDSA_SIG *sig;
+
+ sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec);
+ if (sig)
{
- if (scheme == ecdsa_scheme->scheme)
- {
- *hash = ecdsa_scheme->hash;
- *curve = ecdsa_scheme->curve;
- return TRUE;
- }
- ecdsa_scheme++;
+ /* concatenate BNs r/s to a signature chunk */
+ built = openssl_bn_cat(EC_FIELD_ELEMENT_LEN(EC_KEY_get0_group(this->ec)),
+ sig->r, sig->s, signature);
+ ECDSA_SIG_free(sig);
}
- return FALSE;
-}
-
-/**
- * shared functions, implemented in openssl_ec_public_key.c
- */
-bool openssl_ec_public_key_build_id(EC_KEY *ec, identification_t **keyid,
- identification_t **keyid_info);
-
-openssl_ec_public_key_t *openssl_ec_public_key_create_from_private_key(EC_KEY *ec);
-
-
-/**
- * Convert an ECDSA_SIG to a chunk by concatenating r and s.
- * This function allocates memory for the chunk.
- */
-static bool sig2chunk(const EC_GROUP *group, ECDSA_SIG *sig, chunk_t *chunk)
-{
- return openssl_bn_cat(EC_FIELD_ELEMENT_LEN(group), sig->r, sig->s, chunk);
+ return built;
}
/**
- * Build the signature
+ * Build a RFC 4754 signature for a specified curve and hash algorithm
*/
-static bool build_signature(private_openssl_ec_private_key_t *this,
- chunk_t hash, chunk_t *signature)
+static bool build_curve_signature(private_openssl_ec_private_key_t *this,
+ signature_scheme_t scheme, int nid_hash,
+ int nid_curve, chunk_t data, chunk_t *signature)
{
- ECDSA_SIG *sig = ECDSA_do_sign(hash.ptr, hash.len, this->ec);
- bool success;
+ const EC_GROUP *my_group;
+ EC_GROUP *req_group;
+ chunk_t hash;
+ bool built;
- if (!sig)
+ req_group = EC_GROUP_new_by_curve_name(nid_curve);
+ if (!req_group)
+ {
+ DBG1("signature scheme %N not supported in EC (required curve "
+ "not supported)", signature_scheme_names, scheme);
+ return FALSE;
+ }
+ my_group = EC_KEY_get0_group(this->ec);
+ if (EC_GROUP_cmp(my_group, req_group, NULL) != 0)
+ {
+ DBG1("signature scheme %N not supported by private key",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+ EC_GROUP_free(req_group);
+ if (!openssl_hash_chunk(nid_hash, data, &hash))
{
return FALSE;
}
- success = sig2chunk(EC_KEY_get0_group(this->ec), sig, signature);
- ECDSA_SIG_free(sig);
- return success;
+ built = build_signature(this, hash, signature);
+ chunk_free(&hash);
+ return built;
}
/**
- * Implementation of private_key_t.get_type.
+ * Build a DER encoded signature as in RFC 3279
*/
-static key_type_t get_type(private_openssl_ec_private_key_t *this)
+static bool build_der_signature(private_openssl_ec_private_key_t *this,
+ int hash_nid, chunk_t data, chunk_t *signature)
{
- return KEY_ECDSA;
+ chunk_t hash, sig;
+ int siglen = 0;
+ bool built;
+
+ if (!openssl_hash_chunk(hash_nid, data, &hash))
+ {
+ return FALSE;
+ }
+ sig = chunk_alloc(ECDSA_size(this->ec));
+ built = ECDSA_sign(0, hash.ptr, hash.len, sig.ptr, &siglen, this->ec) == 1;
+ sig.len = siglen;
+ if (built)
+ {
+ *signature = sig;
+ }
+ else
+ {
+ free(sig.ptr);
+ }
+ free(hash.ptr);
+ return built;
}
/**
* Implementation of private_key_t.sign.
*/
-static bool sign(private_openssl_ec_private_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t *signature)
+static bool sign(private_openssl_ec_private_key_t *this,
+ signature_scheme_t scheme, chunk_t data, chunk_t *signature)
{
- bool success;
-
- if (scheme == SIGN_ECDSA_WITH_NULL)
+ switch (scheme)
{
- success = build_signature(this, data, signature);
- }
- else
- {
- EC_GROUP *req_group;
- const EC_GROUP *my_group;
- chunk_t hash = chunk_empty;
- int hash_type, curve;
-
- if (!lookup_scheme(scheme, &hash_type, &curve))
- {
- DBG1("signature scheme %N not supported in EC",
- signature_scheme_names, scheme);
- return FALSE;
- }
-
- req_group = EC_GROUP_new_by_curve_name(curve);
- if (!req_group)
- {
- DBG1("signature scheme %N not supported in EC (required curve not supported)",
- signature_scheme_names, scheme);
- return FALSE;
- }
-
- my_group = EC_KEY_get0_group(this->ec);
- if (EC_GROUP_cmp(my_group, req_group, NULL) != 0)
- {
- DBG1("signature scheme %N not supported by private key",
- signature_scheme_names, scheme);
- return FALSE;
- }
- EC_GROUP_free(req_group);
-
- if (!openssl_hash_chunk(hash_type, data, &hash))
- {
+ case SIGN_ECDSA_WITH_NULL:
+ return build_signature(this, data, signature);
+ case SIGN_ECDSA_WITH_SHA1_DER:
+ return build_der_signature(this, NID_sha1, data, signature);
+ case SIGN_ECDSA_WITH_SHA256_DER:
+ return build_der_signature(this, NID_sha256, data, signature);
+ case SIGN_ECDSA_WITH_SHA384_DER:
+ return build_der_signature(this, NID_sha384, data, signature);
+ case SIGN_ECDSA_WITH_SHA512_DER:
+ return build_der_signature(this, NID_sha512, data, signature);
+ case SIGN_ECDSA_256:
+ return build_curve_signature(this, scheme, NID_sha256,
+ NID_X9_62_prime256v1, data, signature);
+ case SIGN_ECDSA_384:
+ return build_curve_signature(this, scheme, NID_sha384,
+ NID_secp384r1, data, signature);
+ case SIGN_ECDSA_521:
+ return build_curve_signature(this, scheme, NID_sha512,
+ NID_secp521r1, data, signature);
+ default:
+ DBG1("signature scheme %N not supported",
+ signature_scheme_names, scheme);
return FALSE;
- }
- success = build_signature(this, hash, signature);
- chunk_free(&hash);
- }
- return success;
+ }
}
/**
@@ -222,73 +187,70 @@ static size_t get_keysize(private_openssl_ec_private_key_t *this)
}
/**
- * Implementation of private_key_t.get_id.
+ * Implementation of private_key_t.get_type.
*/
-static identification_t* get_id(private_openssl_ec_private_key_t *this,
- id_type_t type)
+static key_type_t get_type(private_openssl_ec_private_key_t *this)
{
- switch (type)
- {
- case ID_PUBKEY_INFO_SHA1:
- return this->keyid_info;
- case ID_PUBKEY_SHA1:
- return this->keyid;
- default:
- return NULL;
- }
+ return KEY_ECDSA;
}
/**
* Implementation of private_key_t.get_public_key.
*/
-static openssl_ec_public_key_t* get_public_key(private_openssl_ec_private_key_t *this)
+static public_key_t* get_public_key(private_openssl_ec_private_key_t *this)
{
- return openssl_ec_public_key_create_from_private_key(this->ec);
+ public_key_t *public;
+ chunk_t key;
+ u_char *p;
+
+ key = chunk_alloc(i2d_EC_PUBKEY(this->ec, NULL));
+ p = key.ptr;
+ i2d_EC_PUBKEY(this->ec, &p);
+
+ public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
+ BUILD_BLOB_ASN1_DER, key, BUILD_END);
+ free(key.ptr);
+ return public;
}
/**
- * Implementation of private_key_t.belongs_to.
+ * Implementation of private_key_t.get_fingerprint.
*/
-static bool belongs_to(private_openssl_ec_private_key_t *this, public_key_t *public)
+static bool get_fingerprint(private_openssl_ec_private_key_t *this,
+ key_encoding_type_t type, chunk_t *fingerprint)
{
- identification_t *keyid;
-
- if (public->get_type(public) != KEY_ECDSA)
- {
- return FALSE;
- }
- keyid = public->get_id(public, ID_PUBKEY_SHA1);
- if (keyid && keyid->equals(keyid, this->keyid))
- {
- return TRUE;
- }
- keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
- if (keyid && keyid->equals(keyid, this->keyid_info))
- {
- return TRUE;
- }
- return FALSE;
+ return openssl_ec_fingerprint(this->ec, type, fingerprint);
}
/**
* Implementation of private_key_t.get_encoding.
*/
-static chunk_t get_encoding(private_openssl_ec_private_key_t *this)
+static bool get_encoding(private_openssl_ec_private_key_t *this,
+ key_encoding_type_t type, chunk_t *encoding)
{
- chunk_t enc = chunk_alloc(i2d_ECPrivateKey(this->ec, NULL));
- u_char *p = enc.ptr;
- i2d_ECPrivateKey(this->ec, &p);
- return enc;
+ u_char *p;
+
+ switch (type)
+ {
+ case KEY_PRIV_ASN1_DER:
+ {
+ *encoding = chunk_alloc(i2d_ECPrivateKey(this->ec, NULL));
+ p = encoding->ptr;
+ i2d_ECPrivateKey(this->ec, &p);
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
}
/**
* Implementation of private_key_t.get_ref.
*/
-static private_openssl_ec_private_key_t* get_ref(private_openssl_ec_private_key_t *this)
+static private_key_t* get_ref(private_openssl_ec_private_key_t *this)
{
ref_get(&this->ref);
- return this;
-
+ return &this->public.interface;
}
/**
@@ -300,10 +262,9 @@ static void destroy(private_openssl_ec_private_key_t *this)
{
if (this->ec)
{
+ lib->encoding->clear_cache(lib->encoding, this->ec);
EC_KEY_free(this->ec);
}
- DESTROY_IF(this->keyid);
- DESTROY_IF(this->keyid_info);
free(this);
}
}
@@ -311,133 +272,121 @@ static void destroy(private_openssl_ec_private_key_t *this)
/**
* Internal generic constructor
*/
-static private_openssl_ec_private_key_t *openssl_ec_private_key_create_empty(void)
+static private_openssl_ec_private_key_t *create_empty(void)
{
private_openssl_ec_private_key_t *this = malloc_thing(private_openssl_ec_private_key_t);
-
+
this->public.interface.get_type = (key_type_t (*)(private_key_t *this))get_type;
this->public.interface.sign = (bool (*)(private_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t *signature))sign;
this->public.interface.decrypt = (bool (*)(private_key_t *this, chunk_t crypto, chunk_t *plain))decrypt;
this->public.interface.get_keysize = (size_t (*) (private_key_t *this))get_keysize;
- this->public.interface.get_id = (identification_t* (*) (private_key_t *this,id_type_t))get_id;
this->public.interface.get_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
- this->public.interface.belongs_to = (bool (*) (private_key_t *this, public_key_t *public))belongs_to;
- this->public.interface.get_encoding = (chunk_t(*)(private_key_t*))get_encoding;
+ this->public.interface.equals = private_key_equals;
+ this->public.interface.belongs_to = private_key_belongs_to;
+ this->public.interface.get_fingerprint = (bool(*)(private_key_t*, key_encoding_type_t type, chunk_t *fp))get_fingerprint;
+ this->public.interface.has_fingerprint = (bool(*)(private_key_t*, chunk_t fp))private_key_has_fingerprint;
+ this->public.interface.get_encoding = (bool(*)(private_key_t*, key_encoding_type_t type, chunk_t *encoding))get_encoding;
this->public.interface.get_ref = (private_key_t* (*)(private_key_t *this))get_ref;
this->public.interface.destroy = (void (*)(private_key_t *this))destroy;
-
+
this->ec = NULL;
- this->keyid = NULL;
- this->keyid_info = NULL;
this->ref = 1;
-
+
return this;
}
/**
- * load private key from an ASN1 encoded blob
+ * See header.
*/
-static openssl_ec_private_key_t *load(chunk_t blob)
+openssl_ec_private_key_t *openssl_ec_private_key_gen(key_type_t type,
+ va_list args)
{
- u_char *p = blob.ptr;
- private_openssl_ec_private_key_t *this = openssl_ec_private_key_create_empty();
-
- this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&p, blob.len);
-
- chunk_clear(&blob);
+ private_openssl_ec_private_key_t *this;
+ u_int key_size = 0;
- if (!this->ec)
+ while (TRUE)
{
- destroy(this);
- return NULL;
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_KEY_SIZE:
+ key_size = va_arg(args, u_int);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
}
-
- if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info))
+ if (!key_size)
{
- destroy(this);
return NULL;
}
-
- if (!EC_KEY_check_key(this->ec))
+ this = create_empty();
+ switch (key_size)
+ {
+ case 256:
+ this->ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+ break;
+ case 384:
+ this->ec = EC_KEY_new_by_curve_name(NID_secp384r1);
+ break;
+ case 521:
+ this->ec = EC_KEY_new_by_curve_name(NID_secp521r1);
+ break;
+ default:
+ DBG1("EC private key size %d not supported", key_size);
+ destroy(this);
+ return NULL;
+ }
+ if (EC_KEY_generate_key(this->ec) != 1)
{
+ DBG1("EC private key generation failed", key_size);
destroy(this);
return NULL;
}
-
+ /* encode as a named curve key (no parameters), uncompressed public key */
+ EC_KEY_set_asn1_flag(this->ec, OPENSSL_EC_NAMED_CURVE);
+ EC_KEY_set_conv_form(this->ec, POINT_CONVERSION_UNCOMPRESSED);
return &this->public;
}
-typedef struct private_builder_t private_builder_t;
-/**
- * Builder implementation for key loading/generation
- */
-struct private_builder_t {
- /** implements the builder interface */
- builder_t public;
- /** loaded/generated private key */
- openssl_ec_private_key_t *key;
-};
-
/**
- * Implementation of builder_t.build
+ * See header.
*/
-static openssl_ec_private_key_t *build(private_builder_t *this)
+openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type,
+ va_list args)
{
- openssl_ec_private_key_t *key = this->key;
-
- free(this);
- return key;
-}
+ private_openssl_ec_private_key_t *this;
+ chunk_t blob = chunk_empty;
-/**
- * Implementation of builder_t.add
- */
-static void add(private_builder_t *this, builder_part_t part, ...)
-{
- if (!this->key)
+ while (TRUE)
{
- va_list args;
- chunk_t chunk;
-
- switch (part)
+ switch (va_arg(args, builder_part_t))
{
case BUILD_BLOB_ASN1_DER:
- {
- va_start(args, part);
- chunk = va_arg(args, chunk_t);
- this->key = load(chunk_clone(chunk));
- va_end(args);
- return;
- }
- default:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
break;
+ default:
+ return NULL;
}
+ break;
}
- if (this->key)
+
+ this = create_empty();
+ this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len);
+ if (!this->ec)
{
- destroy((private_openssl_ec_private_key_t*)this->key);
+ destroy(this);
+ return NULL;
}
- builder_cancel(&this->public);
-}
-
-/**
- * Builder construction function
- */
-builder_t *openssl_ec_private_key_builder(key_type_t type)
-{
- private_builder_t *this;
-
- if (type != KEY_ECDSA)
+ if (!EC_KEY_check_key(this->ec))
{
+ destroy(this);
return NULL;
}
-
- this = malloc_thing(private_builder_t);
-
- this->key = NULL;
- this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
- this->public.build = (void*(*)(builder_t *this))build;
-
return &this->public;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
index 6a6f7c867..720c63f90 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
@@ -21,6 +21,7 @@
#ifndef OPENSSL_EC_PRIVATE_KEY_H_
#define OPENSSL_EC_PRIVATE_KEY_H_
+#include <credentials/builder.h>
#include <credentials/keys/private_key.h>
typedef struct openssl_ec_private_key_t openssl_ec_private_key_t;
@@ -37,11 +38,27 @@ struct openssl_ec_private_key_t {
};
/**
- * Create the builder for a private key.
+ * Generate a ECDSA private key using OpenSSL.
+ *
+ * Accepts the BUILD_KEY_SIZE argument.
+ *
+ * @param type type of the key, must be KEY_ECDSA
+ * @param args builder_part_t argument list
+ * @return generated key, NULL on failure
+ */
+openssl_ec_private_key_t *openssl_ec_private_key_gen(key_type_t type,
+ va_list args);
+
+/**
+ * Load a ECDSA private key using OpenSSL.
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
*
* @param type type of the key, must be KEY_ECDSA
- * @return builder instance
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
*/
-builder_t *openssl_ec_private_key_builder(key_type_t type);
+openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type,
+ va_list args);
#endif /** OPENSSL_EC_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
index 635a106dd..f37c736b1 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2009 Martin Willi
* Copyright (C) 2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
@@ -32,22 +33,12 @@ struct private_openssl_ec_public_key_t {
* Public interface for this signer.
*/
openssl_ec_public_key_t public;
-
+
/**
* EC key object
*/
EC_KEY *ec;
-
- /**
- * Keyid formed as a SHA-1 hash of a publicKeyInfo object
- */
- identification_t *keyid_info;
-
- /**
- * Keyid formed as a SHA-1 hash of a publicKey object
- */
- identification_t *keyid;
-
+
/**
* reference counter
*/
@@ -55,99 +46,83 @@ struct private_openssl_ec_public_key_t {
};
/**
- * Convert a chunk to an ECDSA_SIG (which must already exist). r and s
- * of the signature have to be concatenated in the chunk.
- */
-static bool chunk2sig(const EC_GROUP *group, chunk_t chunk, ECDSA_SIG *sig)
-{
- return openssl_bn_split(chunk, sig->r, sig->s);
-}
-
-/**
* Verification of a signature as in RFC 4754
*/
static bool verify_signature(private_openssl_ec_public_key_t *this,
- int hash_type, chunk_t data, chunk_t signature)
+ chunk_t hash, chunk_t signature)
{
- chunk_t hash = chunk_empty;
- ECDSA_SIG *sig;
bool valid = FALSE;
-
- if (hash_type == NID_undef)
- {
- hash = data;
- }
- else
+ ECDSA_SIG *sig;
+
+ sig = ECDSA_SIG_new();
+ if (sig)
{
- if (!openssl_hash_chunk(hash_type, data, &hash))
+ /* split the signature chunk in r and s */
+ if (openssl_bn_split(signature, sig->r, sig->s))
{
- return FALSE;
+ valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1);
}
+ ECDSA_SIG_free(sig);
}
-
- sig = ECDSA_SIG_new();
- if (!sig)
- {
- goto error;
- }
-
- if (!chunk2sig(EC_KEY_get0_group(this->ec), signature, sig))
+ return valid;
+}
+
+/**
+ * Verify a RFC 4754 signature for a specified curve and hash algorithm
+ */
+static bool verify_curve_signature(private_openssl_ec_public_key_t *this,
+ signature_scheme_t scheme, int nid_hash,
+ int nid_curve, chunk_t data, chunk_t signature)
+{
+ const EC_GROUP *my_group;
+ EC_GROUP *req_group;
+ chunk_t hash;
+ bool valid;
+
+ req_group = EC_GROUP_new_by_curve_name(nid_curve);
+ if (!req_group)
{
- goto error;
+ DBG1("signature scheme %N not supported in EC (required curve "
+ "not supported)", signature_scheme_names, scheme);
+ return FALSE;
}
- valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1);
-
-error:
- if (sig)
+ my_group = EC_KEY_get0_group(this->ec);
+ if (EC_GROUP_cmp(my_group, req_group, NULL) != 0)
{
- ECDSA_SIG_free(sig);
+ DBG1("signature scheme %N not supported by private key",
+ signature_scheme_names, scheme);
+ return FALSE;
}
- if (hash_type != NID_undef)
+ EC_GROUP_free(req_group);
+ if (!openssl_hash_chunk(nid_hash, data, &hash))
{
- chunk_free(&hash);
+ return FALSE;
}
+ valid = verify_signature(this, hash, signature);
+ chunk_free(&hash);
return valid;
}
-
/**
- * Verification of the default signature using SHA-1
+ * Verification of a DER encoded signature as in RFC 3279
*/
-static bool verify_default_signature(private_openssl_ec_public_key_t *this,
- chunk_t data, chunk_t signature)
+static bool verify_der_signature(private_openssl_ec_public_key_t *this,
+ int nid_hash, chunk_t data, chunk_t signature)
{
+ chunk_t hash;
bool valid = FALSE;
- chunk_t hash = chunk_empty;
- u_char *p;
- ECDSA_SIG *sig;
-
+
/* remove any preceding 0-bytes from signature */
- while (signature.len && *(signature.ptr) == 0x00)
- {
- signature.len -= 1;
- signature.ptr++;
- }
-
- p = signature.ptr;
- sig = d2i_ECDSA_SIG(NULL, (const u_char**)&p, signature.len);
- if (!sig)
- {
- return FALSE;
- }
-
- if (!openssl_hash_chunk(NID_sha1, data, &hash))
+ while (signature.len && signature.ptr[0] == 0x00)
{
- goto error;
+ signature = chunk_skip(signature, 1);
}
-
- valid = (ECDSA_do_verify(hash.ptr, hash.len, sig, this->ec) == 1);
-
-error:
- if (sig)
+ if (openssl_hash_chunk(nid_hash, data, &hash))
{
- ECDSA_SIG_free(sig);
+ valid = ECDSA_verify(0, hash.ptr, hash.len,
+ signature.ptr, signature.len, this->ec);
+ free(hash.ptr);
}
- chunk_free(&hash);
return valid;
}
@@ -162,21 +137,30 @@ static key_type_t get_type(private_openssl_ec_public_key_t *this)
/**
* Implementation of public_key_t.verify.
*/
-static bool verify(private_openssl_ec_public_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t signature)
+static bool verify(private_openssl_ec_public_key_t *this,
+ signature_scheme_t scheme, chunk_t data, chunk_t signature)
{
switch (scheme)
{
+ case SIGN_ECDSA_WITH_SHA1_DER:
+ return verify_der_signature(this, NID_sha1, data, signature);
+ case SIGN_ECDSA_WITH_SHA256_DER:
+ return verify_der_signature(this, NID_sha256, data, signature);
+ case SIGN_ECDSA_WITH_SHA384_DER:
+ return verify_der_signature(this, NID_sha384, data, signature);
+ case SIGN_ECDSA_WITH_SHA512_DER:
+ return verify_der_signature(this, NID_sha512, data, signature);
case SIGN_ECDSA_WITH_NULL:
- return verify_signature(this, NID_undef, data, signature);
- case SIGN_ECDSA_WITH_SHA1:
- return verify_default_signature(this, data, signature);
+ return verify_signature(this, data, signature);
case SIGN_ECDSA_256:
- return verify_signature(this, NID_sha256, data, signature);
+ return verify_curve_signature(this, scheme, NID_sha256,
+ NID_X9_62_prime256v1, data, signature);
case SIGN_ECDSA_384:
- return verify_signature(this, NID_sha384, data, signature);
+ return verify_curve_signature(this, scheme, NID_sha384,
+ NID_secp384r1, data, signature);
case SIGN_ECDSA_521:
- return verify_signature(this, NID_sha512, data, signature);
+ return verify_curve_signature(this, scheme, NID_sha512,
+ NID_secp521r1, data, signature);
default:
DBG1("signature scheme %N not supported in EC",
signature_scheme_names, scheme);
@@ -187,7 +171,8 @@ static bool verify(private_openssl_ec_public_key_t *this, signature_scheme_t sch
/**
* Implementation of public_key_t.get_keysize.
*/
-static bool encrypt_(private_openssl_ec_public_key_t *this, chunk_t crypto, chunk_t *plain)
+static bool encrypt_(private_openssl_ec_public_key_t *this,
+ chunk_t crypto, chunk_t *plain)
{
DBG1("EC public key encryption not implemented");
return FALSE;
@@ -202,64 +187,85 @@ static size_t get_keysize(private_openssl_ec_public_key_t *this)
}
/**
- * Implementation of public_key_t.get_id.
+ * Calculate fingerprint from a EC_KEY, also used in ec private key.
*/
-static identification_t *get_id(private_openssl_ec_public_key_t *this,
- id_type_t type)
+bool openssl_ec_fingerprint(EC_KEY *ec, key_encoding_type_t type, chunk_t *fp)
{
+ hasher_t *hasher;
+ chunk_t key;
+ u_char *p;
+
+ if (lib->encoding->get_cache(lib->encoding, type, ec, fp))
+ {
+ return TRUE;
+ }
switch (type)
{
- case ID_PUBKEY_INFO_SHA1:
- return this->keyid_info;
- case ID_PUBKEY_SHA1:
- return this->keyid;
+ case KEY_ID_PUBKEY_SHA1:
+ key = chunk_alloc(i2o_ECPublicKey(ec, NULL));
+ p = key.ptr;
+ i2o_ECPublicKey(ec, &p);
+ break;
+ case KEY_ID_PUBKEY_INFO_SHA1:
+ key = chunk_alloc(i2d_EC_PUBKEY(ec, NULL));
+ p = key.ptr;
+ i2d_EC_PUBKEY(ec, &p);
+ break;
default:
- return NULL;
+ return FALSE;
+ }
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher)
+ {
+ DBG1("SHA1 hash algorithm not supported, fingerprinting failed");
+ free(key.ptr);
+ return FALSE;
}
+ hasher->allocate_hash(hasher, key, fp);
+ hasher->destroy(hasher);
+ free(key.ptr);
+ lib->encoding->cache(lib->encoding, type, ec, *fp);
+ return TRUE;
}
/**
- * Encodes the public key
- */
-static chunk_t get_encoding_raw(EC_KEY *ec)
+ * Implementation of private_key_t.get_fingerprint.
+ */
+static bool get_fingerprint(private_openssl_ec_public_key_t *this,
+ key_encoding_type_t type, chunk_t *fingerprint)
{
- /* since the points can be stored in three different forms this may not
- * be correct for all cases */
- const EC_GROUP *group = EC_KEY_get0_group(ec);
- const EC_POINT *pub = EC_KEY_get0_public_key(ec);
- chunk_t enc = chunk_alloc(EC_POINT_point2oct(group, pub,
- POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL));
- EC_POINT_point2oct(group, pub, POINT_CONVERSION_UNCOMPRESSED,
- enc.ptr, enc.len, NULL);
- return enc;
+ return openssl_ec_fingerprint(this->ec, type, fingerprint);
}
/**
- * Encodes the public key info (public key with ec parameters)
- */
-static chunk_t get_encoding_full(EC_KEY *ec)
-{
- chunk_t enc = chunk_alloc(i2d_EC_PUBKEY(ec, NULL));
- u_char *p = enc.ptr;
- i2d_EC_PUBKEY(ec, &p);
- return enc;
-}
-
-/*
- * Implementation of public_key_t.get_encoding.
+ * Implementation of private_key_t.get_encoding.
*/
-static chunk_t get_encoding(private_openssl_ec_public_key_t *this)
+static bool get_encoding(private_openssl_ec_public_key_t *this,
+ key_encoding_type_t type, chunk_t *encoding)
{
- return get_encoding_full(this->ec);
+ u_char *p;
+
+ switch (type)
+ {
+ case KEY_PUB_SPKI_ASN1_DER:
+ {
+ *encoding = chunk_alloc(i2d_EC_PUBKEY(this->ec, NULL));
+ p = encoding->ptr;
+ i2d_EC_PUBKEY(this->ec, &p);
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
}
/**
* Implementation of public_key_t.get_ref.
*/
-static private_openssl_ec_public_key_t* get_ref(private_openssl_ec_public_key_t *this)
+static public_key_t* get_ref(private_openssl_ec_public_key_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public.interface;
}
/**
@@ -271,10 +277,9 @@ static void destroy(private_openssl_ec_public_key_t *this)
{
if (this->ec)
{
+ lib->encoding->clear_cache(lib->encoding, this->ec);
EC_KEY_free(this->ec);
}
- DESTROY_IF(this->keyid);
- DESTROY_IF(this->keyid_info);
free(this);
}
}
@@ -282,168 +287,62 @@ static void destroy(private_openssl_ec_public_key_t *this)
/**
* Generic private constructor
*/
-static private_openssl_ec_public_key_t *openssl_ec_public_key_create_empty()
+static private_openssl_ec_public_key_t *create_empty()
{
private_openssl_ec_public_key_t *this = malloc_thing(private_openssl_ec_public_key_t);
-
+
this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
- this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
- this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
+ this->public.interface.equals = public_key_equals;
+ this->public.interface.get_fingerprint = (bool(*)(public_key_t*, key_encoding_type_t type, chunk_t *fp))get_fingerprint;
+ this->public.interface.has_fingerprint = (bool(*)(public_key_t*, chunk_t fp))public_key_has_fingerprint;
+ this->public.interface.get_encoding = (bool(*)(public_key_t*, key_encoding_type_t type, chunk_t *encoding))get_encoding;
this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
-
+
this->ec = NULL;
- this->keyid = NULL;
- this->keyid_info = NULL;
this->ref = 1;
-
+
return this;
}
/**
- * Build key identifier from the public key using SHA1 hashed publicKey(Info).
- * Also used in openssl_ec_private_key.c.
+ * See header.
*/
-bool openssl_ec_public_key_build_id(EC_KEY *ec, identification_t **keyid,
- identification_t **keyid_info)
+openssl_ec_public_key_t *openssl_ec_public_key_load(key_type_t type,
+ va_list args)
{
- chunk_t publicKeyInfo, publicKey, hash;
- hasher_t *hasher;
-
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (hasher == NULL)
- {
- DBG1("SHA1 hash algorithm not supported, unable to use EC");
- return FALSE;
- }
-
- publicKey = get_encoding_raw(ec);
-
- hasher->allocate_hash(hasher, publicKey, &hash);
- *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
- chunk_free(&hash);
-
- publicKeyInfo = get_encoding_full(ec);
-
- hasher->allocate_hash(hasher, publicKeyInfo, &hash);
- *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
- chunk_free(&hash);
-
- hasher->destroy(hasher);
- chunk_free(&publicKeyInfo);
- chunk_free(&publicKey);
-
- return TRUE;
-}
+ private_openssl_ec_public_key_t *this;
+ chunk_t blob = chunk_empty;
-/**
- * Load a public key from an ASN1 encoded blob
- */
-static openssl_ec_public_key_t *load(chunk_t blob)
-{
- u_char *p = blob.ptr;
- private_openssl_ec_public_key_t *this = openssl_ec_public_key_create_empty();
-
- this->ec = d2i_EC_PUBKEY(NULL, (const u_char**)&p, blob.len);
-
- chunk_clear(&blob);
-
- if (!this->ec)
+ if (type != KEY_ECDSA)
{
- destroy(this);
return NULL;
}
-
- if (!openssl_ec_public_key_build_id(this->ec, &this->keyid, &this->keyid_info))
- {
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-
-/**
- * Create a public key from BIGNUM values, used in openssl_ec_private_key.c
- */
-openssl_ec_public_key_t *openssl_ec_public_key_create_from_private_key(EC_KEY *ec)
-{
- return (openssl_ec_public_key_t*)load(get_encoding_full(ec));
-}
-
-typedef struct private_builder_t private_builder_t;
-/**
- * Builder implementation for key loading
- */
-struct private_builder_t {
- /** implements the builder interface */
- builder_t public;
- /** loaded public key */
- openssl_ec_public_key_t *key;
-};
-
-/**
- * Implementation of builder_t.build
- */
-static openssl_ec_public_key_t *build(private_builder_t *this)
-{
- openssl_ec_public_key_t *key = this->key;
-
- free(this);
- return key;
-}
-/**
- * Implementation of builder_t.add
- */
-static void add(private_builder_t *this, builder_part_t part, ...)
-{
- if (!this->key)
+ while (TRUE)
{
- va_list args;
- chunk_t chunk;
-
- switch (part)
+ switch (va_arg(args, builder_part_t))
{
case BUILD_BLOB_ASN1_DER:
- {
- va_start(args, part);
- chunk = va_arg(args, chunk_t);
- this->key = load(chunk_clone(chunk));
- va_end(args);
- return;
- }
- default:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
break;
+ default:
+ return NULL;
}
+ break;
}
- if (this->key)
- {
- destroy((private_openssl_ec_public_key_t*)this->key);
- }
- builder_cancel(&this->public);
-}
-
-/**
- * Builder construction function
- */
-builder_t *openssl_ec_public_key_builder(key_type_t type)
-{
- private_builder_t *this;
-
- if (type != KEY_ECDSA)
+ this = create_empty();
+ this->ec = d2i_EC_PUBKEY(NULL, (const u_char**)&blob.ptr, blob.len);
+ if (!this->ec)
{
+ destroy(this);
return NULL;
}
-
- this = malloc_thing(private_builder_t);
-
- this->key = NULL;
- this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
- this->public.build = (void*(*)(builder_t *this))build;
-
return &this->public;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
index bdbb2fe6e..29d607d38 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
@@ -23,6 +23,7 @@
typedef struct openssl_ec_public_key_t openssl_ec_public_key_t;
+#include <credentials/builder.h>
#include <credentials/keys/public_key.h>
/**
@@ -37,11 +38,15 @@ struct openssl_ec_public_key_t {
};
/**
- * Create the builder for a public key.
+ * Load a ECDSA public key using OpenSSL.
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
*
* @param type type of the key, must be KEY_ECDSA
- * @return builder instance
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
*/
-builder_t *openssl_ec_public_key_builder(key_type_t type);
+openssl_ec_public_key_t *openssl_ec_public_key_load(key_type_t type,
+ va_list args);
#endif /** OPENSSL_EC_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.c b/src/libstrongswan/plugins/openssl/openssl_hasher.c
index 90a5229d5..7556bc594 100644
--- a/src/libstrongswan/plugins/openssl/openssl_hasher.c
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -23,19 +23,19 @@ typedef struct private_openssl_hasher_t private_openssl_hasher_t;
* Private data of openssl_hasher_t
*/
struct private_openssl_hasher_t {
-
+
/**
* Public part of this class.
*/
openssl_hasher_t public;
-
+
/**
* the hasher to use
*/
const EVP_MD *hasher;
-
+
/**
- * the current digest context
+ * the current digest context
*/
EVP_MD_CTX *ctx;
};
@@ -49,7 +49,7 @@ typedef struct {
* Identifier specified in IKEv2
*/
int ikev2_id;
-
+
/**
* Name of the algorithm, as used in OpenSSL
*/
@@ -76,7 +76,7 @@ static openssl_algorithm_t integrity_algs[] = {
/**
* Look up an OpenSSL algorithm name
*/
-static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
+static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
u_int16_t ikev2_algo)
{
while (openssl_algo->ikev2_id != END_OF_LIST)
@@ -133,7 +133,7 @@ static void allocate_hash(private_openssl_hasher_t *this, chunk_t chunk,
}
else
{
- get_hash(this, chunk, NULL);
+ get_hash(this, chunk, NULL);
}
}
@@ -152,7 +152,7 @@ static void destroy (private_openssl_hasher_t *this)
openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
{
private_openssl_hasher_t *this;
-
+
char* name = lookup_algorithm(integrity_algs, algo);
if (!name)
{
@@ -161,7 +161,7 @@ openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
}
this = malloc_thing(private_openssl_hasher_t);
-
+
this->hasher = EVP_get_digestbyname(name);
if (!this->hasher)
{
@@ -169,17 +169,17 @@ openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
free(this);
return NULL;
}
-
+
this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
-
+
this->ctx = EVP_MD_CTX_create();
-
+
/* initialization */
reset(this);
-
+
return &this->public;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.h b/src/libstrongswan/plugins/openssl/openssl_hasher.h
index aec5bc7dd..fd7a043d1 100644
--- a/src/libstrongswan/plugins/openssl/openssl_hasher.h
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.h
@@ -29,7 +29,7 @@ typedef struct openssl_hasher_t openssl_hasher_t;
* Implementation of hashers using OpenSSL.
*/
struct openssl_hasher_t {
-
+
/**
* The hasher_t interface.
*/
@@ -38,7 +38,7 @@ struct openssl_hasher_t {
/**
* Constructor to create openssl_hasher_t.
- *
+ *
* @param algo algorithm
* @return openssl_hasher_t, NULL if not supported
*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index ce6716f5a..548a76bb4 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -18,12 +18,13 @@
#include <openssl/evp.h>
#include <openssl/engine.h>
#include <openssl/crypto.h>
-#include <pthread.h>
#include "openssl_plugin.h"
#include <library.h>
-#include <utils/mutex.h>
+#include <threading/thread.h>
+#include <threading/mutex.h>
+#include "openssl_util.h"
#include "openssl_crypter.h"
#include "openssl_hasher.h"
#include "openssl_diffie_hellman.h"
@@ -82,7 +83,7 @@ struct CRYPTO_dynlock_value {
static struct CRYPTO_dynlock_value *create_function(const char *file, int line)
{
struct CRYPTO_dynlock_value *lock;
-
+
lock = malloc_thing(struct CRYPTO_dynlock_value);
lock->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
return lock;
@@ -119,7 +120,7 @@ static void destroy_function(struct CRYPTO_dynlock_value *lock,
*/
static unsigned long id_function(void)
{
- return (unsigned long)pthread_self();
+ return (unsigned long)thread_current_id();
}
/**
@@ -130,12 +131,12 @@ static void threading_init()
int i, num_locks;
CRYPTO_set_id_callback(id_function);
- CRYPTO_set_locking_callback(locking_function);
-
+ CRYPTO_set_locking_callback(locking_function);
+
CRYPTO_set_dynlock_create_callback(create_function);
CRYPTO_set_dynlock_lock_callback(lock_function);
CRYPTO_set_dynlock_destroy_callback(destroy_function);
-
+
num_locks = CRYPTO_num_locks();
mutex = malloc(sizeof(mutex_t*) * num_locks);
for (i = 0; i < num_locks; i++)
@@ -150,7 +151,7 @@ static void threading_init()
static void threading_cleanup()
{
int i, num_locks;
-
+
num_locks = CRYPTO_num_locks();
for (i = 0; i < num_locks; i++)
{
@@ -169,25 +170,31 @@ static void destroy(private_openssl_plugin_t *this)
(crypter_constructor_t)openssl_crypter_create);
lib->crypto->remove_hasher(lib->crypto,
(hasher_constructor_t)openssl_hasher_create);
- lib->crypto->remove_dh(lib->crypto,
+ lib->crypto->remove_dh(lib->crypto,
(dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->remove_dh(lib->crypto,
+ lib->crypto->remove_dh(lib->crypto,
(dh_constructor_t)openssl_ec_diffie_hellman_create);
lib->creds->remove_builder(lib->creds,
- (builder_constructor_t)openssl_rsa_private_key_builder);
+ (builder_function_t)openssl_rsa_private_key_load);
+ lib->creds->remove_builder(lib->creds,
+ (builder_function_t)openssl_rsa_private_key_gen);
lib->creds->remove_builder(lib->creds,
- (builder_constructor_t)openssl_rsa_public_key_builder);
+ (builder_function_t)openssl_rsa_private_key_connect);
lib->creds->remove_builder(lib->creds,
- (builder_constructor_t)openssl_ec_private_key_builder);
+ (builder_function_t)openssl_rsa_public_key_load);
lib->creds->remove_builder(lib->creds,
- (builder_constructor_t)openssl_ec_public_key_builder);
-
+ (builder_function_t)openssl_ec_private_key_load);
+ lib->creds->remove_builder(lib->creds,
+ (builder_function_t)openssl_ec_private_key_gen);
+ lib->creds->remove_builder(lib->creds,
+ (builder_function_t)openssl_ec_public_key_load);
+
ENGINE_cleanup();
EVP_cleanup();
CONF_modules_free();
-
+
threading_cleanup();
-
+
free(this);
}
@@ -197,18 +204,18 @@ static void destroy(private_openssl_plugin_t *this)
plugin_t *plugin_create()
{
private_openssl_plugin_t *this = malloc_thing(private_openssl_plugin_t);
-
+
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
-
+
threading_init();
-
+
OPENSSL_config(NULL);
OpenSSL_add_all_algorithms();
-
+
/* activate support for hardware accelerators */
ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
-
+
/* crypter */
lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
(crypter_constructor_t)openssl_crypter_create);
@@ -230,7 +237,7 @@ plugin_t *plugin_create()
(crypter_constructor_t)openssl_crypter_create);
lib->crypto->add_crypter(lib->crypto, ENCR_NULL,
(crypter_constructor_t)openssl_crypter_create);
-
+
/* hasher */
lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
(hasher_constructor_t)openssl_hasher_create);
@@ -248,48 +255,53 @@ plugin_t *plugin_create()
(hasher_constructor_t)openssl_hasher_create);
lib->crypto->add_hasher(lib->crypto, HASH_SHA512,
(hasher_constructor_t)openssl_hasher_create);
-
- /* ec diffie hellman */
- lib->crypto->add_dh(lib->crypto, ECP_192_BIT,
- (dh_constructor_t)openssl_ec_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, ECP_224_BIT,
- (dh_constructor_t)openssl_ec_diffie_hellman_create);
+
+ /* (ec) diffie hellman */
+ lib->crypto->add_dh(lib->crypto, MODP_2048_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_1536_BIT,
+ (dh_constructor_t)openssl_diffie_hellman_create);
lib->crypto->add_dh(lib->crypto, ECP_256_BIT,
(dh_constructor_t)openssl_ec_diffie_hellman_create);
lib->crypto->add_dh(lib->crypto, ECP_384_BIT,
(dh_constructor_t)openssl_ec_diffie_hellman_create);
lib->crypto->add_dh(lib->crypto, ECP_521_BIT,
(dh_constructor_t)openssl_ec_diffie_hellman_create);
-
- /* diffie hellman */
- lib->crypto->add_dh(lib->crypto, MODP_2048_BIT,
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_1536_BIT,
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_3072_BIT,
+ lib->crypto->add_dh(lib->crypto, ECP_224_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, ECP_192_BIT,
+ (dh_constructor_t)openssl_ec_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_3072_BIT,
(dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_4096_BIT,
+ lib->crypto->add_dh(lib->crypto, MODP_4096_BIT,
(dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_6144_BIT,
+ lib->crypto->add_dh(lib->crypto, MODP_6144_BIT,
(dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_8192_BIT,
+ lib->crypto->add_dh(lib->crypto, MODP_8192_BIT,
(dh_constructor_t)openssl_diffie_hellman_create);
lib->crypto->add_dh(lib->crypto, MODP_1024_BIT,
(dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_768_BIT,
+ lib->crypto->add_dh(lib->crypto, MODP_768_BIT,
(dh_constructor_t)openssl_diffie_hellman_create);
-
+
/* rsa */
lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
- (builder_constructor_t)openssl_rsa_private_key_builder);
+ (builder_function_t)openssl_rsa_private_key_load);
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ (builder_function_t)openssl_rsa_private_key_gen);
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ (builder_function_t)openssl_rsa_private_key_connect);
lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
- (builder_constructor_t)openssl_rsa_public_key_builder);
-
+ (builder_function_t)openssl_rsa_public_key_load);
+
/* ec */
lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
- (builder_constructor_t)openssl_ec_private_key_builder);
+ (builder_function_t)openssl_ec_private_key_load);
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
+ (builder_function_t)openssl_ec_private_key_gen);
lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
- (builder_constructor_t)openssl_ec_public_key_builder);
-
+ (builder_function_t)openssl_ec_public_key_load);
+
return &this->public.plugin;
}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
index 95c0ffdc8..078f889a6 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2009 Martin Willi
* Copyright (C) 2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
@@ -37,42 +38,25 @@ struct private_openssl_rsa_private_key_t {
* Public interface for this signer.
*/
openssl_rsa_private_key_t public;
-
+
/**
* RSA object from OpenSSL
*/
RSA *rsa;
-
+
/**
* TRUE if the key is from an OpenSSL ENGINE and might not be readable
*/
bool engine;
/**
- * Keyid formed as a SHA-1 hash of a privateKey object
- */
- identification_t* keyid;
-
- /**
- * Keyid formed as a SHA-1 hash of a privateKeyInfo object
- */
- identification_t* keyid_info;
-
- /**
* reference count
*/
- refcount_t ref;
+ refcount_t ref;
};
-/**
- * shared functions, implemented in openssl_rsa_public_key.c
- */
-bool openssl_rsa_public_key_build_id(RSA *rsa, identification_t **keyid,
- identification_t **keyid_info);
-
-
-openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGNUM *e);
-
+/* implemented in rsa public key */
+bool openssl_rsa_fingerprint(RSA *rsa, key_encoding_type_t type, chunk_t *fp);
/**
* Build an EMPSA PKCS1 signature described in PKCS#1
@@ -104,7 +88,7 @@ static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this,
{
return FALSE;
}
-
+
ctx = EVP_MD_CTX_create();
key = EVP_PKEY_new();
if (!ctx || !key)
@@ -127,7 +111,7 @@ static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this,
{
success = TRUE;
}
-
+
error:
if (key)
{
@@ -156,7 +140,7 @@ static key_type_t get_type(private_openssl_rsa_private_key_t *this)
/**
* Implementation of openssl_rsa_private_key.sign.
*/
-static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t scheme,
+static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t scheme,
chunk_t data, chunk_t *signature)
{
switch (scheme)
@@ -201,95 +185,56 @@ static size_t get_keysize(private_openssl_rsa_private_key_t *this)
}
/**
- * Implementation of openssl_rsa_private_key.get_id.
- */
-static identification_t* get_id(private_openssl_rsa_private_key_t *this,
- id_type_t type)
-{
- switch (type)
- {
- case ID_PUBKEY_INFO_SHA1:
- return this->keyid_info;
- case ID_PUBKEY_SHA1:
- return this->keyid;
- default:
- return NULL;
- }
-}
-
-/**
* Implementation of openssl_rsa_private_key.get_public_key.
*/
-static openssl_rsa_public_key_t* get_public_key(private_openssl_rsa_private_key_t *this)
+static public_key_t* get_public_key(private_openssl_rsa_private_key_t *this)
{
- return openssl_rsa_public_key_create_from_n_e(this->rsa->n, this->rsa->e);
+ chunk_t enc;
+ public_key_t *key;
+ u_char *p;
+
+ enc = chunk_alloc(i2d_RSAPublicKey(this->rsa, NULL));
+ p = enc.ptr;
+ i2d_RSAPublicKey(this->rsa, &p);
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ BUILD_BLOB_ASN1_DER, enc, BUILD_END);
+ free(enc.ptr);
+ return key;
}
/**
- * Implementation of openssl_rsa_private_key.equals.
+ * Implementation of public_key_t.get_fingerprint.
*/
-static bool equals(private_openssl_rsa_private_key_t *this, private_key_t *other)
+static bool get_fingerprint(private_openssl_rsa_private_key_t *this,
+ key_encoding_type_t type, chunk_t *fingerprint)
{
- identification_t *keyid;
-
- if (&this->public.interface == other)
- {
- return TRUE;
- }
- if (other->get_type(other) != KEY_RSA)
- {
- return FALSE;
- }
- keyid = other->get_id(other, ID_PUBKEY_SHA1);
- if (keyid && keyid->equals(keyid, this->keyid))
- {
- return TRUE;
- }
- keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
- if (keyid && keyid->equals(keyid, this->keyid_info))
- {
- return TRUE;
- }
- return FALSE;
+ return openssl_rsa_fingerprint(this->rsa, type, fingerprint);
}
-/**
- * Implementation of openssl_rsa_private_key.belongs_to.
+/*
+ * Implementation of public_key_t.get_encoding.
*/
-static bool belongs_to(private_openssl_rsa_private_key_t *this, public_key_t *public)
+static bool get_encoding(private_openssl_rsa_private_key_t *this,
+ key_encoding_type_t type, chunk_t *encoding)
{
- identification_t *keyid;
+ u_char *p;
- if (public->get_type(public) != KEY_RSA)
+ if (this->engine)
{
return FALSE;
}
- keyid = public->get_id(public, ID_PUBKEY_SHA1);
- if (keyid && keyid->equals(keyid, this->keyid))
- {
- return TRUE;
- }
- keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
- if (keyid && keyid->equals(keyid, this->keyid_info))
- {
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * Implementation of private_key_t.get_encoding.
- */
-static chunk_t get_encoding(private_openssl_rsa_private_key_t *this)
-{
- chunk_t enc = chunk_empty;
- if (!this->engine)
+ switch (type)
{
- enc = chunk_alloc(i2d_RSAPrivateKey(this->rsa, NULL));
- u_char *p = enc.ptr;
- i2d_RSAPrivateKey(this->rsa, &p);
+ case KEY_PRIV_ASN1_DER:
+ {
+ *encoding = chunk_alloc(i2d_RSAPrivateKey(this->rsa, NULL));
+ p = encoding->ptr;
+ i2d_RSAPrivateKey(this->rsa, &p);
+ return TRUE;
+ }
+ default:
+ return FALSE;
}
- return enc;
}
/**
@@ -299,7 +244,6 @@ static private_openssl_rsa_private_key_t* get_ref(private_openssl_rsa_private_ke
{
ref_get(&this->ref);
return this;
-
}
/**
@@ -311,10 +255,9 @@ static void destroy(private_openssl_rsa_private_key_t *this)
{
if (this->rsa)
{
+ lib->encoding->clear_cache(lib->encoding, this->rsa);
RSA_free(this->rsa);
}
- DESTROY_IF(this->keyid);
- DESTROY_IF(this->keyid_info);
free(this);
}
}
@@ -322,238 +265,215 @@ static void destroy(private_openssl_rsa_private_key_t *this)
/**
* Internal generic constructor
*/
-static private_openssl_rsa_private_key_t *openssl_rsa_private_key_create_empty(void)
+static private_openssl_rsa_private_key_t *create_empty(void)
{
private_openssl_rsa_private_key_t *this = malloc_thing(private_openssl_rsa_private_key_t);
-
+
this->public.interface.get_type = (key_type_t (*) (private_key_t*))get_type;
this->public.interface.sign = (bool (*) (private_key_t*, signature_scheme_t, chunk_t, chunk_t*))sign;
this->public.interface.decrypt = (bool (*) (private_key_t*, chunk_t, chunk_t*))decrypt;
this->public.interface.get_keysize = (size_t (*) (private_key_t*))get_keysize;
- this->public.interface.get_id = (identification_t* (*) (private_key_t*, id_type_t))get_id;
this->public.interface.get_public_key = (public_key_t* (*) (private_key_t*))get_public_key;
- this->public.interface.equals = (bool (*) (private_key_t*, private_key_t*))equals;
- this->public.interface.belongs_to = (bool (*) (private_key_t*, public_key_t*))belongs_to;
- this->public.interface.get_encoding = (chunk_t(*) (private_key_t*))get_encoding;
+ this->public.interface.equals = private_key_equals;
+ this->public.interface.belongs_to = private_key_belongs_to;
+ this->public.interface.get_fingerprint = (bool(*)(private_key_t*, key_encoding_type_t type, chunk_t *fp))get_fingerprint;
+ this->public.interface.has_fingerprint = (bool(*)(private_key_t*, chunk_t fp))private_key_has_fingerprint;
+ this->public.interface.get_encoding = (bool(*)(private_key_t*, key_encoding_type_t type, chunk_t *encoding))get_encoding;
this->public.interface.get_ref = (private_key_t* (*) (private_key_t*))get_ref;
this->public.interface.destroy = (void (*) (private_key_t*))destroy;
-
+
this->engine = FALSE;
- this->keyid = NULL;
- this->keyid_info = NULL;
this->ref = 1;
-
+
return this;
}
/**
- * Generate an RSA key of specified key size
+ * See header.
*/
-static openssl_rsa_private_key_t *generate(size_t key_size)
+openssl_rsa_private_key_t *openssl_rsa_private_key_gen(key_type_t type,
+ va_list args)
{
- private_openssl_rsa_private_key_t *this = openssl_rsa_private_key_create_empty();
-
- this->rsa = RSA_generate_key(key_size, PUBLIC_EXPONENT, NULL, NULL);
-
- if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
+ private_openssl_rsa_private_key_t *this;
+ u_int key_size = 0;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_KEY_SIZE:
+ key_size = va_arg(args, u_int);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+ if (!key_size)
{
- destroy(this);
return NULL;
}
-
+ this = create_empty();
+ this->rsa = RSA_generate_key(key_size, PUBLIC_EXPONENT, NULL, NULL);
+
return &this->public;
}
/**
- * load private key from an ASN1 encoded blob
+ * See header
*/
-static openssl_rsa_private_key_t *load(chunk_t blob)
+openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
+ va_list args)
{
- u_char *p = blob.ptr;
- private_openssl_rsa_private_key_t *this = openssl_rsa_private_key_create_empty();
-
- this->rsa = d2i_RSAPrivateKey(NULL, (const u_char**)&p, blob.len);
-
- chunk_clear(&blob);
-
- if (!this->rsa)
+ private_openssl_rsa_private_key_t *this;
+ chunk_t blob, n, e, d, p, q, exp1, exp2, coeff;
+
+ blob = n = e = d = p = q = exp1 = exp2 = coeff = chunk_empty;
+ while (TRUE)
{
- destroy(this);
- return NULL;
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_BLOB_ASN1_DER:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_RSA_MODULUS:
+ n = va_arg(args, chunk_t);
+ continue;
+ case BUILD_RSA_PUB_EXP:
+ e = va_arg(args, chunk_t);
+ continue;
+ case BUILD_RSA_PRIV_EXP:
+ d = va_arg(args, chunk_t);
+ continue;
+ case BUILD_RSA_PRIME1:
+ p = va_arg(args, chunk_t);
+ continue;
+ case BUILD_RSA_PRIME2:
+ q = va_arg(args, chunk_t);
+ continue;
+ case BUILD_RSA_EXP1:
+ exp1 = va_arg(args, chunk_t);
+ continue;
+ case BUILD_RSA_EXP2:
+ exp2 = va_arg(args, chunk_t);
+ continue;
+ case BUILD_RSA_COEFF:
+ coeff = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
}
-
- if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
+
+ this = create_empty();
+ if (blob.ptr)
{
- destroy(this);
- return NULL;
+ this->rsa = d2i_RSAPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len);
+ if (this->rsa && RSA_check_key(this->rsa))
+ {
+ return &this->public;
+ }
}
-
- if (!RSA_check_key(this->rsa))
+ else if (n.ptr && e.ptr && d.ptr && p.ptr && q.ptr && coeff.ptr)
{
- destroy(this);
- return NULL;
+ this->rsa = RSA_new();
+ this->rsa->n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL);
+ this->rsa->e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL);
+ this->rsa->d = BN_bin2bn((const u_char*)d.ptr, d.len, NULL);
+ this->rsa->p = BN_bin2bn((const u_char*)p.ptr, p.len, NULL);
+ this->rsa->q = BN_bin2bn((const u_char*)q.ptr, q.len, NULL);
+ if (exp1.ptr)
+ {
+ this->rsa->dmp1 = BN_bin2bn((const u_char*)exp1.ptr, exp1.len, NULL);
+ }
+ if (exp2.ptr)
+ {
+ this->rsa->dmq1 = BN_bin2bn((const u_char*)exp2.ptr, exp2.len, NULL);
+ }
+ this->rsa->iqmp = BN_bin2bn((const u_char*)coeff.ptr, coeff.len, NULL);
+ if (RSA_check_key(this->rsa))
+ {
+ return &this->public;
+ }
}
-
- return &this->public;
+ destroy(this);
+ return NULL;
}
/**
- * load private key from a smart card
+ * See header.
*/
-static openssl_rsa_private_key_t *load_from_smartcard(char *keyid, char *pin)
+openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
+ va_list args)
{
- private_openssl_rsa_private_key_t *this = NULL;
+ private_openssl_rsa_private_key_t *this;
+ char *keyid = NULL, *pin = NULL;
EVP_PKEY *key;
- char *engine_id = lib->settings->get_str(lib->settings,
+ char *engine_id;
+ ENGINE *engine;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_SMARTCARD_KEYID:
+ keyid = va_arg(args, char*);
+ continue;
+ case BUILD_SMARTCARD_PIN:
+ pin = va_arg(args, char*);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+ if (!keyid || !pin)
+ {
+ return NULL;
+ }
+
+ engine_id = lib->settings->get_str(lib->settings,
"library.plugins.openssl.engine_id", "pkcs11");
-
- ENGINE *engine = ENGINE_by_id(engine_id);
+ engine = ENGINE_by_id(engine_id);
if (!engine)
{
DBG1("engine '%s' is not available", engine_id);
return NULL;
}
-
if (!ENGINE_init(engine))
{
DBG1("failed to initialize engine '%s'", engine_id);
- goto error;
+ ENGINE_free(engine);
+ return NULL;
}
-
if (!ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0))
{
DBG1("failed to set PIN on engine '%s'", engine_id);
- goto error;
+ ENGINE_free(engine);
+ return NULL;
}
-
+
key = ENGINE_load_private_key(engine, keyid, NULL, NULL);
-
if (!key)
{
- DBG1("failed to load private key with ID '%s' from engine '%s'", keyid,
- engine_id);
- goto error;
- }
- ENGINE_free(engine);
-
- this = openssl_rsa_private_key_create_empty();
- this->rsa = EVP_PKEY_get1_RSA(key);
- this->engine = TRUE;
-
- if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
- {
- destroy(this);
+ DBG1("failed to load private key with ID '%s' from engine '%s'",
+ keyid, engine_id);
+ ENGINE_free(engine);
return NULL;
}
- return &this->public;
-
-error:
ENGINE_free(engine);
- return NULL;
-}
-
-typedef struct private_builder_t private_builder_t;
-/**
- * Builder implementation for key loading/generation
- */
-struct private_builder_t {
- /** implements the builder interface */
- builder_t public;
- /** loaded/generated private key */
- openssl_rsa_private_key_t *key;
- /** temporary stored smartcard key ID */
- char *keyid;
- /** temporary stored smartcard pin */
- char *pin;
-};
-/**
- * Implementation of builder_t.build
- */
-static openssl_rsa_private_key_t *build(private_builder_t *this)
-{
- openssl_rsa_private_key_t *key = this->key;
-
- if (this->keyid && this->pin)
- {
- key = load_from_smartcard(this->keyid, this->pin);
- }
- free(this);
- return key;
-}
-
-/**
- * Implementation of builder_t.add
- */
-static void add(private_builder_t *this, builder_part_t part, ...)
-{
- if (!this->key)
- {
- va_list args;
- chunk_t chunk;
-
- switch (part)
- {
- case BUILD_BLOB_ASN1_DER:
- {
- va_start(args, part);
- chunk = va_arg(args, chunk_t);
- this->key = load(chunk_clone(chunk));
- va_end(args);
- return;
- }
- case BUILD_KEY_SIZE:
- {
- va_start(args, part);
- this->key = generate(va_arg(args, u_int));
- va_end(args);
- return;
- }
- case BUILD_SMARTCARD_KEYID:
- {
- va_start(args, part);
- this->keyid = va_arg(args, char*);
- va_end(args);
- return;
- }
- case BUILD_SMARTCARD_PIN:
- {
- va_start(args, part);
- this->pin = va_arg(args, char*);
- va_end(args);
- return;
- }
- default:
- break;
- }
- }
- if (this->key)
- {
- destroy((private_openssl_rsa_private_key_t*)this->key);
- }
- builder_cancel(&this->public);
-}
+ this = create_empty();
+ this->rsa = EVP_PKEY_get1_RSA(key);
+ this->engine = TRUE;
-/**
- * Builder construction function
- */
-builder_t *openssl_rsa_private_key_builder(key_type_t type)
-{
- private_builder_t *this;
-
- if (type != KEY_RSA)
- {
- return NULL;
- }
-
- this = malloc_thing(private_builder_t);
-
- this->key = NULL;
- this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
- this->public.build = (void*(*)(builder_t *this))build;
- this->keyid = NULL;
- this->pin = NULL;
-
return &this->public;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
index 53ec44b28..079dfa46a 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
@@ -21,6 +21,7 @@
#ifndef OPENSSL_RSA_PRIVATE_KEY_H_
#define OPENSSL_RSA_PRIVATE_KEY_H_
+#include <credentials/builder.h>
#include <credentials/keys/private_key.h>
typedef struct openssl_rsa_private_key_t openssl_rsa_private_key_t;
@@ -37,11 +38,40 @@ struct openssl_rsa_private_key_t {
};
/**
- * Create the builder for a private key.
+ * Generate a RSA private key using OpenSSL.
+ *
+ * Accepts the BUILD_KEY_SIZE argument.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @param args builder_part_t argument list
+ * @return generated key, NULL on failure
+ */
+openssl_rsa_private_key_t *openssl_rsa_private_key_gen(key_type_t type,
+ va_list args);
+
+/**
+ * Load a RSA private key using OpenSSL.
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
+ *
+ * @param type type of the key, must be KEY_RSA
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
+ va_list args);
+
+/**
+ * Connect to a RSA private key on a smartcard.
+ *
+ * Accepts the BUILD_SMARTCARD_KEYID and the BUILD_SMARTCARD_PIN
+ * arguments.
*
* @param type type of the key, must be KEY_RSA
- * @return builder instance
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
*/
-builder_t *openssl_rsa_private_key_builder(key_type_t type);
+openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
+ va_list args);
#endif /** OPENSSL_RSA_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
index bc1ba35b6..422262b19 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2009 Martin Willi
* Copyright (C) 2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
@@ -31,22 +32,12 @@ struct private_openssl_rsa_public_key_t {
* Public interface for this signer.
*/
openssl_rsa_public_key_t public;
-
+
/**
* RSA object from OpenSSL
*/
RSA *rsa;
-
- /**
- * Keyid formed as a SHA-1 hash of a publicKeyInfo object
- */
- identification_t *keyid_info;
-
- /**
- * Keyid formed as a SHA-1 hash of a publicKey object
- */
- identification_t *keyid;
-
+
/**
* reference counter
*/
@@ -109,7 +100,7 @@ static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this,
goto error;
}
valid = (EVP_VerifyFinal(ctx, signature.ptr, signature.len, key) == 1);
-
+
error:
if (key)
{
@@ -134,7 +125,7 @@ static key_type_t get_type(private_openssl_rsa_public_key_t *this)
/**
* Implementation of public_key_t.verify.
*/
-static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t scheme,
+static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t scheme,
chunk_t data, chunk_t signature)
{
switch (scheme)
@@ -163,41 +154,14 @@ static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t sc
/**
* Implementation of public_key_t.get_keysize.
*/
-static bool encrypt_(private_openssl_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain)
+static bool encrypt_(private_openssl_rsa_public_key_t *this,
+ chunk_t crypto, chunk_t *plain)
{
DBG1("RSA public key encryption not implemented");
return FALSE;
}
/**
- * Implementation of public_key_t.equals.
- */
-static bool equals(private_openssl_rsa_public_key_t *this, public_key_t *other)
-{
- identification_t *keyid;
-
- if (&this->public.interface == other)
- {
- return TRUE;
- }
- if (other->get_type(other) != KEY_RSA)
- {
- return FALSE;
- }
- keyid = other->get_id(other, ID_PUBKEY_SHA1);
- if (keyid && keyid->equals(keyid, this->keyid))
- {
- return TRUE;
- }
- keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1);
- if (keyid && keyid->equals(keyid, this->keyid_info))
- {
- return TRUE;
- }
- return FALSE;
-}
-
-/**
* Implementation of public_key_t.get_keysize.
*/
static size_t get_keysize(private_openssl_rsa_public_key_t *this)
@@ -206,79 +170,92 @@ static size_t get_keysize(private_openssl_rsa_public_key_t *this)
}
/**
- * Implementation of public_key_t.get_id.
+ * Calculate fingerprint from a RSA key, also used in rsa private key.
*/
-static identification_t *get_id(private_openssl_rsa_public_key_t *this,
- id_type_t type)
+bool openssl_rsa_fingerprint(RSA *rsa, key_encoding_type_t type, chunk_t *fp)
{
+ hasher_t *hasher;
+ chunk_t key;
+ u_char *p;
+
+ if (lib->encoding->get_cache(lib->encoding, type, rsa, fp))
+ {
+ return TRUE;
+ }
switch (type)
{
- case ID_PUBKEY_INFO_SHA1:
- return this->keyid_info;
- case ID_PUBKEY_SHA1:
- return this->keyid;
+ case KEY_ID_PUBKEY_SHA1:
+ key = chunk_alloc(i2d_RSAPublicKey(rsa, NULL));
+ p = key.ptr;
+ i2d_RSAPublicKey(rsa, &p);
+ break;
+ case KEY_ID_PUBKEY_INFO_SHA1:
+ key = chunk_alloc(i2d_RSA_PUBKEY(rsa, NULL));
+ p = key.ptr;
+ i2d_RSA_PUBKEY(rsa, &p);
+ break;
default:
- return NULL;
+ return FALSE;
}
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher)
+ {
+ DBG1("SHA1 hash algorithm not supported, fingerprinting failed");
+ free(key.ptr);
+ return FALSE;
+ }
+ hasher->allocate_hash(hasher, key, fp);
+ free(key.ptr);
+ hasher->destroy(hasher);
+ lib->encoding->cache(lib->encoding, type, rsa, *fp);
+ return TRUE;
}
/**
- * Encodes the public key
- */
-static chunk_t get_encoding_raw(RSA *rsa)
-{
- chunk_t enc = chunk_alloc(i2d_RSAPublicKey(rsa, NULL));
- u_char *p = enc.ptr;
- i2d_RSAPublicKey(rsa, &p);
- return enc;
-}
-
-/**
- * Encodes the public key with the algorithm used
+ * Implementation of public_key_t.get_fingerprint.
*/
-static chunk_t get_encoding_with_algo(RSA *rsa)
+static bool get_fingerprint(private_openssl_rsa_public_key_t *this,
+ key_encoding_type_t type, chunk_t *fingerprint)
{
- u_char *p;
- chunk_t enc;
- X509_PUBKEY *pubkey = X509_PUBKEY_new();
-
- ASN1_OBJECT_free(pubkey->algor->algorithm);
- pubkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
-
- if (pubkey->algor->parameter == NULL ||
- pubkey->algor->parameter->type != V_ASN1_NULL)
- {
- ASN1_TYPE_free(pubkey->algor->parameter);
- pubkey->algor->parameter = ASN1_TYPE_new();
- pubkey->algor->parameter->type = V_ASN1_NULL;
- }
-
- enc = get_encoding_raw(rsa);
- M_ASN1_BIT_STRING_set(pubkey->public_key, enc.ptr, enc.len);
- chunk_free(&enc);
-
- enc = chunk_alloc(i2d_X509_PUBKEY(pubkey, NULL));
- p = enc.ptr;
- i2d_X509_PUBKEY(pubkey, &p);
- X509_PUBKEY_free(pubkey);
- return enc;
+ return openssl_rsa_fingerprint(this->rsa, type, fingerprint);
}
/*
* Implementation of public_key_t.get_encoding.
*/
-static chunk_t get_encoding(private_openssl_rsa_public_key_t *this)
+static bool get_encoding(private_openssl_rsa_public_key_t *this,
+ key_encoding_type_t type, chunk_t *encoding)
{
- return get_encoding_raw(this->rsa);
+ u_char *p;
+
+ switch (type)
+ {
+ case KEY_PUB_SPKI_ASN1_DER:
+ {
+ *encoding = chunk_alloc(i2d_RSA_PUBKEY(this->rsa, NULL));
+ p = encoding->ptr;
+ i2d_RSA_PUBKEY(this->rsa, &p);
+ return TRUE;
+ }
+ case KEY_PUB_ASN1_DER:
+ {
+ *encoding = chunk_alloc(i2d_RSAPublicKey(this->rsa, NULL));
+ p = encoding->ptr;
+ i2d_RSAPublicKey(this->rsa, &p);
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
}
/**
* Implementation of public_key_t.get_ref.
*/
-static private_openssl_rsa_public_key_t* get_ref(private_openssl_rsa_public_key_t *this)
+static public_key_t* get_ref(private_openssl_rsa_public_key_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public.interface;
}
/**
@@ -290,10 +267,9 @@ static void destroy(private_openssl_rsa_public_key_t *this)
{
if (this->rsa)
{
+ lib->encoding->clear_cache(lib->encoding, this->rsa);
RSA_free(this->rsa);
}
- DESTROY_IF(this->keyid);
- DESTROY_IF(this->keyid_info);
free(this);
}
}
@@ -301,179 +277,75 @@ static void destroy(private_openssl_rsa_public_key_t *this)
/**
* Generic private constructor
*/
-static private_openssl_rsa_public_key_t *openssl_rsa_public_key_create_empty()
+static private_openssl_rsa_public_key_t *create_empty()
{
private_openssl_rsa_public_key_t *this = malloc_thing(private_openssl_rsa_public_key_t);
-
+
this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type;
this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify;
this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_;
- this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals;
+ this->public.interface.equals = public_key_equals;
this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
- this->public.interface.get_id = (identification_t* (*) (public_key_t *this,id_type_t))get_id;
- this->public.interface.get_encoding = (chunk_t(*)(public_key_t*))get_encoding;
+ this->public.interface.get_fingerprint = (bool(*)(public_key_t*, key_encoding_type_t type, chunk_t *fp))get_fingerprint;
+ this->public.interface.has_fingerprint = (bool(*)(public_key_t*, chunk_t fp))public_key_has_fingerprint;
+ this->public.interface.get_encoding = (bool(*)(public_key_t*, key_encoding_type_t type, chunk_t *encoding))get_encoding;
this->public.interface.get_ref = (public_key_t* (*)(public_key_t *this))get_ref;
this->public.interface.destroy = (void (*)(public_key_t *this))destroy;
-
- this->keyid = NULL;
- this->keyid_info = NULL;
- this->ref = 1;
-
- return this;
-}
-
-/**
- * Build the RSA key identifier from n and e using SHA1 hashed publicKey(Info).
- * Also used in openssl_rsa_private_key.c.
- */
-bool openssl_rsa_public_key_build_id(RSA *rsa, identification_t **keyid,
- identification_t **keyid_info)
-{
- chunk_t publicKeyInfo, publicKey, hash;
- hasher_t *hasher;
-
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (hasher == NULL)
- {
- DBG1("SHA1 hash algorithm not supported, unable to use RSA");
- return FALSE;
- }
-
- publicKey = get_encoding_raw(rsa);
-
- hasher->allocate_hash(hasher, publicKey, &hash);
- *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash);
- chunk_free(&hash);
-
- publicKeyInfo = get_encoding_with_algo(rsa);
-
- hasher->allocate_hash(hasher, publicKeyInfo, &hash);
- *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash);
- chunk_free(&hash);
-
- hasher->destroy(hasher);
- chunk_free(&publicKeyInfo);
- chunk_free(&publicKey);
-
- return TRUE;
-}
-
-/**
- * Create a public key from BIGNUM values, used in openssl_rsa_private_key.c
- */
-openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGNUM *e)
-{
- private_openssl_rsa_public_key_t *this = openssl_rsa_public_key_create_empty();
-
- this->rsa = RSA_new();
- this->rsa->n = BN_dup(n);
- this->rsa->e = BN_dup(e);
-
- if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
- {
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-/**
- * Load a public key from an ASN1 encoded blob
- */
-static openssl_rsa_public_key_t *load(chunk_t blob)
-{
- u_char *p = blob.ptr;
- private_openssl_rsa_public_key_t *this = openssl_rsa_public_key_create_empty();
-
- this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&p, blob.len);
-
- chunk_clear(&blob);
-
- if (!this->rsa)
- {
- destroy(this);
- return NULL;
- }
+ this->rsa = NULL;
+ this->ref = 1;
- if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info))
- {
- destroy(this);
- return NULL;
- }
- return &this->public;
+ return this;
}
-typedef struct private_builder_t private_builder_t;
/**
- * Builder implementation for key loading
+ * See header.
*/
-struct private_builder_t {
- /** implements the builder interface */
- builder_t public;
- /** loaded public key */
- openssl_rsa_public_key_t *key;
-};
-
-/**
- * Implementation of builder_t.build
- */
-static openssl_rsa_public_key_t *build(private_builder_t *this)
+openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type,
+ va_list args)
{
- openssl_rsa_public_key_t *key = this->key;
-
- free(this);
- return key;
-}
+ private_openssl_rsa_public_key_t *this;
+ chunk_t blob, n, e;
-/**
- * Implementation of builder_t.add
- */
-static void add(private_builder_t *this, builder_part_t part, ...)
-{
- if (!this->key)
+ n = e = blob = chunk_empty;
+ while (TRUE)
{
- va_list args;
- chunk_t chunk;
-
- switch (part)
+ switch (va_arg(args, builder_part_t))
{
case BUILD_BLOB_ASN1_DER:
- {
- va_start(args, part);
- chunk = va_arg(args, chunk_t);
- this->key = load(chunk_clone(chunk));
- va_end(args);
- return;
- }
- default:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_RSA_MODULUS:
+ n = va_arg(args, chunk_t);
+ continue;
+ case BUILD_RSA_PUB_EXP:
+ e = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
break;
+ default:
+ return NULL;
}
+ break;
}
- if (this->key)
+
+ this = create_empty();
+ if (blob.ptr)
{
- destroy((private_openssl_rsa_public_key_t*)this->key);
+ this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&blob.ptr, blob.len);
+ if (this->rsa)
+ {
+ return &this->public;
+ }
}
- builder_cancel(&this->public);
-}
-
-/**
- * Builder construction function
- */
-builder_t *openssl_rsa_public_key_builder(key_type_t type)
-{
- private_builder_t *this;
-
- if (type != KEY_RSA)
+ else if (n.ptr && e.ptr)
{
- return NULL;
+ this->rsa = RSA_new();
+ this->rsa->n = BN_bin2bn((const u_char*)n.ptr, n.len, NULL);
+ this->rsa->e = BN_bin2bn((const u_char*)e.ptr, e.len, NULL);
+ return &this->public;
}
-
- this = malloc_thing(private_builder_t);
-
- this->key = NULL;
- this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
- this->public.build = (void*(*)(builder_t *this))build;
-
- return &this->public;
+ destroy(this);
+ return NULL;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
index ff99ddbc5..620aa51ce 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
@@ -37,11 +37,15 @@ struct openssl_rsa_public_key_t {
};
/**
- * Create the builder for a public key.
+ * Load a RSA public key using OpenSSL.
+ *
+ * Accepts a BUILD_BLOB_ASN1_DER argument.
*
* @param type type of the key, must be KEY_RSA
- * @return builder instance
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
*/
-builder_t *openssl_rsa_public_key_builder(key_type_t type);
+openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type,
+ va_list args);
#endif /** OPENSSL_RSA_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.c b/src/libstrongswan/plugins/openssl/openssl_util.c
index c8c453f64..55b18a524 100644
--- a/src/libstrongswan/plugins/openssl/openssl_util.c
+++ b/src/libstrongswan/plugins/openssl/openssl_util.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2009 Martin Willi
* Copyright (C) 2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
@@ -18,6 +19,7 @@
#include <debug.h>
#include <openssl/evp.h>
+#include <openssl/x509.h>
/**
* Described in header.
@@ -31,30 +33,30 @@ bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash)
{
return FALSE;
}
-
- ctx = EVP_MD_CTX_create();
+
+ ctx = EVP_MD_CTX_create();
if (!ctx)
{
goto error;
}
-
+
if (!EVP_DigestInit_ex(ctx, hasher, NULL))
{
goto error;
}
-
+
if (!EVP_DigestUpdate(ctx, data.ptr, data.len))
{
goto error;
}
-
+
*hash = chunk_alloc(hasher->md_size);
if (!EVP_DigestFinal_ex(ctx, hash->ptr, NULL))
{
chunk_free(hash);
goto error;
}
-
+
ret = TRUE;
error:
if (ctx)
@@ -70,18 +72,18 @@ error:
bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk)
{
int offset;
-
+
chunk->len = len + (b ? len : 0);
chunk->ptr = malloc(chunk->len);
memset(chunk->ptr, 0, chunk->len);
-
+
/* convert a */
offset = len - BN_num_bytes(a);
if (!BN_bn2bin(a, chunk->ptr + offset))
{
goto error;
}
-
+
/* optionally convert and concatenate b */
if (b)
{
@@ -90,8 +92,8 @@ bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk)
{
goto error;
}
- }
-
+ }
+
return TRUE;
error:
chunk_free(chunk);
@@ -105,19 +107,20 @@ error:
bool openssl_bn_split(chunk_t chunk, BIGNUM *a, BIGNUM *b)
{
int len;
-
+
if ((chunk.len % 2) != 0)
{
return FALSE;
}
-
+
len = chunk.len / 2;
-
+
if (!BN_bin2bn(chunk.ptr, len, a) ||
!BN_bin2bn(chunk.ptr + len, len, b))
{
return FALSE;
}
-
+
return TRUE;
}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.h b/src/libstrongswan/plugins/openssl/openssl_util.h
index 6ba1ff07b..538008f2c 100644
--- a/src/libstrongswan/plugins/openssl/openssl_util.h
+++ b/src/libstrongswan/plugins/openssl/openssl_util.h
@@ -31,9 +31,9 @@
/**
* Creates a hash of a given type of a chunk of data.
- *
+ *
* Note: this function allocates memory for the hash
- *
+ *
* @param hash_type NID of the hash
* @param data the chunk of data to hash
* @param hash chunk that contains the hash
@@ -44,9 +44,9 @@ bool openssl_hash_chunk(int hash_type, chunk_t data, chunk_t *hash);
/**
* Concatenates two bignums into a chunk, thereby enfocing the length of
* a single BIGNUM, if necessary, by pre-pending it with zeros.
- *
+ *
* Note: this function allocates memory for the chunk
- *
+ *
* @param len the length of a single BIGNUM
* @param a first BIGNUM
* @param b second BIGNUM
@@ -57,7 +57,7 @@ bool openssl_bn_cat(int len, BIGNUM *a, BIGNUM *b, chunk_t *chunk);
/**
* Splits a chunk into two bignums of equal binary length.
- *
+ *
* @param chunk a chunk that contains the two BIGNUMs
* @param a first BIGNUM
* @param b second BIGNUM