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.am4
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.in23
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crl.c7
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.c28
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.c4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.c88
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hmac.c191
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hmac.h45
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c55
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rng.c100
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rng.h54
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c3
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_sha1_prf.c20
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_x509.c13
15 files changed, 533 insertions, 106 deletions
diff --git a/src/libstrongswan/plugins/openssl/Makefile.am b/src/libstrongswan/plugins/openssl/Makefile.am
index 5c845a19c..c59888663 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.am
+++ b/src/libstrongswan/plugins/openssl/Makefile.am
@@ -22,7 +22,9 @@ libstrongswan_openssl_la_SOURCES = \
openssl_ec_private_key.c openssl_ec_private_key.h \
openssl_ec_public_key.c openssl_ec_public_key.h \
openssl_x509.c openssl_x509.h \
- openssl_crl.c openssl_crl.h
+ openssl_crl.c openssl_crl.h \
+ openssl_rng.c openssl_rng.h \
+ openssl_hmac.c openssl_hmac.h
libstrongswan_openssl_la_LDFLAGS = -module -avoid-version
libstrongswan_openssl_la_LIBADD = -lcrypto
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
index 8994ff1b4..ada44ead3 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.in
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -80,7 +81,8 @@ am_libstrongswan_openssl_la_OBJECTS = openssl_plugin.lo \
openssl_sha1_prf.lo openssl_diffie_hellman.lo \
openssl_rsa_private_key.lo openssl_rsa_public_key.lo \
openssl_ec_diffie_hellman.lo openssl_ec_private_key.lo \
- openssl_ec_public_key.lo openssl_x509.lo openssl_crl.lo
+ openssl_ec_public_key.lo openssl_x509.lo openssl_crl.lo \
+ openssl_rng.lo openssl_hmac.lo
libstrongswan_openssl_la_OBJECTS = \
$(am_libstrongswan_openssl_la_OBJECTS)
libstrongswan_openssl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -89,7 +91,7 @@ libstrongswan_openssl_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@MONOLITHIC_FALSE@am_libstrongswan_openssl_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
@MONOLITHIC_TRUE@am_libstrongswan_openssl_la_rpath =
-DEFAULT_INCLUDES = -I.@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@@ -115,6 +117,7 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BFDLIB = @BFDLIB@
BTLIB = @BTLIB@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
@@ -209,11 +212,14 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
-default_pkcs11 = @default_pkcs11@
+dev_headers = @dev_headers@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
@@ -230,11 +236,12 @@ imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
-libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
linux_headers = @linux_headers@
@@ -250,6 +257,7 @@ mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
@@ -259,7 +267,6 @@ pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
plugindir = @plugindir@
-pluto_plugins = @pluto_plugins@
pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
@@ -304,7 +311,9 @@ libstrongswan_openssl_la_SOURCES = \
openssl_ec_private_key.c openssl_ec_private_key.h \
openssl_ec_public_key.c openssl_ec_public_key.h \
openssl_x509.c openssl_x509.h \
- openssl_crl.c openssl_crl.h
+ openssl_crl.c openssl_crl.h \
+ openssl_rng.c openssl_rng.h \
+ openssl_hmac.c openssl_hmac.h
libstrongswan_openssl_la_LDFLAGS = -module -avoid-version
libstrongswan_openssl_la_LIBADD = -lcrypto
@@ -398,7 +407,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_private_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_ec_public_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_hasher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_hmac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_rng.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_rsa_private_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_rsa_public_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openssl_sha1_prf.Plo@am__quote@
diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c
index 9a9efb2b6..e529ff8a5 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crl.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crl.c
@@ -225,7 +225,8 @@ METHOD(certificate_t, has_subject_or_issuer, id_match_t,
}
METHOD(certificate_t, issued_by, bool,
- private_openssl_crl_t *this, certificate_t *issuer)
+ private_openssl_crl_t *this, certificate_t *issuer,
+ signature_scheme_t *scheme)
{
chunk_t fingerprint, tbs;
public_key_t *key;
@@ -270,6 +271,10 @@ METHOD(certificate_t, issued_by, bool,
openssl_asn1_str2chunk(this->crl->signature));
free(tbs.ptr);
key->destroy(key);
+ if (valid && scheme)
+ {
+ *scheme = this->scheme;
+ }
return valid;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c
index cd9a3bd4a..07b96b320 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crypter.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c
@@ -90,7 +90,7 @@ static char* lookup_algorithm(u_int16_t ikev2_algo, size_t *key_size)
/**
* Do the actual en/decryption in an EVP context
*/
-static void crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv,
+static bool crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv,
chunk_t *dst, int enc)
{
int len;
@@ -104,25 +104,26 @@ static void crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv,
}
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
- EVP_CipherInit_ex(&ctx, this->cipher, NULL, NULL, NULL, enc);
- EVP_CIPHER_CTX_set_padding(&ctx, 0); /* disable padding */
- EVP_CIPHER_CTX_set_key_length(&ctx, this->key.len);
- EVP_CipherInit_ex(&ctx, NULL, NULL, this->key.ptr, iv.ptr, enc);
- EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len);
- EVP_CipherFinal_ex(&ctx, out + len, &len); /* since padding is disabled this does nothing */
- EVP_CIPHER_CTX_cleanup(&ctx);
+ return EVP_CipherInit_ex(&ctx, this->cipher, NULL, NULL, NULL, enc) &&
+ EVP_CIPHER_CTX_set_padding(&ctx, 0) /* disable padding */ &&
+ EVP_CIPHER_CTX_set_key_length(&ctx, this->key.len) &&
+ EVP_CipherInit_ex(&ctx, NULL, NULL, this->key.ptr, iv.ptr, enc) &&
+ EVP_CipherUpdate(&ctx, out, &len, data.ptr, data.len) &&
+ /* since padding is disabled this does nothing */
+ EVP_CipherFinal_ex(&ctx, out + len, &len) &&
+ EVP_CIPHER_CTX_cleanup(&ctx);
}
-METHOD(crypter_t, decrypt, void,
+METHOD(crypter_t, decrypt, bool,
private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
{
- crypt(this, data, iv, dst, 0);
+ return crypt(this, data, iv, dst, 0);
}
-METHOD(crypter_t, encrypt, void,
+METHOD(crypter_t, encrypt, bool,
private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
{
- crypt(this, data, iv, dst, 1);
+ return crypt(this, data, iv, dst, 1);
}
METHOD(crypter_t, get_block_size, size_t,
@@ -143,10 +144,11 @@ METHOD(crypter_t, get_key_size, size_t,
return this->key.len;
}
-METHOD(crypter_t, set_key, void,
+METHOD(crypter_t, set_key, bool,
private_openssl_crypter_t *this, chunk_t key)
{
memcpy(this->key.ptr, key.ptr, min(key.len, this->key.len));
+ return TRUE;
}
METHOD(crypter_t, destroy, void,
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
index 7461695ad..9cb68a3ab 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
@@ -221,13 +221,13 @@ bool openssl_ec_fingerprint(EC_KEY *ec, cred_encoding_type_t type, chunk_t *fp)
return FALSE;
}
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (!hasher)
+ if (!hasher || !hasher->allocate_hash(hasher, key, fp))
{
DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed");
+ DESTROY_IF(hasher);
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);
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.c b/src/libstrongswan/plugins/openssl/openssl_hasher.c
index d81f4b21e..50b14698b 100644
--- a/src/libstrongswan/plugins/openssl/openssl_hasher.c
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.c
@@ -40,91 +40,45 @@ struct private_openssl_hasher_t {
EVP_MD_CTX *ctx;
};
-/**
- * Mapping from the algorithms defined in IKEv2 to
- * OpenSSL algorithm names
- */
-typedef struct {
- /**
- * Identifier specified in IKEv2
- */
- int ikev2_id;
-
- /**
- * Name of the algorithm, as used in OpenSSL
- */
- char *name;
-} openssl_algorithm_t;
-
-#define END_OF_LIST -1
-
-/**
- * Algorithms for integrity
- */
-static openssl_algorithm_t integrity_algs[] = {
- {HASH_MD2, "md2"},
- {HASH_MD5, "md5"},
- {HASH_SHA1, "sha1"},
- {HASH_SHA224, "sha224"},
- {HASH_SHA256, "sha256"},
- {HASH_SHA384, "sha384"},
- {HASH_SHA512, "sha512"},
- {HASH_MD4, "md4"},
- {END_OF_LIST, NULL},
-};
-
-/**
- * Look up an OpenSSL algorithm name
- */
-static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
- u_int16_t ikev2_algo)
-{
- while (openssl_algo->ikev2_id != END_OF_LIST)
- {
- if (ikev2_algo == openssl_algo->ikev2_id)
- {
- return openssl_algo->name;
- }
- openssl_algo++;
- }
- return NULL;
-}
-
METHOD(hasher_t, get_hash_size, size_t,
private_openssl_hasher_t *this)
{
return this->hasher->md_size;
}
-METHOD(hasher_t, reset, void,
+METHOD(hasher_t, reset, bool,
private_openssl_hasher_t *this)
{
- EVP_DigestInit_ex(this->ctx, this->hasher, NULL);
+ return EVP_DigestInit_ex(this->ctx, this->hasher, NULL) == 1;
}
-METHOD(hasher_t, get_hash, void,
+METHOD(hasher_t, get_hash, bool,
private_openssl_hasher_t *this, chunk_t chunk, u_int8_t *hash)
{
- EVP_DigestUpdate(this->ctx, chunk.ptr, chunk.len);
+ if (EVP_DigestUpdate(this->ctx, chunk.ptr, chunk.len) != 1)
+ {
+ return FALSE;
+ }
if (hash)
{
- EVP_DigestFinal_ex(this->ctx, hash, NULL);
- reset(this);
+ if (EVP_DigestFinal_ex(this->ctx, hash, NULL) != 1)
+ {
+ return FALSE;
+ }
+ return reset(this);
}
+ return TRUE;
}
-METHOD(hasher_t, allocate_hash, void,
+METHOD(hasher_t, allocate_hash, bool,
private_openssl_hasher_t *this, chunk_t chunk, chunk_t *hash)
{
if (hash)
{
*hash = chunk_alloc(get_hash_size(this));
- get_hash(this, chunk, hash->ptr);
- }
- else
- {
- get_hash(this, chunk, NULL);
+ return get_hash(this, chunk, hash->ptr);
}
+ return get_hash(this, chunk, NULL);
}
METHOD(hasher_t, destroy, void,
@@ -140,11 +94,11 @@ METHOD(hasher_t, destroy, void,
openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
{
private_openssl_hasher_t *this;
+ char* name;
- char* name = lookup_algorithm(integrity_algs, algo);
+ name = enum_to_name(hash_algorithm_short_names, algo);
if (!name)
{
- /* algo unavailable */
return NULL;
}
@@ -171,7 +125,11 @@ openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
this->ctx = EVP_MD_CTX_create();
/* initialization */
- reset(this);
+ if (!reset(this))
+ {
+ destroy(this);
+ return NULL;
+ }
return &this->public;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_hmac.c b/src/libstrongswan/plugins/openssl/openssl_hmac.c
new file mode 100644
index 000000000..5d05425d3
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_hmac.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2012 Tobias Brunner
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/*
+ * Copyright (C) 2012 Aleksandr Grinberg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+#include "openssl_hmac.h"
+
+#include <crypto/mac.h>
+#include <crypto/prfs/mac_prf.h>
+#include <crypto/signers/mac_signer.h>
+
+typedef struct private_mac_t private_mac_t;
+
+/**
+ * Private data of a mac_t object.
+ */
+struct private_mac_t {
+
+ /**
+ * Public interface
+ */
+ mac_t public;
+
+ /**
+ * Hasher to use
+ */
+ const EVP_MD *hasher;
+
+ /**
+ * Current HMAC context
+ */
+ HMAC_CTX hmac;
+};
+
+METHOD(mac_t, set_key, bool,
+ private_mac_t *this, chunk_t key)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ return HMAC_Init_ex(&this->hmac, key.ptr, key.len, this->hasher, NULL);
+#else /* OPENSSL_VERSION_NUMBER < 1.0 */
+ HMAC_Init_ex(&this->hmac, key.ptr, key.len, this->hasher, NULL);
+ return TRUE;
+#endif
+}
+
+METHOD(mac_t, get_mac, bool,
+ private_mac_t *this, chunk_t data, u_int8_t *out)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ if (!HMAC_Update(&this->hmac, data.ptr, data.len))
+ {
+ return FALSE;
+ }
+ if (out == NULL)
+ {
+ return TRUE;
+ }
+ if (!HMAC_Final(&this->hmac, out, NULL))
+ {
+ return FALSE;
+ }
+#else /* OPENSSL_VERSION_NUMBER < 1.0 */
+ HMAC_Update(&this->hmac, data.ptr, data.len);
+ if (out == NULL)
+ {
+ return TRUE;
+ }
+ HMAC_Final(&this->hmac, out, NULL);
+#endif
+ return set_key(this, chunk_empty);
+}
+
+METHOD(mac_t, get_mac_size, size_t,
+ private_mac_t *this)
+{
+ return EVP_MD_size(this->hasher);
+}
+
+METHOD(mac_t, destroy, void,
+ private_mac_t *this)
+{
+ HMAC_CTX_cleanup(&this->hmac);
+ free(this);
+}
+
+/*
+ * Create an OpenSSL-backed implementation of the mac_t interface
+ */
+static mac_t *hmac_create(hash_algorithm_t algo)
+{
+ private_mac_t *this;
+ char *name;
+
+ name = enum_to_name(hash_algorithm_short_names, algo);
+ if (!name)
+ {
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .get_mac = _get_mac,
+ .get_mac_size = _get_mac_size,
+ .set_key = _set_key,
+ .destroy = _destroy,
+ },
+ .hasher = EVP_get_digestbyname(name),
+ );
+
+ if (!this->hasher)
+ {
+ free(this);
+ return NULL;
+ }
+
+ HMAC_CTX_init(&this->hmac);
+ if (!set_key(this, chunk_empty))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
+/*
+ * Described in header
+ */
+prf_t *openssl_hmac_prf_create(pseudo_random_function_t algo)
+{
+ mac_t *hmac;
+
+ hmac = hmac_create(hasher_algorithm_from_prf(algo));
+ if (hmac)
+ {
+ return mac_prf_create(hmac);
+ }
+ return NULL;
+}
+
+/*
+ * Described in header
+ */
+signer_t *openssl_hmac_signer_create(integrity_algorithm_t algo)
+{
+ mac_t *hmac;
+ size_t trunc;
+
+ hmac = hmac_create(hasher_algorithm_from_integrity(algo, &trunc));
+ if (hmac)
+ {
+ return mac_signer_create(hmac, trunc);
+ }
+ return NULL;
+}
+
diff --git a/src/libstrongswan/plugins/openssl/openssl_hmac.h b/src/libstrongswan/plugins/openssl/openssl_hmac.h
new file mode 100644
index 000000000..95ab6bfc3
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_hmac.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 Tobias Brunner
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * Implements HMAC based PRF and signer using OpenSSL's HMAC functions.
+ *
+ * @defgroup openssl_hmac openssl_hmac
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_HMAC_H_
+#define OPENSSL_HMAC_H_
+
+#include <crypto/prfs/prf.h>
+#include <crypto/signers/signer.h>
+
+/**
+ * Creates a new prf_t object based on an HMAC.
+ *
+ * @param algo algorithm to implement
+ * @return prf_t object, NULL if not supported
+ */
+prf_t *openssl_hmac_prf_create(pseudo_random_function_t algo);
+
+/**
+ * Creates a new signer_t object based on an HMAC.
+ *
+ * @param algo algorithm to implement
+ * @return signer_t, NULL if not supported
+ */
+signer_t *openssl_hmac_signer_create(integrity_algorithm_t algo);
+
+#endif /** OPENSSL_HMAC_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index c93ceacc9..b69de981e 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -40,6 +40,8 @@
#include "openssl_ec_public_key.h"
#include "openssl_x509.h"
#include "openssl_crl.h"
+#include "openssl_rng.h"
+#include "openssl_hmac.h"
typedef struct private_openssl_plugin_t private_openssl_plugin_t;
@@ -127,7 +129,9 @@ static void destroy_function(struct CRYPTO_dynlock_value *lock,
*/
static unsigned long id_function(void)
{
- return (unsigned long)thread_current_id();
+ /* ensure the thread ID is never zero, otherwise OpenSSL might try to
+ * acquire locks recursively */
+ return 1 + (unsigned long)thread_current_id();
}
/**
@@ -170,7 +174,11 @@ static bool seed_rng()
return FALSE;
}
}
- rng->get_bytes(rng, sizeof(buf), buf);
+ if (!rng->get_bytes(rng, sizeof(buf), buf))
+ {
+ rng->destroy(rng);
+ return FALSE;
+ }
RAND_seed(buf, sizeof(buf));
}
DESTROY_IF(rng);
@@ -260,6 +268,41 @@ METHOD(plugin_t, get_features, int,
PLUGIN_REGISTER(PRF, openssl_sha1_prf_create),
PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1),
#endif
+#ifndef OPENSSL_NO_HMAC
+ PLUGIN_REGISTER(PRF, openssl_hmac_prf_create),
+#ifndef OPENSSL_NO_MD5
+ PLUGIN_PROVIDE(PRF, PRF_HMAC_MD5),
+#endif
+#ifndef OPENSSL_NO_SHA1
+ PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA1),
+#endif
+#ifndef OPENSSL_NO_SHA256
+ PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_256),
+#endif
+#ifndef OPENSSL_NO_SHA512
+ PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_384),
+ PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_512),
+#endif
+ PLUGIN_REGISTER(SIGNER, openssl_hmac_signer_create),
+#ifndef OPENSSL_NO_MD5
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_96),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_128),
+#endif
+#ifndef OPENSSL_NO_SHA1
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_96),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_128),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_160),
+#endif
+#ifndef OPENSSL_NO_SHA256
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_128),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_256),
+#endif
+#ifndef OPENSSL_NO_SHA512
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_192),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_384),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256),
+#endif
+#endif /* OPENSSL_NO_HMAC */
#ifndef OPENSSL_NO_DH
/* MODP DH groups */
PLUGIN_REGISTER(DH, openssl_diffie_hellman_create),
@@ -284,7 +327,7 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
PLUGIN_REGISTER(PRIVKEY_GEN, openssl_rsa_private_key_gen, FALSE),
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
- PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, FALSE),
+ PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE),
PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE),
PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
@@ -317,6 +360,9 @@ METHOD(plugin_t, get_features, int,
/* certificate/CRL loading */
PLUGIN_REGISTER(CERT_DECODE, openssl_x509_load, TRUE),
PLUGIN_PROVIDE(CERT_DECODE, CERT_X509),
+ PLUGIN_SDEPEND(PUBKEY, KEY_RSA),
+ PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA),
+ PLUGIN_SDEPEND(PUBKEY, KEY_DSA),
PLUGIN_REGISTER(CERT_DECODE, openssl_crl_load, TRUE),
PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL),
#ifndef OPENSSL_NO_ECDH
@@ -360,6 +406,9 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521),
#endif
#endif /* OPENSSL_NO_ECDSA */
+ PLUGIN_REGISTER(RNG, openssl_rng_create),
+ PLUGIN_PROVIDE(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(RNG, RNG_WEAK),
};
*features = f;
return countof(f);
diff --git a/src/libstrongswan/plugins/openssl/openssl_rng.c b/src/libstrongswan/plugins/openssl/openssl_rng.c
new file mode 100644
index 000000000..c83244f60
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_rng.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2012 Aleksandr Grinberg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <debug.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#include "openssl_rng.h"
+
+typedef struct private_openssl_rng_t private_openssl_rng_t;
+
+/**
+ * Private data of openssl_rng_t
+ */
+struct private_openssl_rng_t {
+
+ /**
+ * Public part of this class.
+ */
+ openssl_rng_t public;
+
+ /**
+ * Quality of randomness
+ */
+ rng_quality_t quality;
+};
+
+METHOD(rng_t, get_bytes, bool,
+ private_openssl_rng_t *this, size_t bytes, u_int8_t *buffer)
+{
+ u_int32_t ret;
+
+ if (this->quality == RNG_STRONG)
+ {
+ ret = RAND_bytes((char*)buffer, bytes);
+ }
+ else
+ {
+ ret = RAND_pseudo_bytes((char*)buffer, bytes);
+ }
+ return ret != 0;
+}
+
+METHOD(rng_t, allocate_bytes, bool,
+ private_openssl_rng_t *this, size_t bytes, chunk_t *chunk)
+{
+ *chunk = chunk_alloc(bytes);
+ if (!get_bytes(this, chunk->len, chunk->ptr))
+ {
+ chunk_free(chunk);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(rng_t, destroy, void,
+ private_openssl_rng_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+openssl_rng_t *openssl_rng_create(rng_quality_t quality)
+{
+ private_openssl_rng_t *this;
+
+ INIT(this,
+ .public = {
+ .rng = {
+ .get_bytes = _get_bytes,
+ .allocate_bytes = _allocate_bytes,
+ .destroy = _destroy,
+ },
+ },
+ .quality = quality,
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/openssl/openssl_rng.h b/src/libstrongswan/plugins/openssl/openssl_rng.h
new file mode 100644
index 000000000..a4596563a
--- /dev/null
+++ b/src/libstrongswan/plugins/openssl/openssl_rng.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 Aleksandr Grinberg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @defgroup openssl_rng openssl_rng
+ * @{ @ingroup openssl_p
+ */
+
+#ifndef OPENSSL_RNG_H_
+#define OPENSSL_RNG_H_
+
+#include <library.h>
+
+typedef struct openssl_rng_t openssl_rng_t;
+
+/**
+ * Implementation of random number using OpenSSL.
+ */
+struct openssl_rng_t {
+
+ /**
+ * Implements rng_t interface.
+ */
+ rng_t rng;
+};
+
+/**
+ * Constructor to create openssl_rng_t.
+ *
+ * @param quality quality of randomness
+ * @return openssl_rng_t
+ */
+openssl_rng_t *openssl_rng_create(rng_quality_t quality);
+
+#endif /** OPENSSL_RNG_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
index d1afd94cc..98cd700bf 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
@@ -475,7 +475,8 @@ static bool login(ENGINE *engine, chunk_t keyid)
{
found = TRUE;
key = shared->get_key(shared);
- if (snprintf(pin, sizeof(pin), "%.*s", key.len, key.ptr) >= sizeof(pin))
+ if (snprintf(pin, sizeof(pin),
+ "%.*s", (int)key.len, key.ptr) >= sizeof(pin))
{
continue;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
index a24bae5d6..5872a8159 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
@@ -217,13 +217,13 @@ bool openssl_rsa_fingerprint(RSA *rsa, cred_encoding_type_t type, chunk_t *fp)
return FALSE;
}
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (!hasher)
+ if (!hasher || !hasher->allocate_hash(hasher, key, fp))
{
DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed");
+ DESTROY_IF(hasher);
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);
diff --git a/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c
index 20f2fa984..8501e2cd4 100644
--- a/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c
+++ b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c
@@ -35,7 +35,7 @@ struct private_openssl_sha1_prf_t {
SHA_CTX ctx;
};
-METHOD(prf_t, get_bytes, void,
+METHOD(prf_t, get_bytes, bool,
private_openssl_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes)
{
SHA1_Update(&this->ctx, seed.ptr, seed.len);
@@ -50,6 +50,8 @@ METHOD(prf_t, get_bytes, void,
hash[3] = htonl(this->ctx.h3);
hash[4] = htonl(this->ctx.h4);
}
+
+ return TRUE;
}
METHOD(prf_t, get_block_size, size_t,
@@ -58,18 +60,15 @@ METHOD(prf_t, get_block_size, size_t,
return HASH_SIZE_SHA1;
}
-METHOD(prf_t, allocate_bytes, void,
+METHOD(prf_t, allocate_bytes, bool,
private_openssl_sha1_prf_t *this, chunk_t seed, chunk_t *chunk)
{
if (chunk)
{
*chunk = chunk_alloc(HASH_SIZE_SHA1);
- get_bytes(this, seed, chunk->ptr);
- }
- else
- {
- get_bytes(this, seed, NULL);
+ return get_bytes(this, seed, chunk->ptr);
}
+ return get_bytes(this, seed, NULL);
}
METHOD(prf_t, get_key_size, size_t,
@@ -78,11 +77,15 @@ METHOD(prf_t, get_key_size, size_t,
return HASH_SIZE_SHA1;
}
-METHOD(prf_t, set_key, void,
+METHOD(prf_t, set_key, bool,
private_openssl_sha1_prf_t *this, chunk_t key)
{
SHA1_Init(&this->ctx);
+ if (key.len % 4)
+ {
+ return FALSE;
+ }
if (key.len >= 4)
{
this->ctx.h0 ^= untoh32(key.ptr);
@@ -103,6 +106,7 @@ METHOD(prf_t, set_key, void,
{
this->ctx.h4 ^= untoh32(key.ptr + 16);
}
+ return TRUE;
}
METHOD(prf_t, destroy, void,
diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c
index 5caf5182c..e85c5cc90 100644
--- a/src/libstrongswan/plugins/openssl/openssl_x509.c
+++ b/src/libstrongswan/plugins/openssl/openssl_x509.c
@@ -350,7 +350,8 @@ METHOD(certificate_t, has_issuer, id_match_t,
}
METHOD(certificate_t, issued_by, bool,
- private_openssl_x509_t *this, certificate_t *issuer)
+ private_openssl_x509_t *this, certificate_t *issuer,
+ signature_scheme_t *scheme)
{
public_key_t *key;
bool valid;
@@ -393,6 +394,10 @@ METHOD(certificate_t, issued_by, bool,
openssl_asn1_str2chunk(this->x509->signature));
free(tbs.ptr);
key->destroy(key);
+ if (valid && scheme)
+ {
+ *scheme = this->scheme;
+ }
return valid;
}
@@ -968,14 +973,14 @@ static bool parse_certificate(private_openssl_x509_t *this)
parse_extKeyUsage(this);
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (!hasher)
+ if (!hasher || !hasher->allocate_hash(hasher, this->encoding, &this->hash))
{
+ DESTROY_IF(hasher);
return FALSE;
}
- hasher->allocate_hash(hasher, this->encoding, &this->hash);
hasher->destroy(hasher);
- if (issued_by(this, &this->public.x509.interface))
+ if (issued_by(this, &this->public.x509.interface, NULL))
{
this->flags |= X509_SELF_SIGNED;
}