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.in20
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crl.c17
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.c174
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.h4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c72
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h5
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c59
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.c114
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.c104
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.c50
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.h4
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c72
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c229
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c123
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_sha1_prf.c16
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_x509.c57
20 files changed, 651 insertions, 477 deletions
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
index de9df7271..a32418b16 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.in
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -171,6 +172,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -202,14 +205,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -224,24 +230,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
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@
psdir = @psdir@
@@ -249,7 +262,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c
index 5645d72d7..b9d97a901 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crl.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crl.c
@@ -416,10 +416,19 @@ static bool parse_authKeyIdentifier_ext(private_openssl_crl_t *this,
static bool parse_crlNumber_ext(private_openssl_crl_t *this,
X509_EXTENSION *ext)
{
- free(this->serial.ptr);
- this->serial = chunk_clone(
- openssl_asn1_str2chunk(X509_EXTENSION_get_data(ext)));
- return this->serial.len != 0;
+ chunk_t chunk;
+
+ chunk = openssl_asn1_str2chunk(X509_EXTENSION_get_data(ext));
+ /* quick and dirty INTEGER unwrap */
+ if (chunk.len > 1 && chunk.ptr[0] == V_ASN1_INTEGER &&
+ chunk.ptr[1] == chunk.len - 2)
+ {
+ chunk = chunk_skip(chunk, 2);
+ free(this->serial.ptr);
+ this->serial = chunk_clone(chunk);
+ return TRUE;
+ }
+ return FALSE;
}
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c
index a8923ab56..2ed07ff0c 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crypter.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c
@@ -41,85 +41,57 @@ struct private_openssl_crypter_t {
};
/**
- * Mapping from the algorithms defined in IKEv2 to
- * OpenSSL algorithm names and their key length
- */
-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
- */
- size_t key_size_max;
-} openssl_algorithm_t;
-
-#define END_OF_LIST -1
-
-/**
- * Algorithms for encryption
- */
-static openssl_algorithm_t encryption_algs[] = {
-/* {ENCR_DES_IV64, "***", 0, 0}, */
- {ENCR_DES, "des", 8, 8}, /* 64 bits */
- {ENCR_3DES, "des3", 24, 24}, /* 192 bits */
- {ENCR_RC5, "rc5", 5, 255}, /* 40 to 2040 bits, RFC 2451 */
- {ENCR_IDEA, "idea", 16, 16}, /* 128 bits, RFC 2451 */
- {ENCR_CAST, "cast", 5, 16}, /* 40 to 128 bits, RFC 2451 */
- {ENCR_BLOWFISH, "blowfish", 5, 56}, /* 40 to 448 bits, RFC 2451 */
-/* {ENCR_3IDEA, "***", 0, 0}, */
-/* {ENCR_DES_IV32, "***", 0, 0}, */
-/* {ENCR_NULL, "***", 0, 0}, */ /* handled separately */
-/* {ENCR_AES_CBC, "***", 0, 0}, */ /* handled separately */
-/* {ENCR_CAMELLIA_CBC, "***", 0, 0}, */ /* handled separately */
-/* {ENCR_AES_CTR, "***", 0, 0}, */ /* disabled in evp.h */
- {END_OF_LIST, NULL, 0, 0},
-};
-
-/**
* Look up an OpenSSL algorithm name and validate its key size
*/
-static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
- u_int16_t ikev2_algo, size_t *key_size)
+static char* lookup_algorithm(u_int16_t ikev2_algo, size_t *key_size)
{
- while (openssl_algo->ikev2_id != END_OF_LIST)
+ struct {
+ /* identifier specified in IKEv2 */
+ int ikev2_id;
+ /* name of the algorithm, as used in OpenSSL */
+ char *name;
+ /* default key size in bytes */
+ size_t key_def;
+ /* minimum key size */
+ size_t key_min;
+ /* maximum key size */
+ size_t key_max;
+ } mappings[] = {
+ {ENCR_DES, "des", 8, 8, 8},
+ {ENCR_3DES, "des3", 24, 24, 24},
+ {ENCR_RC5, "rc5", 16, 5, 255},
+ {ENCR_IDEA, "idea", 16, 16, 16},
+ {ENCR_CAST, "cast", 16, 5, 16},
+ {ENCR_BLOWFISH, "blowfish", 16, 5, 56},
+ };
+ int i;
+
+ for (i = 0; i < countof(mappings); i++)
{
- if (ikev2_algo == openssl_algo->ikev2_id)
+ if (ikev2_algo == mappings[i].ikev2_id)
{
/* set the key size if it is not set */
- if (*key_size == 0 &&
- (openssl_algo->key_size_min == openssl_algo->key_size_max))
+ if (*key_size == 0)
{
- *key_size = openssl_algo->key_size_min;
+ *key_size = mappings[i].key_def;
}
-
/* validate key size */
- if (*key_size < openssl_algo->key_size_min ||
- *key_size > openssl_algo->key_size_max)
+ if (*key_size < mappings[i].key_min ||
+ *key_size > mappings[i].key_max)
{
return NULL;
}
- return openssl_algo->name;
+ return mappings[i].name;
}
- openssl_algo++;
}
return NULL;
}
-static void crypt(private_openssl_crypter_t *this, chunk_t data,
- chunk_t iv, chunk_t *dst, int enc)
+/**
+ * Do the actual en/decryption in an EVP context
+ */
+static void crypt(private_openssl_crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *dst, int enc)
{
int len;
u_char *out;
@@ -141,53 +113,44 @@ static void crypt(private_openssl_crypter_t *this, chunk_t data,
EVP_CIPHER_CTX_cleanup(&ctx);
}
-/**
- * Implementation of crypter_t.decrypt.
- */
-static void decrypt(private_openssl_crypter_t *this, chunk_t data,
- chunk_t iv, chunk_t *dst)
+METHOD(crypter_t, decrypt, void,
+ private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
{
crypt(this, data, iv, dst, 0);
}
-
-/**
- * Implementation of crypter_t.encrypt.
- */
-static void encrypt (private_openssl_crypter_t *this, chunk_t data,
- chunk_t iv, chunk_t *dst)
+METHOD(crypter_t, encrypt, void,
+ private_openssl_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *dst)
{
crypt(this, data, iv, dst, 1);
}
-/**
- * Implementation of crypter_t.get_block_size.
- */
-static size_t get_block_size(private_openssl_crypter_t *this)
+METHOD(crypter_t, get_block_size, size_t,
+ private_openssl_crypter_t *this)
{
return this->cipher->block_size;
}
-/**
- * Implementation of crypter_t.get_key_size.
- */
-static size_t get_key_size(private_openssl_crypter_t *this)
+METHOD(crypter_t, get_iv_size, size_t,
+ private_openssl_crypter_t *this)
+{
+ return this->cipher->block_size;
+}
+
+METHOD(crypter_t, get_key_size, size_t,
+ private_openssl_crypter_t *this)
{
return this->key.len;
}
-/**
- * Implementation of crypter_t.set_key.
- */
-static void set_key(private_openssl_crypter_t *this, chunk_t key)
+METHOD(crypter_t, set_key, void,
+ private_openssl_crypter_t *this, chunk_t key)
{
memcpy(this->key.ptr, key.ptr, min(key.len, this->key.len));
}
-/**
- * Implementation of crypter_t.destroy.
- */
-static void destroy (private_openssl_crypter_t *this)
+METHOD(crypter_t, destroy, void,
+ private_openssl_crypter_t *this)
{
free(this->key.ptr);
free(this);
@@ -201,16 +164,32 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
{
private_openssl_crypter_t *this;
- this = malloc_thing(private_openssl_crypter_t);
+ INIT(this,
+ .public = {
+ .crypter = {
+ .encrypt = _encrypt,
+ .decrypt = _decrypt,
+ .get_block_size = _get_block_size,
+ .get_iv_size = _get_iv_size,
+ .get_key_size = _get_key_size,
+ .set_key = _set_key,
+ .destroy = _destroy,
+ },
+ },
+ );
switch (algo)
{
case ENCR_NULL:
this->cipher = EVP_enc_null();
+ key_size = 0;
break;
case ENCR_AES_CBC:
switch (key_size)
{
+ case 0:
+ key_size = 16;
+ /* FALL */
case 16: /* AES 128 */
this->cipher = EVP_get_cipherbyname("aes128");
break;
@@ -228,6 +207,9 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
case ENCR_CAMELLIA_CBC:
switch (key_size)
{
+ case 0:
+ key_size = 16;
+ /* FALL */
case 16: /* CAMELLIA 128 */
this->cipher = EVP_get_cipherbyname("camellia128");
break;
@@ -243,11 +225,14 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
}
break;
case ENCR_DES_ECB:
+ key_size = 8;
this->cipher = EVP_des_ecb();
break;
default:
{
- char* name = lookup_algorithm(encryption_algs, algo, &key_size);
+ char* name;
+
+ name = lookup_algorithm(algo, &key_size);
if (!name)
{
/* algo unavailable or key_size invalid */
@@ -268,12 +253,5 @@ openssl_crypter_t *openssl_crypter_create(encryption_algorithm_t algo,
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 7e30ae03c..b12e7a6ab 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crypter.h
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.h
@@ -31,9 +31,9 @@ typedef struct openssl_crypter_t openssl_crypter_t;
struct openssl_crypter_t {
/**
- * The crypter_t interface.
+ * Implements crypter_t interface.
*/
- crypter_t crypter_interface;
+ crypter_t crypter;
};
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
index 9a032c54f..b27aa3391 100644
--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
@@ -57,11 +57,8 @@ struct private_openssl_diffie_hellman_t {
bool computed;
};
-/**
- * Implementation of openssl_diffie_hellman_t.get_my_public_value.
- */
-static void get_my_public_value(private_openssl_diffie_hellman_t *this,
- chunk_t *value)
+METHOD(diffie_hellman_t, get_my_public_value, void,
+ private_openssl_diffie_hellman_t *this, chunk_t *value)
{
*value = chunk_alloc(DH_size(this->dh));
memset(value->ptr, 0, value->len);
@@ -69,11 +66,8 @@ static void get_my_public_value(private_openssl_diffie_hellman_t *this,
value->ptr + value->len - BN_num_bytes(this->dh->pub_key));
}
-/**
- * Implementation of openssl_diffie_hellman_t.get_shared_secret.
- */
-static status_t get_shared_secret(private_openssl_diffie_hellman_t *this,
- chunk_t *secret)
+METHOD(diffie_hellman_t, get_shared_secret, status_t,
+ private_openssl_diffie_hellman_t *this, chunk_t *secret)
{
if (!this->computed)
{
@@ -88,11 +82,8 @@ static status_t get_shared_secret(private_openssl_diffie_hellman_t *this,
}
-/**
- * Implementation of openssl_diffie_hellman_t.set_other_public_value.
- */
-static void set_other_public_value(private_openssl_diffie_hellman_t *this,
- chunk_t value)
+METHOD(diffie_hellman_t, set_other_public_value, void,
+ private_openssl_diffie_hellman_t *this, chunk_t value)
{
int len;
@@ -110,10 +101,8 @@ static void set_other_public_value(private_openssl_diffie_hellman_t *this,
this->computed = TRUE;
}
-/**
- * Implementation of openssl_diffie_hellman_t.get_dh_group.
- */
-static diffie_hellman_group_t get_dh_group(private_openssl_diffie_hellman_t *this)
+METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
+ private_openssl_diffie_hellman_t *this)
{
return this->group;
}
@@ -137,10 +126,8 @@ static status_t set_modulus(private_openssl_diffie_hellman_t *this)
return SUCCESS;
}
-/**
- * Implementation of openssl_diffie_hellman_t.destroy.
- */
-static void destroy(private_openssl_diffie_hellman_t *this)
+METHOD(diffie_hellman_t, destroy, void,
+ private_openssl_diffie_hellman_t *this)
{
BN_clear_free(this->pub_key);
DH_free(this->dh);
@@ -151,15 +138,22 @@ static void destroy(private_openssl_diffie_hellman_t *this)
/*
* Described in header.
*/
-openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t group)
+openssl_diffie_hellman_t *openssl_diffie_hellman_create(
+ diffie_hellman_group_t group, chunk_t g, chunk_t p)
{
- 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;
+ private_openssl_diffie_hellman_t *this;
+
+ INIT(this,
+ .public = {
+ .dh = {
+ .get_shared_secret = _get_shared_secret,
+ .set_other_public_value = _set_other_public_value,
+ .get_my_public_value = _get_my_public_value,
+ .get_dh_group = _get_dh_group,
+ .destroy = _destroy,
+ },
+ },
+ );
this->dh = DH_new();
if (!this->dh)
@@ -173,11 +167,19 @@ openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t g
this->pub_key = BN_new();
this->shared_secret = chunk_empty;
- /* find a modulus according to group */
- if (set_modulus(this) != SUCCESS)
+ if (group == MODP_CUSTOM)
{
- destroy(this);
- return NULL;
+ this->dh->p = BN_bin2bn(p.ptr, p.len, NULL);
+ this->dh->g = BN_bin2bn(g.ptr, g.len, NULL);
+ }
+ else
+ {
+ /* find a modulus according to group */
+ if (set_modulus(this) != SUCCESS)
+ {
+ destroy(this);
+ return NULL;
+ }
}
/* generate my public and private values */
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
index 6c4b4fe81..53dc59c78 100644
--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
@@ -40,9 +40,12 @@ struct openssl_diffie_hellman_t {
* Creates a new openssl_diffie_hellman_t object.
*
* @param group Diffie Hellman group number to use
+ * @param g custom generator, if MODP_CUSTOM
+ * @param p custom prime, if MODP_CUSTOM
* @return openssl_diffie_hellman_t object, NULL if not supported
*/
-openssl_diffie_hellman_t *openssl_diffie_hellman_create(diffie_hellman_group_t group);
+openssl_diffie_hellman_t *openssl_diffie_hellman_create(
+ diffie_hellman_group_t group, chunk_t g, chunk_t p);
#endif /** OPENSSL_DIFFIE_HELLMAN_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
index a53e8aea0..32fc2bccd 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
@@ -165,7 +165,8 @@ error:
* of the Diffie-Hellman shared secret value is the same as that of the
* Diffie-Hellman public value."
*/
-static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this, chunk_t *shared_secret)
+static bool compute_shared_key(private_openssl_ec_diffie_hellman_t *this,
+ chunk_t *shared_secret)
{
const BIGNUM *priv_key;
EC_POINT *secret = NULL;
@@ -209,10 +210,8 @@ error:
return ret;
}
-/**
- * Implementation of openssl_ec_diffie_hellman_t.set_other_public_value.
- */
-static void set_other_public_value(private_openssl_ec_diffie_hellman_t *this, chunk_t value)
+METHOD(diffie_hellman_t, set_other_public_value, void,
+ private_openssl_ec_diffie_hellman_t *this, chunk_t value)
{
if (!chunk2ecp(this->ec_group, value, this->pub_key))
{
@@ -230,18 +229,14 @@ static void set_other_public_value(private_openssl_ec_diffie_hellman_t *this, ch
this->computed = TRUE;
}
-/**
- * Implementation of openssl_ec_diffie_hellman_t.get_my_public_value.
- */
-static void get_my_public_value(private_openssl_ec_diffie_hellman_t *this,chunk_t *value)
+METHOD(diffie_hellman_t, get_my_public_value, void,
+ private_openssl_ec_diffie_hellman_t *this,chunk_t *value)
{
ecp2chunk(this->ec_group, EC_KEY_get0_public_key(this->key), value, FALSE);
}
-/**
- * Implementation of openssl_ec_diffie_hellman_t.get_shared_secret.
- */
-static status_t get_shared_secret(private_openssl_ec_diffie_hellman_t *this, chunk_t *secret)
+METHOD(diffie_hellman_t, get_shared_secret, status_t,
+ private_openssl_ec_diffie_hellman_t *this, chunk_t *secret)
{
if (!this->computed)
{
@@ -251,18 +246,14 @@ static status_t get_shared_secret(private_openssl_ec_diffie_hellman_t *this, chu
return SUCCESS;
}
-/**
- * Implementation of openssl_ec_diffie_hellman_t.get_dh_group.
- */
-static diffie_hellman_group_t get_dh_group(private_openssl_ec_diffie_hellman_t *this)
+METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
+ private_openssl_ec_diffie_hellman_t *this)
{
return this->group;
}
-/**
- * Implementation of openssl_ec_diffie_hellman_t.destroy.
- */
-static void destroy(private_openssl_ec_diffie_hellman_t *this)
+METHOD(diffie_hellman_t, destroy, void,
+ private_openssl_ec_diffie_hellman_t *this)
{
EC_POINT_clear_free(this->pub_key);
EC_KEY_free(this->key);
@@ -275,13 +266,20 @@ 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;
+ private_openssl_ec_diffie_hellman_t *this;
+
+ INIT(this,
+ .public = {
+ .dh = {
+ .get_shared_secret = _get_shared_secret,
+ .set_other_public_value = _set_other_public_value,
+ .get_my_public_value = _get_my_public_value,
+ .get_dh_group = _get_dh_group,
+ .destroy = _destroy,
+ },
+ },
+ .group = group,
+ );
switch (group)
{
@@ -328,11 +326,6 @@ openssl_ec_diffie_hellman_t *openssl_ec_diffie_hellman_create(diffie_hellman_gro
return NULL;
}
- this->group = group;
- this->computed = FALSE;
-
- this->shared_secret = chunk_empty;
-
return &this->public;
}
#endif /* OPENSSL_NO_EC */
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
index 281155913..f4c4759bf 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
@@ -138,11 +138,9 @@ static bool build_der_signature(private_openssl_ec_private_key_t *this,
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)
+METHOD(private_key_t, sign, bool,
+ private_openssl_ec_private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *signature)
{
switch (scheme)
{
@@ -172,36 +170,38 @@ static bool sign(private_openssl_ec_private_key_t *this,
}
}
-/**
- * Implementation of private_key_t.destroy.
- */
-static bool decrypt(private_openssl_ec_private_key_t *this,
- chunk_t crypto, chunk_t *plain)
+METHOD(private_key_t, decrypt, bool,
+ private_openssl_ec_private_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
{
DBG1(DBG_LIB, "EC private key decryption not implemented");
return FALSE;
}
-/**
- * Implementation of private_key_t.get_keysize.
- */
-static size_t get_keysize(private_openssl_ec_private_key_t *this)
+METHOD(private_key_t, get_keysize, int,
+ private_openssl_ec_private_key_t *this)
{
- return EC_FIELD_ELEMENT_LEN(EC_KEY_get0_group(this->ec));
+ switch (EC_GROUP_get_curve_name(EC_KEY_get0_group(this->ec)))
+ {
+ case NID_X9_62_prime256v1:
+ return 256;
+ case NID_secp384r1:
+ return 384;
+ case NID_secp521r1:
+ return 521;
+ default:
+ return 0;
+ }
}
-/**
- * Implementation of private_key_t.get_type.
- */
-static key_type_t get_type(private_openssl_ec_private_key_t *this)
+METHOD(private_key_t, get_type, key_type_t,
+ private_openssl_ec_private_key_t *this)
{
return KEY_ECDSA;
}
-/**
- * Implementation of private_key_t.get_public_key.
- */
-static public_key_t* get_public_key(private_openssl_ec_private_key_t *this)
+METHOD(private_key_t, get_public_key, public_key_t*,
+ private_openssl_ec_private_key_t *this)
{
public_key_t *public;
chunk_t key;
@@ -217,20 +217,16 @@ static public_key_t* get_public_key(private_openssl_ec_private_key_t *this)
return public;
}
-/**
- * Implementation of private_key_t.get_fingerprint.
- */
-static bool get_fingerprint(private_openssl_ec_private_key_t *this,
- cred_encoding_type_t type, chunk_t *fingerprint)
+METHOD(private_key_t, get_fingerprint, bool,
+ private_openssl_ec_private_key_t *this, cred_encoding_type_t type,
+ chunk_t *fingerprint)
{
return openssl_ec_fingerprint(this->ec, type, fingerprint);
}
-/**
- * Implementation of private_key_t.get_encoding.
- */
-static bool get_encoding(private_openssl_ec_private_key_t *this,
- cred_encoding_type_t type, chunk_t *encoding)
+METHOD(private_key_t, get_encoding, bool,
+ private_openssl_ec_private_key_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
{
u_char *p;
@@ -261,19 +257,15 @@ static bool get_encoding(private_openssl_ec_private_key_t *this,
}
}
-/**
- * Implementation of private_key_t.get_ref.
- */
-static private_key_t* get_ref(private_openssl_ec_private_key_t *this)
+METHOD(private_key_t, get_ref, private_key_t*,
+ private_openssl_ec_private_key_t *this)
{
ref_get(&this->ref);
- return &this->public.interface;
+ return &this->public.key;
}
-/**
- * Implementation of private_key_t.destroy.
- */
-static void destroy(private_openssl_ec_private_key_t *this)
+METHOD(private_key_t, destroy, void,
+ private_openssl_ec_private_key_t *this)
{
if (ref_put(&this->ref))
{
@@ -291,23 +283,27 @@ static void destroy(private_openssl_ec_private_key_t *this)
*/
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_public_key = (public_key_t* (*)(private_key_t *this))get_public_key;
- 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*, cred_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*, cred_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->ref = 1;
+ private_openssl_ec_private_key_t *this;
+
+ INIT(this,
+ .public = {
+ .key = {
+ .get_type = _get_type,
+ .sign = _sign,
+ .decrypt = _decrypt,
+ .get_keysize = _get_keysize,
+ .get_public_key = _get_public_key,
+ .equals = private_key_equals,
+ .belongs_to = private_key_belongs_to,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = private_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .ref = 1,
+ );
return this;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
index 720c63f90..f56c95aa1 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
@@ -34,7 +34,7 @@ struct openssl_ec_private_key_t {
/**
* Implements private_key_t interface
*/
- private_key_t interface;
+ private_key_t key;
};
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
index def36c92f..7461695ad 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
@@ -130,19 +130,15 @@ static bool verify_der_signature(private_openssl_ec_public_key_t *this,
return valid;
}
-/**
- * Implementation of public_key_t.get_type.
- */
-static key_type_t get_type(private_openssl_ec_public_key_t *this)
+METHOD(public_key_t, get_type, key_type_t,
+ private_openssl_ec_public_key_t *this)
{
return KEY_ECDSA;
}
-/**
- * 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)
+METHOD(public_key_t, verify, bool,
+ private_openssl_ec_public_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t signature)
{
switch (scheme)
{
@@ -172,22 +168,28 @@ static bool verify(private_openssl_ec_public_key_t *this,
}
}
-/**
- * Implementation of public_key_t.get_keysize.
- */
-static bool encrypt_(private_openssl_ec_public_key_t *this,
- chunk_t crypto, chunk_t *plain)
+METHOD(public_key_t, encrypt, bool,
+ private_openssl_ec_public_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
{
DBG1(DBG_LIB, "EC public key encryption not implemented");
return FALSE;
}
-/**
- * Implementation of public_key_t.get_keysize.
- */
-static size_t get_keysize(private_openssl_ec_public_key_t *this)
+METHOD(public_key_t, get_keysize, int,
+ private_openssl_ec_public_key_t *this)
{
- return EC_FIELD_ELEMENT_LEN(EC_KEY_get0_group(this->ec));
+ switch (EC_GROUP_get_curve_name(EC_KEY_get0_group(this->ec)))
+ {
+ case NID_X9_62_prime256v1:
+ return 256;
+ case NID_secp384r1:
+ return 384;
+ case NID_secp521r1:
+ return 521;
+ default:
+ return 0;
+ }
}
/**
@@ -232,20 +234,16 @@ bool openssl_ec_fingerprint(EC_KEY *ec, cred_encoding_type_t type, chunk_t *fp)
return TRUE;
}
-/**
- * Implementation of private_key_t.get_fingerprint.
- */
-static bool get_fingerprint(private_openssl_ec_public_key_t *this,
- cred_encoding_type_t type, chunk_t *fingerprint)
+METHOD(public_key_t, get_fingerprint, bool,
+ private_openssl_ec_public_key_t *this, cred_encoding_type_t type,
+ chunk_t *fingerprint)
{
return openssl_ec_fingerprint(this->ec, type, fingerprint);
}
-/**
- * Implementation of private_key_t.get_encoding.
- */
-static bool get_encoding(private_openssl_ec_public_key_t *this,
- cred_encoding_type_t type, chunk_t *encoding)
+METHOD(public_key_t, get_encoding, bool,
+ private_openssl_ec_public_key_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
{
u_char *p;
@@ -276,19 +274,15 @@ static bool get_encoding(private_openssl_ec_public_key_t *this,
}
}
-/**
- * Implementation of public_key_t.get_ref.
- */
-static public_key_t* get_ref(private_openssl_ec_public_key_t *this)
+METHOD(public_key_t, get_ref, public_key_t*,
+ private_openssl_ec_public_key_t *this)
{
ref_get(&this->ref);
- return &this->public.interface;
+ return &this->public.key;
}
-/**
- * Implementation of openssl_ec_public_key.destroy.
- */
-static void destroy(private_openssl_ec_public_key_t *this)
+METHOD(public_key_t, destroy, void,
+ private_openssl_ec_public_key_t *this)
{
if (ref_put(&this->ref))
{
@@ -306,21 +300,25 @@ static void destroy(private_openssl_ec_public_key_t *this)
*/
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.equals = public_key_equals;
- this->public.interface.get_fingerprint = (bool(*)(public_key_t*, cred_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*, cred_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->ref = 1;
+ private_openssl_ec_public_key_t *this;
+
+ INIT(this,
+ .public = {
+ .key = {
+ .get_type = _get_type,
+ .verify = _verify,
+ .encrypt = _encrypt,
+ .get_keysize = _get_keysize,
+ .equals = public_key_equals,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = public_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .ref = 1,
+ );
return this;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
index 29d607d38..8094083a7 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.h
@@ -34,7 +34,7 @@ struct openssl_ec_public_key_t {
/**
* Implements the public_key_t interface
*/
- public_key_t interface;
+ public_key_t key;
};
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.c b/src/libstrongswan/plugins/openssl/openssl_hasher.c
index 7556bc594..d81f4b21e 100644
--- a/src/libstrongswan/plugins/openssl/openssl_hasher.c
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.c
@@ -90,27 +90,20 @@ static char* lookup_algorithm(openssl_algorithm_t *openssl_algo,
return NULL;
}
-/**
- * Implementation of hasher_t.get_hash_size.
- */
-static size_t get_hash_size(private_openssl_hasher_t *this)
+METHOD(hasher_t, get_hash_size, size_t,
+ private_openssl_hasher_t *this)
{
return this->hasher->md_size;
}
-/**
- * Implementation of hasher_t.reset.
- */
-static void reset(private_openssl_hasher_t *this)
+METHOD(hasher_t, reset, void,
+ private_openssl_hasher_t *this)
{
EVP_DigestInit_ex(this->ctx, this->hasher, NULL);
}
-/**
- * Implementation of hasher_t.get_hash.
- */
-static void get_hash(private_openssl_hasher_t *this, chunk_t chunk,
- u_int8_t *hash)
+METHOD(hasher_t, get_hash, void,
+ private_openssl_hasher_t *this, chunk_t chunk, u_int8_t *hash)
{
EVP_DigestUpdate(this->ctx, chunk.ptr, chunk.len);
if (hash)
@@ -120,11 +113,8 @@ static void get_hash(private_openssl_hasher_t *this, chunk_t chunk,
}
}
-/**
- * Implementation of hasher_t.allocate_hash.
- */
-static void allocate_hash(private_openssl_hasher_t *this, chunk_t chunk,
- chunk_t *hash)
+METHOD(hasher_t, allocate_hash, void,
+ private_openssl_hasher_t *this, chunk_t chunk, chunk_t *hash)
{
if (hash)
{
@@ -137,10 +127,8 @@ static void allocate_hash(private_openssl_hasher_t *this, chunk_t chunk,
}
}
-/**
- * Implementation of hasher_t.destroy.
- */
-static void destroy (private_openssl_hasher_t *this)
+METHOD(hasher_t, destroy, void,
+ private_openssl_hasher_t *this)
{
EVP_MD_CTX_destroy(this->ctx);
free(this);
@@ -160,7 +148,17 @@ openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
return NULL;
}
- this = malloc_thing(private_openssl_hasher_t);
+ INIT(this,
+ .public = {
+ .hasher = {
+ .get_hash = _get_hash,
+ .allocate_hash = _allocate_hash,
+ .get_hash_size = _get_hash_size,
+ .reset = _reset,
+ .destroy = _destroy,
+ },
+ },
+ );
this->hasher = EVP_get_digestbyname(name);
if (!this->hasher)
@@ -170,12 +168,6 @@ openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
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 */
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.h b/src/libstrongswan/plugins/openssl/openssl_hasher.h
index fd7a043d1..b03f6891b 100644
--- a/src/libstrongswan/plugins/openssl/openssl_hasher.h
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.h
@@ -31,9 +31,9 @@ typedef struct openssl_hasher_t openssl_hasher_t;
struct openssl_hasher_t {
/**
- * The hasher_t interface.
+ * Implements hasher_t interface.
*/
- hasher_t hasher_interface;
+ hasher_t hasher;
};
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index 31697dcb8..0ab4eda9c 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -16,6 +16,7 @@
#include <openssl/evp.h>
#include <openssl/conf.h>
+#include <openssl/rand.h>
#include <openssl/crypto.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
@@ -24,6 +25,7 @@
#include "openssl_plugin.h"
#include <library.h>
+#include <debug.h>
#include <threading/thread.h>
#include <threading/mutex.h>
#include "openssl_util.h"
@@ -151,6 +153,31 @@ static void threading_init()
}
/**
+ * Seed the OpenSSL RNG, if required
+ */
+static bool seed_rng()
+{
+ rng_t *rng = NULL;
+ char buf[32];
+
+ while (RAND_status() != 1)
+ {
+ if (!rng)
+ {
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (!rng)
+ {
+ return FALSE;
+ }
+ }
+ rng->get_bytes(rng, sizeof(buf), buf);
+ RAND_seed(buf, sizeof(buf));
+ }
+ DESTROY_IF(rng);
+ return TRUE;
+}
+
+/**
* cleanup OpenSSL threading locks
*/
static void threading_cleanup()
@@ -166,10 +193,8 @@ static void threading_cleanup()
mutex = NULL;
}
-/**
- * Implementation of openssl_plugin_t.destroy
- */
-static void destroy(private_openssl_plugin_t *this)
+METHOD(plugin_t, destroy, void,
+ private_openssl_plugin_t *this)
{
lib->crypto->remove_crypter(lib->crypto,
(crypter_constructor_t)openssl_crypter_create);
@@ -218,9 +243,15 @@ static void destroy(private_openssl_plugin_t *this)
*/
plugin_t *openssl_plugin_create()
{
- private_openssl_plugin_t *this = malloc_thing(private_openssl_plugin_t);
+ private_openssl_plugin_t *this;
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
+ );
threading_init();
@@ -233,6 +264,13 @@ plugin_t *openssl_plugin_create()
ENGINE_register_all_complete();
#endif /* OPENSSL_NO_ENGINE */
+ if (!seed_rng())
+ {
+ DBG1(DBG_CFG, "no RNG found to seed OpenSSL");
+ destroy(this);
+ return NULL;
+ }
+
/* crypter */
lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
(crypter_constructor_t)openssl_crypter_create);
@@ -312,33 +350,35 @@ plugin_t *openssl_plugin_create()
(dh_constructor_t)openssl_diffie_hellman_create);
lib->crypto->add_dh(lib->crypto, MODP_768_BIT,
(dh_constructor_t)openssl_diffie_hellman_create);
+ lib->crypto->add_dh(lib->crypto, MODP_CUSTOM,
+ (dh_constructor_t)openssl_diffie_hellman_create);
/* rsa */
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, TRUE,
(builder_function_t)openssl_rsa_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE,
(builder_function_t)openssl_rsa_private_key_gen);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY, FALSE,
(builder_function_t)openssl_rsa_private_key_connect);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, TRUE,
(builder_function_t)openssl_rsa_public_key_load);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE,
(builder_function_t)openssl_rsa_public_key_load);
#ifndef OPENSSL_NO_EC
/* ecdsa */
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, TRUE,
(builder_function_t)openssl_ec_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA,
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, FALSE,
(builder_function_t)openssl_ec_private_key_gen);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA,
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA, TRUE,
(builder_function_t)openssl_ec_public_key_load);
#endif /* OPENSSL_NO_EC */
/* X509 certificates */
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509, TRUE,
(builder_function_t)openssl_x509_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, TRUE,
(builder_function_t)openssl_crl_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 5817ade9e..0b607c386 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
@@ -131,19 +131,16 @@ error:
return success;
}
-/**
- * Implementation of openssl_rsa_private_key.get_type.
- */
-static key_type_t get_type(private_openssl_rsa_private_key_t *this)
+
+METHOD(private_key_t, get_type, key_type_t,
+ private_openssl_rsa_private_key_t *this)
{
return KEY_RSA;
}
-/**
- * Implementation of openssl_rsa_private_key.sign.
- */
-static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t *signature)
+METHOD(private_key_t, sign, bool,
+ private_openssl_rsa_private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *signature)
{
switch (scheme)
{
@@ -168,28 +165,47 @@ static bool sign(private_openssl_rsa_private_key_t *this, signature_scheme_t sch
}
}
-/**
- * Implementation of openssl_rsa_private_key.decrypt.
- */
-static bool decrypt(private_openssl_rsa_private_key_t *this,
- chunk_t crypto, chunk_t *plain)
+METHOD(private_key_t, decrypt, bool,
+ private_openssl_rsa_private_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
{
- DBG1(DBG_LIB, "RSA private key decryption not implemented");
- return FALSE;
+ int padding, len;
+ char *decrypted;
+
+ switch (scheme)
+ {
+ case ENCRYPT_RSA_PKCS1:
+ padding = RSA_PKCS1_PADDING;
+ break;
+ case ENCRYPT_RSA_OAEP_SHA1:
+ padding = RSA_PKCS1_OAEP_PADDING;
+ break;
+ default:
+ DBG1(DBG_LIB, "encryption scheme %N not supported via openssl",
+ encryption_scheme_names, scheme);
+ return FALSE;
+ }
+ decrypted = malloc(RSA_size(this->rsa));
+ len = RSA_private_decrypt(crypto.len, crypto.ptr, decrypted,
+ this->rsa, padding);
+ if (len < 0)
+ {
+ DBG1(DBG_LIB, "RSA decryption failed");
+ free(decrypted);
+ return FALSE;
+ }
+ *plain = chunk_create(decrypted, len);
+ return TRUE;
}
-/**
- * Implementation of openssl_rsa_private_key.get_keysize.
- */
-static size_t get_keysize(private_openssl_rsa_private_key_t *this)
+METHOD(private_key_t, get_keysize, int,
+ private_openssl_rsa_private_key_t *this)
{
- return RSA_size(this->rsa);
+ return RSA_size(this->rsa) * 8;
}
-/**
- * Implementation of openssl_rsa_private_key.get_public_key.
- */
-static public_key_t* get_public_key(private_openssl_rsa_private_key_t *this)
+METHOD(private_key_t, get_public_key, public_key_t*,
+ private_openssl_rsa_private_key_t *this)
{
chunk_t enc;
public_key_t *key;
@@ -204,20 +220,16 @@ static public_key_t* get_public_key(private_openssl_rsa_private_key_t *this)
return key;
}
-/**
- * Implementation of public_key_t.get_fingerprint.
- */
-static bool get_fingerprint(private_openssl_rsa_private_key_t *this,
- cred_encoding_type_t type, chunk_t *fingerprint)
+METHOD(private_key_t, get_fingerprint, bool,
+ private_openssl_rsa_private_key_t *this, cred_encoding_type_t type,
+ chunk_t *fingerprint)
{
return openssl_rsa_fingerprint(this->rsa, type, fingerprint);
}
-/*
- * Implementation of public_key_t.get_encoding.
- */
-static bool get_encoding(private_openssl_rsa_private_key_t *this,
- cred_encoding_type_t type, chunk_t *encoding)
+METHOD(private_key_t, get_encoding, bool,
+ private_openssl_rsa_private_key_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
{
u_char *p;
@@ -252,19 +264,15 @@ static bool get_encoding(private_openssl_rsa_private_key_t *this,
}
}
-/**
- * Implementation of openssl_rsa_private_key.get_ref.
- */
-static private_openssl_rsa_private_key_t* get_ref(private_openssl_rsa_private_key_t *this)
+METHOD(private_key_t, get_ref, private_key_t*,
+ private_openssl_rsa_private_key_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public.key;
}
-/**
- * Implementation of openssl_rsa_private_key.destroy.
- */
-static void destroy(private_openssl_rsa_private_key_t *this)
+METHOD(private_key_t, destroy, void,
+ private_openssl_rsa_private_key_t *this)
{
if (ref_put(&this->ref))
{
@@ -280,25 +288,29 @@ static void destroy(private_openssl_rsa_private_key_t *this)
/**
* Internal generic constructor
*/
-static private_openssl_rsa_private_key_t *create_empty(void)
+static private_openssl_rsa_private_key_t *create_empty()
{
- 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_public_key = (public_key_t* (*) (private_key_t*))get_public_key;
- 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*, cred_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*, cred_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->ref = 1;
+ private_openssl_rsa_private_key_t *this;
+
+ INIT(this,
+ .public = {
+ .key = {
+ .get_type = _get_type,
+ .sign = _sign,
+ .decrypt = _decrypt,
+ .get_keysize = _get_keysize,
+ .get_public_key = _get_public_key,
+ .equals = private_key_equals,
+ .belongs_to = private_key_belongs_to,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = private_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .ref = 1,
+ );
return this;
}
@@ -444,6 +456,48 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
}
/**
+ * Login to engine with a PIN specified for a keyid
+ */
+static bool login(ENGINE *engine, chunk_t keyid)
+{
+ enumerator_t *enumerator;
+ shared_key_t *shared;
+ identification_t *id;
+ chunk_t key;
+ char pin[64];
+ bool found = FALSE, success = FALSE;
+
+ id = identification_create_from_encoding(ID_KEY_ID, keyid);
+ enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
+ SHARED_PIN, id, NULL);
+ while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
+ {
+ found = TRUE;
+ key = shared->get_key(shared);
+ if (snprintf(pin, sizeof(pin), "%.*s", key.len, key.ptr) >= sizeof(pin))
+ {
+ continue;
+ }
+ if (ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0))
+ {
+ success = TRUE;
+ break;
+ }
+ else
+ {
+ DBG1(DBG_CFG, "setting PIN on engine failed");
+ }
+ }
+ enumerator->destroy(enumerator);
+ id->destroy(id);
+ if (!found)
+ {
+ DBG1(DBG_CFG, "no PIN found for %#B", &keyid);
+ }
+ return success;
+}
+
+/**
* See header.
*/
openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
@@ -451,20 +505,25 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
{
#ifndef OPENSSL_NO_ENGINE
private_openssl_rsa_private_key_t *this;
- char *keyid = NULL, *pin = NULL;
+ char *engine_id = NULL;
+ char keyname[64];
+ chunk_t keyid = chunk_empty;;
EVP_PKEY *key;
- char *engine_id;
ENGINE *engine;
+ int slot = -1;
while (TRUE)
{
switch (va_arg(args, builder_part_t))
{
- case BUILD_SMARTCARD_KEYID:
- keyid = va_arg(args, char*);
+ case BUILD_PKCS11_KEYID:
+ keyid = va_arg(args, chunk_t);
continue;
- case BUILD_SMARTCARD_PIN:
- pin = va_arg(args, char*);
+ case BUILD_PKCS11_SLOT:
+ slot = va_arg(args, int);
+ continue;
+ case BUILD_PKCS11_MODULE:
+ engine_id = va_arg(args, char*);
continue;
case BUILD_END:
break;
@@ -473,17 +532,31 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
}
break;
}
- if (!keyid || !pin)
+ if (!keyid.len || keyid.len > 40)
{
return NULL;
}
- engine_id = lib->settings->get_str(lib->settings,
+ memset(keyname, 0, sizeof(keyname));
+ if (slot != -1)
+ {
+ snprintf(keyname, sizeof(keyname), "%d:", slot);
+ }
+ if (sizeof(keyname) - strlen(keyname) <= keyid.len * 4 / 3 + 1)
+ {
+ return NULL;
+ }
+ chunk_to_hex(keyid, keyname + strlen(keyname), FALSE);
+
+ if (!engine_id)
+ {
+ engine_id = lib->settings->get_str(lib->settings,
"libstrongswan.plugins.openssl.engine_id", "pkcs11");
+ }
engine = ENGINE_by_id(engine_id);
if (!engine)
{
- DBG1(DBG_LIB, "engine '%s' is not available", engine_id);
+ DBG2(DBG_LIB, "engine '%s' is not available", engine_id);
return NULL;
}
if (!ENGINE_init(engine))
@@ -492,18 +565,17 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
ENGINE_free(engine);
return NULL;
}
- if (!ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0))
+ if (!login(engine, keyid))
{
- DBG1(DBG_LIB, "failed to set PIN on engine '%s'", engine_id);
+ DBG1(DBG_LIB, "login to engine '%s' failed", engine_id);
ENGINE_free(engine);
return NULL;
}
-
- key = ENGINE_load_private_key(engine, keyid, NULL, NULL);
+ key = ENGINE_load_private_key(engine, keyname, NULL, NULL);
if (!key)
{
DBG1(DBG_LIB, "failed to load private key with ID '%s' from "
- "engine '%s'", keyid, engine_id);
+ "engine '%s'", keyname, engine_id);
ENGINE_free(engine);
return NULL;
}
@@ -512,6 +584,11 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
this = create_empty();
this->rsa = EVP_PKEY_get1_RSA(key);
this->engine = TRUE;
+ if (!this->rsa)
+ {
+ destroy(this);
+ return NULL;
+ }
return &this->public;
#else /* OPENSSL_NO_ENGINE */
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
index 079dfa46a..60889d651 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
@@ -34,7 +34,7 @@ struct openssl_rsa_private_key_t {
/**
* Implements private_key_t interface
*/
- private_key_t interface;
+ private_key_t key;
};
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
index 6ac61a65c..422e31521 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
@@ -114,19 +114,15 @@ error:
return valid;
}
-/**
- * Implementation of public_key_t.get_type.
- */
-static key_type_t get_type(private_openssl_rsa_public_key_t *this)
+METHOD(public_key_t, get_type, key_type_t,
+ private_openssl_rsa_public_key_t *this)
{
return KEY_RSA;
}
-/**
- * Implementation of public_key_t.verify.
- */
-static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t signature)
+METHOD(public_key_t, verify, bool,
+ private_openssl_rsa_public_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t signature)
{
switch (scheme)
{
@@ -151,22 +147,43 @@ 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)
+METHOD(public_key_t, encrypt, bool,
+ private_openssl_rsa_public_key_t *this, encryption_scheme_t scheme,
+ chunk_t plain, chunk_t *crypto)
{
- DBG1(DBG_LIB, "RSA public key encryption not implemented");
- return FALSE;
+ int padding, len;
+ char *encrypted;
+
+ switch (scheme)
+ {
+ case ENCRYPT_RSA_PKCS1:
+ padding = RSA_PKCS1_PADDING;
+ break;
+ case ENCRYPT_RSA_OAEP_SHA1:
+ padding = RSA_PKCS1_OAEP_PADDING;
+ break;
+ default:
+ DBG1(DBG_LIB, "decryption scheme %N not supported via openssl",
+ encryption_scheme_names, scheme);
+ return FALSE;
+ }
+ encrypted = malloc(RSA_size(this->rsa));
+ len = RSA_public_encrypt(plain.len, plain.ptr, encrypted,
+ this->rsa, padding);
+ if (len < 0)
+ {
+ DBG1(DBG_LIB, "RSA decryption failed");
+ free(encrypted);
+ return FALSE;
+ }
+ *crypto = chunk_create(encrypted, len);
+ return TRUE;
}
-/**
- * Implementation of public_key_t.get_keysize.
- */
-static size_t get_keysize(private_openssl_rsa_public_key_t *this)
+METHOD(public_key_t, get_keysize, int,
+ private_openssl_rsa_public_key_t *this)
{
- return RSA_size(this->rsa);
+ return RSA_size(this->rsa) * 8;
}
/**
@@ -211,20 +228,16 @@ bool openssl_rsa_fingerprint(RSA *rsa, cred_encoding_type_t type, chunk_t *fp)
return TRUE;
}
-/**
- * Implementation of public_key_t.get_fingerprint.
- */
-static bool get_fingerprint(private_openssl_rsa_public_key_t *this,
- cred_encoding_type_t type, chunk_t *fingerprint)
+METHOD(public_key_t, get_fingerprint, bool,
+ private_openssl_rsa_public_key_t *this, cred_encoding_type_t type,
+ chunk_t *fingerprint)
{
return openssl_rsa_fingerprint(this->rsa, type, fingerprint);
}
-/*
- * Implementation of public_key_t.get_encoding.
- */
-static bool get_encoding(private_openssl_rsa_public_key_t *this,
- cred_encoding_type_t type, chunk_t *encoding)
+METHOD(public_key_t, get_encoding, bool,
+ private_openssl_rsa_public_key_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
{
u_char *p;
@@ -262,19 +275,15 @@ static bool get_encoding(private_openssl_rsa_public_key_t *this,
}
}
-/**
- * Implementation of public_key_t.get_ref.
- */
-static public_key_t* get_ref(private_openssl_rsa_public_key_t *this)
+METHOD(public_key_t, get_ref, public_key_t*,
+ private_openssl_rsa_public_key_t *this)
{
ref_get(&this->ref);
- return &this->public.interface;
+ return &this->public.key;
}
-/**
- * Implementation of openssl_rsa_public_key.destroy.
- */
-static void destroy(private_openssl_rsa_public_key_t *this)
+METHOD(public_key_t, destroy, void,
+ private_openssl_rsa_public_key_t *this)
{
if (ref_put(&this->ref))
{
@@ -292,21 +301,25 @@ static void destroy(private_openssl_rsa_public_key_t *this)
*/
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 = public_key_equals;
- this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize;
- this->public.interface.get_fingerprint = (bool(*)(public_key_t*, cred_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*, cred_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->rsa = NULL;
- this->ref = 1;
+ private_openssl_rsa_public_key_t *this;
+
+ INIT(this,
+ .public = {
+ .key = {
+ .get_type = _get_type,
+ .verify = _verify,
+ .encrypt = _encrypt,
+ .equals = public_key_equals,
+ .get_keysize = _get_keysize,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = public_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .ref = 1,
+ );
return this;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
index 620aa51ce..021257d3c 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.h
@@ -33,7 +33,7 @@ struct openssl_rsa_public_key_t {
/**
* Implements the public_key_t interface
*/
- public_key_t interface;
+ public_key_t key;
};
/**
diff --git a/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c
index b65388010..20f2fa984 100644
--- a/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c
+++ b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c
@@ -124,13 +124,15 @@ openssl_sha1_prf_t *openssl_sha1_prf_create(pseudo_random_function_t algo)
}
INIT(this,
- .public.prf = {
- .get_block_size = _get_block_size,
- .get_bytes = _get_bytes,
- .allocate_bytes = _allocate_bytes,
- .get_key_size = _get_key_size,
- .set_key = _set_key,
- .destroy = _destroy,
+ .public = {
+ .prf = {
+ .get_block_size = _get_block_size,
+ .get_bytes = _get_bytes,
+ .allocate_bytes = _allocate_bytes,
+ .get_key_size = _get_key_size,
+ .set_key = _set_key,
+ .destroy = _destroy,
+ },
},
);
diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c
index 1c9bb699e..aa39bc93d 100644
--- a/src/libstrongswan/plugins/openssl/openssl_x509.c
+++ b/src/libstrongswan/plugins/openssl/openssl_x509.c
@@ -187,6 +187,15 @@ static identification_t *general_name2id(GENERAL_NAME *name)
}
case GEN_DIRNAME :
return openssl_x509_name2id(name->d.directoryName);
+ case GEN_OTHERNAME:
+ if (OBJ_obj2nid(name->d.otherName->type_id) == NID_ms_upn &&
+ name->d.otherName->value->type == V_ASN1_UTF8STRING)
+ {
+ return identification_create_from_encoding(ID_RFC822_ADDR,
+ openssl_asn1_str2chunk(
+ name->d.otherName->value->value.utf8string));
+ }
+ return NULL;
default:
return NULL;
}
@@ -286,10 +295,23 @@ METHOD(certificate_t, has_subject, id_match_t,
identification_t *current;
enumerator_t *enumerator;
id_match_t match, best;
+ chunk_t encoding;
if (subject->get_type(subject) == ID_KEY_ID)
{
- if (chunk_equals(this->hash, subject->get_encoding(subject)))
+ encoding = subject->get_encoding(subject);
+
+ if (chunk_equals(this->hash, encoding))
+ {
+ return ID_MATCH_PERFECT;
+ }
+ if (this->subjectKeyIdentifier.len &&
+ chunk_equals(this->subjectKeyIdentifier, encoding))
+ {
+ return ID_MATCH_PERFECT;
+ }
+ if (this->pubkey &&
+ this->pubkey->has_fingerprint(this->pubkey, encoding))
{
return ID_MATCH_PERFECT;
}
@@ -756,6 +778,38 @@ static bool parse_extensions(private_openssl_x509_t *this)
}
/**
+ * Parse ExtendedKeyUsage
+ */
+static void parse_extKeyUsage(private_openssl_x509_t *this)
+{
+ EXTENDED_KEY_USAGE *usage;
+ int i;
+
+ usage = X509_get_ext_d2i(this->x509, NID_ext_key_usage, NULL, NULL);
+ if (usage)
+ {
+ for (i = 0; i < sk_ASN1_OBJECT_num(usage); i++)
+ {
+ switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(usage, i)))
+ {
+ case NID_server_auth:
+ this->flags |= X509_SERVER_AUTH;
+ break;
+ case NID_client_auth:
+ this->flags |= X509_CLIENT_AUTH;
+ break;
+ case NID_OCSP_sign:
+ this->flags |= X509_OCSP_SIGNER;
+ break;
+ default:
+ break;
+ }
+ }
+ sk_ASN1_OBJECT_pop_free(usage, ASN1_OBJECT_free);
+ }
+}
+
+/**
* Parse a DER encoded x509 certificate
*/
static bool parse_certificate(private_openssl_x509_t *this)
@@ -814,6 +868,7 @@ static bool parse_certificate(private_openssl_x509_t *this)
{
return TRUE;
}
+ parse_extKeyUsage(this);
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
if (!hasher)