aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2017-09-23 10:01:57 +0200
committerTobias Brunner <tobias@strongswan.org>2017-11-08 16:48:10 +0100
commit51dd2fd2db1ad3e10a20344e8025c5139455b944 (patch)
tree8722517f3419ca62fef6dbd0a19798d59db9b525 /src/libstrongswan
parent5ae3f5cea86fde54d4f52c7da93432992fbc06e3 (diff)
downloadstrongswan-51dd2fd2db1ad3e10a20344e8025c5139455b944.tar.bz2
strongswan-51dd2fd2db1ad3e10a20344e8025c5139455b944.tar.xz
openssl: Add support for creating RSASSA-PSS signatures
Diffstat (limited to 'src/libstrongswan')
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c3
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c134
2 files changed, 132 insertions, 5 deletions
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index 2f05b2b3d..163ce30f9 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -624,6 +624,9 @@ METHOD(plugin_t, get_features, int,
/* signature/encryption schemes */
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS),
+#endif
#ifndef OPENSSL_NO_SHA1
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
index 234f559fe..401a51a0b 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
@@ -20,9 +20,11 @@
#include "openssl_rsa_private_key.h"
#include "openssl_rsa_public_key.h"
+#include "openssl_hasher.h"
#include "openssl_util.h"
#include <utils/debug.h>
+#include <credentials/keys/signature_params.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
@@ -70,8 +72,126 @@ struct private_openssl_rsa_private_key_t {
/* implemented in rsa public key */
bool openssl_rsa_fingerprint(RSA *rsa, cred_encoding_type_t type, chunk_t *fp);
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+
+/**
+ * Build RSA signature
+ */
+static bool build_signature(private_openssl_rsa_private_key_t *this,
+ const EVP_MD *md, rsa_pss_params_t *pss,
+ chunk_t data, chunk_t *sig)
+{
+ EVP_PKEY_CTX *pctx = NULL;
+ EVP_MD_CTX *mctx = NULL;
+ EVP_PKEY *key;
+ bool success = FALSE;
+
+ mctx = EVP_MD_CTX_create();
+ key = EVP_PKEY_new();
+ if (!mctx || !key)
+ {
+ goto error;
+ }
+ if (!EVP_PKEY_set1_RSA(key, this->rsa))
+ {
+ goto error;
+ }
+ if (EVP_DigestSignInit(mctx, &pctx, md, NULL, key) <= 0)
+ {
+ goto error;
+ }
+ if (pss)
+ {
+ const EVP_MD *mgf1md = openssl_get_md(pss->mgf1_hash);
+ int slen = EVP_MD_size(md);
+ if (pss->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
+ {
+ slen = pss->salt_len;
+ }
+ if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
+ EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, slen) <= 0 ||
+ EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md) <= 0)
+ {
+ goto error;
+ }
+ }
+ if (EVP_DigestSignUpdate(mctx, data.ptr, data.len) <= 0)
+ {
+ goto error;
+ }
+ success = (EVP_DigestSignFinal(mctx, sig->ptr, &sig->len) == 1);
+
+error:
+ if (key)
+ {
+ EVP_PKEY_free(key);
+ }
+ if (mctx)
+ {
+ EVP_MD_CTX_destroy(mctx);
+ }
+ return success;
+}
+
/**
- * Build an EMPSA PKCS1 signature described in PKCS#1
+ * Build an EMSA PKCS1 signature described in PKCS#1
+ */
+static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this,
+ int type, chunk_t data, chunk_t *sig)
+{
+ const EVP_MD *md;
+
+ *sig = chunk_alloc(RSA_size(this->rsa));
+
+ if (type == NID_undef)
+ {
+ if (RSA_private_encrypt(data.len, data.ptr, sig->ptr, this->rsa,
+ RSA_PKCS1_PADDING) == sig->len)
+ {
+ return TRUE;
+ }
+ }
+ else
+ {
+ md = EVP_get_digestbynid(type);
+ if (md && build_signature(this, md, NULL, data, sig))
+ {
+ return TRUE;
+ }
+ }
+ chunk_free(sig);
+ return FALSE;
+}
+
+/**
+ * Build an EMSA PSS signature described in PKCS#1
+ */
+static bool build_emsa_pss_signature(private_openssl_rsa_private_key_t *this,
+ rsa_pss_params_t *params, chunk_t data,
+ chunk_t *sig)
+{
+ const EVP_MD *md;
+
+ if (!params)
+ {
+ return FALSE;
+ }
+
+ *sig = chunk_alloc(RSA_size(this->rsa));
+
+ md = openssl_get_md(params->hash);
+ if (md && build_signature(this, md, params, data, sig))
+ {
+ return TRUE;
+ }
+ chunk_free(sig);
+ return FALSE;
+}
+
+#else /* OPENSSL_VERSION_NUMBER < 1.0 */
+
+/**
+ * Build an EMSA PKCS1 signature described in PKCS#1
*/
static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this,
int type, chunk_t data, chunk_t *sig)
@@ -90,15 +210,15 @@ static bool build_emsa_pkcs1_signature(private_openssl_rsa_private_key_t *this,
}
else
{
- EVP_MD_CTX *ctx;
- EVP_PKEY *key;
+ EVP_MD_CTX *ctx = NULL;
+ EVP_PKEY *key = NULL;
const EVP_MD *hasher;
u_int len;
hasher = EVP_get_digestbynid(type);
if (!hasher)
{
- return FALSE;
+ goto error;
}
ctx = EVP_MD_CTX_create();
@@ -140,7 +260,7 @@ error:
}
return success;
}
-
+#endif /* OPENSSL_VERSION_NUMBER < 1.0 */
METHOD(private_key_t, get_type, key_type_t,
private_openssl_rsa_private_key_t *this)
@@ -168,6 +288,10 @@ METHOD(private_key_t, sign, bool,
return build_emsa_pkcs1_signature(this, NID_sha1, data, signature);
case SIGN_RSA_EMSA_PKCS1_MD5:
return build_emsa_pkcs1_signature(this, NID_md5, data, signature);
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ case SIGN_RSA_EMSA_PSS:
+ return build_emsa_pss_signature(this, params, data, signature);
+#endif
default:
DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
signature_scheme_names, scheme);