summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins')
-rw-r--r--src/libstrongswan/plugins/acert/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/aes/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/aesni/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/af_alg/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/agent/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/agent/agent_private_key.c2
-rw-r--r--src/libstrongswan/plugins/bliss/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_private_key.c2
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_public_key.c2
-rw-r--r--src/libstrongswan/plugins/bliss/tests/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c14
-rw-r--r--src/libstrongswan/plugins/blowfish/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/ccm/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/chapoly/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/cmac/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/constraints/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/ctr/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/curl/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/curve25519/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/curve25519/curve25519_private_key.c2
-rw-r--r--src/libstrongswan/plugins/curve25519/curve25519_public_key.c2
-rw-r--r--src/libstrongswan/plugins/des/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/dnskey/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/files/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/fips_prf/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/gcm/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/gcrypt/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_dh.c6
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_dh.h6
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c22
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c229
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c75
-rw-r--r--src/libstrongswan/plugins/gmp/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c11
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h5
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_plugin.c15
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c232
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c128
-rw-r--r--src/libstrongswan/plugins/hmac/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/keychain/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/ldap/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/md4/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/md5/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/mgf1/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/mgf1/mgf1_plugin.c4
-rw-r--r--src/libstrongswan/plugins/mgf1/mgf1_xof.c8
-rw-r--r--src/libstrongswan/plugins/mysql/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/newhope/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/newhope/tests/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/nonce/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/ntru/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crl.c111
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c5
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h5
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.c15
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.h3
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_public_key.c2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.c22
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_hasher.h14
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_pkcs7.c2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c158
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c512
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h3
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c146
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_sha1_prf.c1
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_x509.c93
-rw-r--r--src/libstrongswan/plugins/padlock/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/pem/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/pem/pem_encoder.c2
-rw-r--r--src/libstrongswan/plugins/pgp/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/pgp/pgp_builder.c20
-rw-r--r--src/libstrongswan/plugins/pgp/pgp_cert.c2
-rw-r--r--src/libstrongswan/plugins/pgp/pgp_encoder.c1
-rw-r--r--src/libstrongswan/plugins/pkcs1/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/pkcs1/pkcs1_builder.c7
-rw-r--r--src/libstrongswan/plugins/pkcs11/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_dh.c6
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_dh.h6
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_manager.c23
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c2
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c2
-rw-r--r--src/libstrongswan/plugins/pkcs12/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/pkcs7/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c5
-rw-r--r--src/libstrongswan/plugins/pkcs8/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/pkcs8/pkcs8_builder.c11
-rw-r--r--src/libstrongswan/plugins/plugin_loader.c6
-rw-r--r--src/libstrongswan/plugins/pubkey/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_cert.c11
-rw-r--r--src/libstrongswan/plugins/random/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/rc2/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/rdrand/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/revocation/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/sha1/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/sha2/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/sha3/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/soup/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/sqlite/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/sshkey/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/test_vectors/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/unbound/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/winhttp/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.in2
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.c89
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c97
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.c85
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_request.c4
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.c35
-rw-r--r--src/libstrongswan/plugins/x509/x509_pkcs10.c80
-rw-r--r--src/libstrongswan/plugins/xcbc/Makefile.in2
111 files changed, 1936 insertions, 531 deletions
diff --git a/src/libstrongswan/plugins/acert/Makefile.in b/src/libstrongswan/plugins/acert/Makefile.in
index 10e6fa460..36067a3ff 100644
--- a/src/libstrongswan/plugins/acert/Makefile.in
+++ b/src/libstrongswan/plugins/acert/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in
index 08f965596..d3817e12a 100644
--- a/src/libstrongswan/plugins/aes/Makefile.in
+++ b/src/libstrongswan/plugins/aes/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/aesni/Makefile.in b/src/libstrongswan/plugins/aesni/Makefile.in
index fbc7d9230..fdcfc099e 100644
--- a/src/libstrongswan/plugins/aesni/Makefile.in
+++ b/src/libstrongswan/plugins/aesni/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/af_alg/Makefile.in b/src/libstrongswan/plugins/af_alg/Makefile.in
index 2c45ce5ba..6b4a7fe5f 100644
--- a/src/libstrongswan/plugins/af_alg/Makefile.in
+++ b/src/libstrongswan/plugins/af_alg/Makefile.in
@@ -248,9 +248,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in
index 8183de939..12a44870c 100644
--- a/src/libstrongswan/plugins/agent/Makefile.in
+++ b/src/libstrongswan/plugins/agent/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/agent/agent_private_key.c b/src/libstrongswan/plugins/agent/agent_private_key.c
index bb55c45c0..cf2c5ea85 100644
--- a/src/libstrongswan/plugins/agent/agent_private_key.c
+++ b/src/libstrongswan/plugins/agent/agent_private_key.c
@@ -233,7 +233,7 @@ static bool scheme_supported(private_agent_private_key_t *this,
}
METHOD(private_key_t, sign, bool,
- private_agent_private_key_t *this, signature_scheme_t scheme,
+ private_agent_private_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t *signature)
{
uint32_t len, flags;
diff --git a/src/libstrongswan/plugins/bliss/Makefile.in b/src/libstrongswan/plugins/bliss/Makefile.in
index eb8eaecb0..b98d367f1 100644
--- a/src/libstrongswan/plugins/bliss/Makefile.in
+++ b/src/libstrongswan/plugins/bliss/Makefile.in
@@ -269,9 +269,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/bliss/bliss_private_key.c b/src/libstrongswan/plugins/bliss/bliss_private_key.c
index 25253ed37..964edcd93 100644
--- a/src/libstrongswan/plugins/bliss/bliss_private_key.c
+++ b/src/libstrongswan/plugins/bliss/bliss_private_key.c
@@ -512,7 +512,7 @@ end:
}
METHOD(private_key_t, sign, bool,
- private_bliss_private_key_t *this, signature_scheme_t scheme,
+ private_bliss_private_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t *signature)
{
switch (scheme)
diff --git a/src/libstrongswan/plugins/bliss/bliss_public_key.c b/src/libstrongswan/plugins/bliss/bliss_public_key.c
index f7ddbbfd2..945840cdc 100644
--- a/src/libstrongswan/plugins/bliss/bliss_public_key.c
+++ b/src/libstrongswan/plugins/bliss/bliss_public_key.c
@@ -194,7 +194,7 @@ end:
}
METHOD(public_key_t, verify, bool,
- private_bliss_public_key_t *this, signature_scheme_t scheme,
+ private_bliss_public_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t signature)
{
switch (scheme)
diff --git a/src/libstrongswan/plugins/bliss/tests/Makefile.in b/src/libstrongswan/plugins/bliss/tests/Makefile.in
index a2d56cdd1..015f40a00 100644
--- a/src/libstrongswan/plugins/bliss/tests/Makefile.in
+++ b/src/libstrongswan/plugins/bliss/tests/Makefile.in
@@ -248,9 +248,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c
index a3e4420a9..908ea910d 100644
--- a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c
@@ -118,9 +118,9 @@ START_TEST(test_bliss_sign_all)
/* generate and verify 1000 BLISS signatures */
while (verify_count--)
{
- ck_assert(privkey->sign(privkey, signature_scheme, msg,
+ ck_assert(privkey->sign(privkey, signature_scheme, NULL, msg,
&signature));
- ck_assert(pubkey->verify(pubkey, signature_scheme, msg,
+ ck_assert(pubkey->verify(pubkey, signature_scheme, NULL, msg,
signature));
free(signature.ptr);
}
@@ -134,7 +134,7 @@ START_TEST(test_bliss_sign_fail)
{
private_key_t *privkey;
public_key_t *pubkey;
- chunk_t msg, signature, encoding, fp;
+ chunk_t msg = chunk_empty, signature, encoding, fp;
/* generate non-supported BLISS-II private key */
privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
@@ -172,18 +172,18 @@ START_TEST(test_bliss_sign_fail)
ck_assert(!privkey->decrypt(privkey, ENCRYPT_UNKNOWN, chunk_empty, NULL));
/* sign with invalid signature scheme */
- ck_assert(!privkey->sign(privkey, SIGN_UNKNOWN, msg, &signature));
+ ck_assert(!privkey->sign(privkey, SIGN_UNKNOWN, NULL, msg, &signature));
/* generate valid signature */
msg = chunk_from_str("Hello Dolly!");
- ck_assert(privkey->sign(privkey, SIGN_BLISS_WITH_SHA2_512, msg, &signature));
+ ck_assert(privkey->sign(privkey, SIGN_BLISS_WITH_SHA2_512, NULL, msg, &signature));
/* verify with invalid signature scheme */
- ck_assert(!pubkey->verify(pubkey, SIGN_UNKNOWN, msg, signature));
+ ck_assert(!pubkey->verify(pubkey, SIGN_UNKNOWN, NULL, msg, signature));
/* corrupt signature */
signature.ptr[signature.len - 1] ^= 0x80;
- ck_assert(!pubkey->verify(pubkey, SIGN_BLISS_WITH_SHA2_512, msg, signature));
+ ck_assert(!pubkey->verify(pubkey, SIGN_BLISS_WITH_SHA2_512, NULL, msg, signature));
free(signature.ptr);
privkey->destroy(privkey);
diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in
index 0d091d196..2f122b5a8 100644
--- a/src/libstrongswan/plugins/blowfish/Makefile.in
+++ b/src/libstrongswan/plugins/blowfish/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/ccm/Makefile.in b/src/libstrongswan/plugins/ccm/Makefile.in
index 008407097..07eb457d5 100644
--- a/src/libstrongswan/plugins/ccm/Makefile.in
+++ b/src/libstrongswan/plugins/ccm/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/chapoly/Makefile.in b/src/libstrongswan/plugins/chapoly/Makefile.in
index 0b2998c95..09cbddee7 100644
--- a/src/libstrongswan/plugins/chapoly/Makefile.in
+++ b/src/libstrongswan/plugins/chapoly/Makefile.in
@@ -259,9 +259,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/cmac/Makefile.in b/src/libstrongswan/plugins/cmac/Makefile.in
index 2586d77c4..234a54cc2 100644
--- a/src/libstrongswan/plugins/cmac/Makefile.in
+++ b/src/libstrongswan/plugins/cmac/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/constraints/Makefile.in b/src/libstrongswan/plugins/constraints/Makefile.in
index 25632d745..82f82ca2d 100644
--- a/src/libstrongswan/plugins/constraints/Makefile.in
+++ b/src/libstrongswan/plugins/constraints/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/ctr/Makefile.in b/src/libstrongswan/plugins/ctr/Makefile.in
index 275a76273..7c3012301 100644
--- a/src/libstrongswan/plugins/ctr/Makefile.in
+++ b/src/libstrongswan/plugins/ctr/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in
index 0dbcca895..0928dee1c 100644
--- a/src/libstrongswan/plugins/curl/Makefile.in
+++ b/src/libstrongswan/plugins/curl/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/curve25519/Makefile.in b/src/libstrongswan/plugins/curve25519/Makefile.in
index 21b0e75f7..cb8bb3405 100644
--- a/src/libstrongswan/plugins/curve25519/Makefile.in
+++ b/src/libstrongswan/plugins/curve25519/Makefile.in
@@ -251,9 +251,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/curve25519/curve25519_private_key.c b/src/libstrongswan/plugins/curve25519/curve25519_private_key.c
index 2a7303c4b..878be4ca5 100644
--- a/src/libstrongswan/plugins/curve25519/curve25519_private_key.c
+++ b/src/libstrongswan/plugins/curve25519/curve25519_private_key.c
@@ -63,7 +63,7 @@ METHOD(private_key_t, get_type, key_type_t,
METHOD(private_key_t, sign, bool,
private_curve25519_private_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t *signature)
+ void *params, chunk_t data, chunk_t *signature)
{
uint8_t r[HASH_SIZE_SHA512], k[HASH_SIZE_SHA512], sig[HASH_SIZE_SHA512];
hasher_t *hasher;
diff --git a/src/libstrongswan/plugins/curve25519/curve25519_public_key.c b/src/libstrongswan/plugins/curve25519/curve25519_public_key.c
index d07776354..1d4dec565 100644
--- a/src/libstrongswan/plugins/curve25519/curve25519_public_key.c
+++ b/src/libstrongswan/plugins/curve25519/curve25519_public_key.c
@@ -50,7 +50,7 @@ METHOD(public_key_t, get_type, key_type_t,
METHOD(public_key_t, verify, bool,
private_curve25519_public_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t signature)
+ void *params, chunk_t data, chunk_t signature)
{
hasher_t *hasher;
uint8_t d = 0, k[HASH_SIZE_SHA512], r[32], *sig;
diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in
index 89b279875..5ffa778cd 100644
--- a/src/libstrongswan/plugins/des/Makefile.in
+++ b/src/libstrongswan/plugins/des/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/dnskey/Makefile.in b/src/libstrongswan/plugins/dnskey/Makefile.in
index 385749a11..37799583a 100644
--- a/src/libstrongswan/plugins/dnskey/Makefile.in
+++ b/src/libstrongswan/plugins/dnskey/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/files/Makefile.in b/src/libstrongswan/plugins/files/Makefile.in
index 7708f9551..87b66df04 100644
--- a/src/libstrongswan/plugins/files/Makefile.in
+++ b/src/libstrongswan/plugins/files/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in
index 478ae818e..aa0bd5fa8 100644
--- a/src/libstrongswan/plugins/fips_prf/Makefile.in
+++ b/src/libstrongswan/plugins/fips_prf/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/gcm/Makefile.in b/src/libstrongswan/plugins/gcm/Makefile.in
index 91ea7c673..da118ce57 100644
--- a/src/libstrongswan/plugins/gcm/Makefile.in
+++ b/src/libstrongswan/plugins/gcm/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in
index 2212be0e2..3ed4a910f 100644
--- a/src/libstrongswan/plugins/gcrypt/Makefile.in
+++ b/src/libstrongswan/plugins/gcrypt/Makefile.in
@@ -248,9 +248,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
index cee25ea74..5519125ba 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
@@ -289,11 +289,13 @@ gcrypt_dh_t *gcrypt_dh_create(diffie_hellman_group_t group)
/*
* Described in header.
*/
-gcrypt_dh_t *gcrypt_dh_create_custom(diffie_hellman_group_t group,
- chunk_t g, chunk_t p)
+gcrypt_dh_t *gcrypt_dh_create_custom(diffie_hellman_group_t group, ...)
{
if (group == MODP_CUSTOM)
{
+ chunk_t g, p;
+
+ VA_ARGS_GET(group, g, p);
return create_generic(group, p.len, g, p);
}
return NULL;
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h
index a70958dc4..c6259f7ac 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.h
@@ -48,12 +48,10 @@ gcrypt_dh_t *gcrypt_dh_create(diffie_hellman_group_t group);
* Creates a new gcrypt_dh_t object for MODP_CUSTOM.
*
* @param group MODP_CUSTOM
- * @param g generator
- * @param p prime
+ * @param ... expects generator and prime as chunk_t
* @return gcrypt_dh_t object, NULL if not supported
*/
-gcrypt_dh_t *gcrypt_dh_create_custom(diffie_hellman_group_t group,
- chunk_t g, chunk_t p);
+gcrypt_dh_t *gcrypt_dh_create_custom(diffie_hellman_group_t group, ...);
#endif /** GCRYPT_DH_H_ @}*/
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
index 7ecba8fa9..8a3de1e01 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
@@ -118,6 +118,28 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
PLUGIN_REGISTER(PRIVKEY_GEN, gcrypt_rsa_private_key_gen, FALSE),
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
+ /* signature schemes, private */
+#if GCRYPT_VERSION_NUMBER >= 0x010700
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS),
+#endif
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_224),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_256),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_384),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_512),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
+ /* signature verification schemes */
+#if GCRYPT_VERSION_NUMBER >= 0x010700
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PSS),
+#endif
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_224),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_256),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_384),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_512),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
/* random numbers */
PLUGIN_REGISTER(RNG, gcrypt_rng_create),
PLUGIN_PROVIDE(RNG, RNG_WEAK),
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
index 15b876b3f..c06f43348 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (C) 2017 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * HSR 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
@@ -21,6 +22,7 @@
#include <asn1/oid.h>
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
+#include <credentials/keys/signature_params.h>
typedef struct private_gcrypt_rsa_private_key_t private_gcrypt_rsa_private_key_t;
@@ -147,51 +149,100 @@ static bool sign_raw(private_gcrypt_rsa_private_key_t *this,
}
/**
- * Sign a chunk of data using hashing and PKCS#1 encoding
+ * Sign a chunk of data using hashing and PKCS#1v1.5/EMSA-PSS encoding
*/
static bool sign_pkcs1(private_gcrypt_rsa_private_key_t *this,
- hash_algorithm_t hash_algorithm, char *hash_name,
+ hash_algorithm_t hash_algorithm, rsa_pss_params_t *pss,
chunk_t data, chunk_t *signature)
{
hasher_t *hasher;
chunk_t hash;
gcry_error_t err;
gcry_sexp_t in, out;
- int hash_oid;
+ char *hash_name = enum_to_name(hash_algorithm_short_names, hash_algorithm);
- hash_oid = hasher_algorithm_to_oid(hash_algorithm);
- if (hash_oid == OID_UNKNOWN)
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
+ if (!hasher)
{
+ DBG1(DBG_LIB, "hash algorithm %N not supported",
+ hash_algorithm_names, hash_algorithm);
return FALSE;
}
- hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
- if (!hasher || !hasher->allocate_hash(hasher, data, &hash))
+ if (!hasher->allocate_hash(hasher, data, &hash))
{
- DESTROY_IF(hasher);
+ hasher->destroy(hasher);
return FALSE;
}
hasher->destroy(hasher);
- err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))",
- hash_name, hash.len, hash.ptr);
+ if (pss)
+ {
+ if (pss->salt.len)
+ {
+ err = gcry_sexp_build(&in, NULL,
+ "(data(flags pss)(salt-length %u)"
+ "(random-override %b)(hash %s %b))",
+ pss->salt.len, pss->salt.len, pss->salt.ptr,
+ hash_name, hash.len, hash.ptr);
+ }
+ else
+ {
+ u_int slen = hasher_hash_size(hash_algorithm);
+ if (pss->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
+ {
+ slen = pss->salt_len;
+ }
+ err = gcry_sexp_build(&in, NULL,
+ "(data(flags pss)(salt-length %u)(hash %s %b))",
+ slen, hash_name, hash.len, hash.ptr);
+ }
+ }
+ else
+ {
+ err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))",
+ hash_name, hash.len, hash.ptr);
+ }
chunk_free(&hash);
if (err)
{
- DBG1(DBG_LIB, "building signature S-expression failed: %s", gpg_strerror(err));
+ DBG1(DBG_LIB, "building signature S-expression failed: %s",
+ gpg_strerror(err));
return FALSE;
}
err = gcry_pk_sign(&out, in, this->key);
gcry_sexp_release(in);
if (err)
{
- DBG1(DBG_LIB, "creating pkcs1 signature failed: %s", gpg_strerror(err));
+ DBG1(DBG_LIB, "creating pkcs1 signature failed: %s",
+ gpg_strerror(err));
return FALSE;
}
+
*signature = gcrypt_rsa_find_token(out, "s", this->key);
gcry_sexp_release(out);
return !!signature->len;
}
+#if GCRYPT_VERSION_NUMBER >= 0x010700
+/**
+ * Sign a chunk of data using hashing and EMSA-PSS encoding
+ */
+static bool sign_pss(private_gcrypt_rsa_private_key_t *this,
+ rsa_pss_params_t *params, chunk_t data, chunk_t *signature)
+{
+ if (!params)
+ {
+ return FALSE;
+ }
+ if (params->mgf1_hash != params->hash)
+ {
+ DBG1(DBG_LIB, "unable to use a different MGF1 hash for RSA-PSS");
+ return FALSE;
+ }
+ return sign_pkcs1(this, params->hash, params, data, signature);
+}
+#endif
+
METHOD(private_key_t, get_type, key_type_t,
private_gcrypt_rsa_private_key_t *this)
{
@@ -200,24 +251,28 @@ METHOD(private_key_t, get_type, key_type_t,
METHOD(private_key_t, sign, bool,
private_gcrypt_rsa_private_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t *sig)
+ void *params, chunk_t data, chunk_t *sig)
{
switch (scheme)
{
case SIGN_RSA_EMSA_PKCS1_NULL:
return sign_raw(this, data, sig);
case SIGN_RSA_EMSA_PKCS1_SHA2_224:
- return sign_pkcs1(this, HASH_SHA224, "sha224", data, sig);
+ return sign_pkcs1(this, HASH_SHA224, NULL, data, sig);
case SIGN_RSA_EMSA_PKCS1_SHA2_256:
- return sign_pkcs1(this, HASH_SHA256, "sha256", data, sig);
+ return sign_pkcs1(this, HASH_SHA256, NULL, data, sig);
case SIGN_RSA_EMSA_PKCS1_SHA2_384:
- return sign_pkcs1(this, HASH_SHA384, "sha384", data, sig);
+ return sign_pkcs1(this, HASH_SHA384, NULL, data, sig);
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
- return sign_pkcs1(this, HASH_SHA512, "sha512", data, sig);
+ return sign_pkcs1(this, HASH_SHA512, NULL, data, sig);
case SIGN_RSA_EMSA_PKCS1_SHA1:
- return sign_pkcs1(this, HASH_SHA1, "sha1", data, sig);
+ return sign_pkcs1(this, HASH_SHA1, NULL, data, sig);
case SIGN_RSA_EMSA_PKCS1_MD5:
- return sign_pkcs1(this, HASH_MD5, "md5", data, sig);
+ return sign_pkcs1(this, HASH_MD5, NULL, data, sig);
+#if GCRYPT_VERSION_NUMBER >= 0x010700
+ case SIGN_RSA_EMSA_PSS:
+ return sign_pss(this, params, data, sig);
+#endif
default:
DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
signature_scheme_names, scheme);
@@ -498,16 +553,131 @@ gcrypt_rsa_private_key_t *gcrypt_rsa_private_key_gen(key_type_t type,
}
/**
+ * Recover the primes from n, e and d using the algorithm described in
+ * Appendix C of NIST SP 800-56B.
+ */
+static bool calculate_pqu(chunk_t cn, chunk_t ce, chunk_t cd, chunk_t *cp,
+ chunk_t *cq, chunk_t *cu)
+{
+ gcry_mpi_t n, e, d, p, q, u, k, r, g, y, n1, x, two;
+ int i, t, j;
+ gcry_error_t err;
+ bool success = FALSE;
+
+ n = e = d = p = q = u = k = r = g = y = n1 = x = two = NULL;
+ err = gcry_mpi_scan(&n, GCRYMPI_FMT_USG, cn.ptr, cn.len, NULL)
+ | gcry_mpi_scan(&e, GCRYMPI_FMT_USG, ce.ptr, ce.len, NULL)
+ | gcry_mpi_scan(&d, GCRYMPI_FMT_USG, cd.ptr, cd.len, NULL);
+ if (err)
+ {
+ goto error;
+ }
+ /* k = (d * e) - 1 */
+ k = gcry_mpi_new(gcry_mpi_get_nbits(n));
+ gcry_mpi_mul(k, d, e);
+ gcry_mpi_sub_ui(k, k, 1);
+ if (gcry_mpi_test_bit(k, 0))
+ {
+ goto error;
+ }
+ /* k = 2^t * r, where r is the largest odd integer dividing k, and t >= 1 */
+ r = gcry_mpi_copy(k);
+ for (t = 0; !gcry_mpi_test_bit(r, 0); t++)
+ { /* r = r/2 */
+ gcry_mpi_rshift(r, r, 1);
+ }
+ /* we need n-1 below */
+ n1 = gcry_mpi_new(gcry_mpi_get_nbits(n));
+ gcry_mpi_sub_ui(n1, n, 1);
+ y = gcry_mpi_new(gcry_mpi_get_nbits(n));
+ g = gcry_mpi_new(gcry_mpi_get_nbits(n));
+ x = gcry_mpi_new(gcry_mpi_get_nbits(n));
+ two = gcry_mpi_set_ui(NULL, 2);
+ for (i = 0; i < 100; i++)
+ { /* generate random integer g in [0, n-1] */
+ do
+ {
+ gcry_mpi_randomize(g, gcry_mpi_get_nbits(n), GCRY_WEAK_RANDOM);
+ }
+ while (gcry_mpi_cmp(n, g) <= 0);
+ /* y = g^r mod n */
+ gcry_mpi_powm(y, g, r, n);
+ /* try again if y == 1 or y == n-1 */
+ if (gcry_mpi_cmp_ui(y, 1) == 0 || gcry_mpi_cmp(y, n1) == 0)
+ {
+ continue;
+ }
+ for (j = 0; j < t; j++)
+ { /* x = y^2 mod n */
+ gcry_mpi_powm(x, y, two, n);
+ /* stop if x == 1 */
+ if (gcry_mpi_cmp_ui(x, 1) == 0)
+ {
+ goto done;
+ }
+ /* retry with new g if x = n-1 */
+ if (gcry_mpi_cmp(x, n1) == 0)
+ {
+ break;
+ }
+ /* y = x */
+ gcry_mpi_set(y, x);
+ }
+ }
+ goto error;
+
+done:
+ /* p = gcd(y-1, n) */
+ gcry_mpi_sub_ui(y, y, 1);
+ p = gcry_mpi_new(gcry_mpi_get_nbits(n));
+ gcry_mpi_gcd(p, y, n);
+ /* q = n/p */
+ q = gcry_mpi_new(gcry_mpi_get_nbits(n));
+ gcry_mpi_div(q, NULL, n, p, 0);
+ if (gcry_mpi_cmp(p, q) > 0)
+ { /* gcrypt expects q < p */
+ gcry_mpi_swap(p, q);
+ }
+ /* u = q^-1 mod p */
+ u = gcry_mpi_new(gcry_mpi_get_nbits(n));
+ gcry_mpi_invm(u, p, q);
+ err = gcry_mpi_aprint(GCRYMPI_FMT_USG, &cp->ptr, &cp->len, p)
+ | gcry_mpi_aprint(GCRYMPI_FMT_USG, &cq->ptr, &cq->len, q)
+ | gcry_mpi_aprint(GCRYMPI_FMT_USG, &cu->ptr, &cu->len, u);
+ if (err)
+ {
+ goto error;
+ }
+ success = TRUE;
+
+error:
+ gcry_mpi_release(n);
+ gcry_mpi_release(e);
+ gcry_mpi_release(d);
+ gcry_mpi_release(p);
+ gcry_mpi_release(q);
+ gcry_mpi_release(u);
+ gcry_mpi_release(k);
+ gcry_mpi_release(r);
+ gcry_mpi_release(g);
+ gcry_mpi_release(y);
+ gcry_mpi_release(n1);
+ gcry_mpi_release(x);
+ gcry_mpi_release(two);
+ return success;
+}
+
+/**
* See header.
*/
gcrypt_rsa_private_key_t *gcrypt_rsa_private_key_load(key_type_t type,
va_list args)
{
private_gcrypt_rsa_private_key_t *this;
- chunk_t n, e, d, p, q, u;
+ chunk_t n, e, d, p, q, u, np, nq, nu;
gcry_error_t err;
- n = e = d = p = q = u = chunk_empty;
+ n = e = d = p = q = u = np = nq = nu = chunk_empty;
while (TRUE)
{
switch (va_arg(args, builder_part_t))
@@ -543,12 +713,25 @@ gcrypt_rsa_private_key_t *gcrypt_rsa_private_key_load(key_type_t type,
}
break;
}
-
+ if (!p.len || !q.len || !u.len)
+ {
+ if (!calculate_pqu(n, e, d, &np, &nq, &nu))
+ {
+ return NULL;
+ }
+ p = np;
+ q = nq;
+ u = nu;
+ }
this = create_empty();
err = gcry_sexp_build(&this->key, NULL,
"(private-key(rsa(n %b)(e %b)(d %b)(p %b)(q %b)(u %b)))",
n.len, n.ptr, e.len, e.ptr, d.len, d.ptr,
p.len, p.ptr, q.len, q.ptr, u.len, u.ptr);
+
+ chunk_clear(&np);
+ chunk_clear(&nq);
+ chunk_clear(&nu);
if (err)
{
DBG1(DBG_LIB, "loading private key failed: %s", gpg_strerror(err));
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
index 90829e052..9e2ac1287 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
@@ -1,6 +1,7 @@
/*
+ * Copyright (C) 2017 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * HSR 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
@@ -22,6 +23,7 @@
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
#include <crypto/hashers/hasher.h>
+#include <credentials/keys/signature_params.h>
typedef struct private_gcrypt_rsa_public_key_t private_gcrypt_rsa_public_key_t;
@@ -109,27 +111,48 @@ static bool verify_raw(private_gcrypt_rsa_public_key_t *this,
}
/**
- * Verification of an EMSA PKCS1 signature described in PKCS#1
+ * Verification of an EMSA PKCS1v1.5 / EMSA-PSS signature described in PKCS#1
*/
static bool verify_pkcs1(private_gcrypt_rsa_public_key_t *this,
- hash_algorithm_t algorithm, char *hash_name,
+ hash_algorithm_t algorithm, rsa_pss_params_t *pss,
chunk_t data, chunk_t signature)
{
hasher_t *hasher;
chunk_t hash;
gcry_error_t err;
gcry_sexp_t in, sig;
+ char *hash_name = enum_to_name(hash_algorithm_short_names, algorithm);
hasher = lib->crypto->create_hasher(lib->crypto, algorithm);
- if (!hasher || !hasher->allocate_hash(hasher, data, &hash))
+ if (!hasher)
{
- DESTROY_IF(hasher);
+ DBG1(DBG_LIB, "hash algorithm %N not supported",
+ hash_algorithm_names, algorithm);
+ return FALSE;
+ }
+ if (!hasher->allocate_hash(hasher, data, &hash))
+ {
+ hasher->destroy(hasher);
return FALSE;
}
hasher->destroy(hasher);
- err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))",
- hash_name, hash.len, hash.ptr);
+ if (pss)
+ {
+ u_int slen = hasher_hash_size(algorithm);
+ if (pss->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
+ {
+ slen = pss->salt_len;
+ }
+ err = gcry_sexp_build(&in, NULL,
+ "(data(flags pss)(salt-length %u)(hash %s %b))",
+ slen, hash_name, hash.len, hash.ptr);
+ }
+ else
+ {
+ err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(hash %s %b))",
+ hash_name, hash.len, hash.ptr);
+ }
chunk_free(&hash);
if (err)
{
@@ -159,6 +182,26 @@ static bool verify_pkcs1(private_gcrypt_rsa_public_key_t *this,
return TRUE;
}
+#if GCRYPT_VERSION_NUMBER >= 0x010700
+/**
+ * Verification of an EMSA-PSS signature described in PKCS#1
+ */
+static bool verify_pss(private_gcrypt_rsa_public_key_t *this,
+ rsa_pss_params_t *params, chunk_t data, chunk_t sig)
+{
+ if (!params)
+ {
+ return FALSE;
+ }
+ if (params->mgf1_hash != params->hash)
+ {
+ DBG1(DBG_LIB, "unable to use a different MGF1 hash for RSA-PSS");
+ return FALSE;
+ }
+ return verify_pkcs1(this, params->hash, params, data, sig);
+}
+#endif
+
METHOD(public_key_t, get_type, key_type_t,
private_gcrypt_rsa_public_key_t *this)
{
@@ -167,24 +210,28 @@ METHOD(public_key_t, get_type, key_type_t,
METHOD(public_key_t, verify, bool,
private_gcrypt_rsa_public_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t signature)
+ void *params, chunk_t data, chunk_t signature)
{
switch (scheme)
{
case SIGN_RSA_EMSA_PKCS1_NULL:
return verify_raw(this, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_224:
- return verify_pkcs1(this, HASH_SHA224, "sha224", data, signature);
+ return verify_pkcs1(this, HASH_SHA224, NULL, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_256:
- return verify_pkcs1(this, HASH_SHA256, "sha256", data, signature);
+ return verify_pkcs1(this, HASH_SHA256, NULL, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_384:
- return verify_pkcs1(this, HASH_SHA384, "sha384", data, signature);
+ return verify_pkcs1(this, HASH_SHA384, NULL, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA2_512:
- return verify_pkcs1(this, HASH_SHA512, "sha512", data, signature);
+ return verify_pkcs1(this, HASH_SHA512, NULL, data, signature);
case SIGN_RSA_EMSA_PKCS1_SHA1:
- return verify_pkcs1(this, HASH_SHA1, "sha1", data, signature);
+ return verify_pkcs1(this, HASH_SHA1, NULL, data, signature);
case SIGN_RSA_EMSA_PKCS1_MD5:
- return verify_pkcs1(this, HASH_MD5, "md5", data, signature);
+ return verify_pkcs1(this, HASH_MD5, NULL, data, signature);
+#if GCRYPT_VERSION_NUMBER >= 0x010700
+ case SIGN_RSA_EMSA_PSS:
+ return verify_pss(this, params, data, signature);
+#endif
default:
DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
signature_scheme_names, scheme);
diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in
index 39a2bcabb..11aef42f0 100644
--- a/src/libstrongswan/plugins/gmp/Makefile.in
+++ b/src/libstrongswan/plugins/gmp/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
index b7ee94ee0..b01adfe01 100644
--- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
+++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
@@ -272,7 +272,7 @@ static gmp_diffie_hellman_t *create_generic(diffie_hellman_group_t group,
}
/*
- * Described in header.
+ * Described in header
*/
gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group)
{
@@ -287,12 +287,17 @@ gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group)
params->generator, params->prime);
}
-
+/*
+ * Described in header
+ */
gmp_diffie_hellman_t *gmp_diffie_hellman_create_custom(
- diffie_hellman_group_t group, chunk_t g, chunk_t p)
+ diffie_hellman_group_t group, ...)
{
if (group == MODP_CUSTOM)
{
+ chunk_t g, p;
+
+ VA_ARGS_GET(group, g, p);
return create_generic(MODP_CUSTOM, p.len, g, p);
}
return NULL;
diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h
index 6d73c0863..a8cde7bca 100644
--- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h
+++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.h
@@ -49,12 +49,11 @@ gmp_diffie_hellman_t *gmp_diffie_hellman_create(diffie_hellman_group_t group);
* Creates a new gmp_diffie_hellman_t object for MODP_CUSTOM.
*
* @param group MODP_CUSTOM
- * @param g generator
- * @param p prime
+ * @param ... expects generator and prime as chunk_t
* @return gmp_diffie_hellman_t object, NULL if not supported
*/
gmp_diffie_hellman_t *gmp_diffie_hellman_create_custom(
- diffie_hellman_group_t group, chunk_t g, chunk_t p);
+ diffie_hellman_group_t group, ...);
#endif /** GMP_DIFFIE_HELLMAN_H_ @}*/
diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.c b/src/libstrongswan/plugins/gmp/gmp_plugin.c
index c75975301..700e29bf6 100644
--- a/src/libstrongswan/plugins/gmp/gmp_plugin.c
+++ b/src/libstrongswan/plugins/gmp/gmp_plugin.c
@@ -79,6 +79,14 @@ METHOD(plugin_t, get_features, int,
PLUGIN_REGISTER(PUBKEY, gmp_rsa_public_key_load, TRUE),
PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
/* signature schemes, private */
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS),
+ PLUGIN_SDEPEND(HASHER, HASH_SHA1),
+ PLUGIN_SDEPEND(HASHER, HASH_SHA256),
+ PLUGIN_SDEPEND(HASHER, HASH_SHA512),
+ PLUGIN_SDEPEND(RNG, RNG_STRONG),
+ PLUGIN_SDEPEND(XOF, XOF_MGF1_SHA1),
+ PLUGIN_SDEPEND(XOF, XOF_MGF1_SHA256),
+ PLUGIN_SDEPEND(XOF, XOF_MGF1_SHA512),
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_224),
PLUGIN_DEPENDS(HASHER, HASH_SHA224),
@@ -101,6 +109,13 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
PLUGIN_DEPENDS(HASHER, HASH_MD5),
/* signature verification schemes */
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PSS),
+ PLUGIN_SDEPEND(HASHER, HASH_SHA1),
+ PLUGIN_SDEPEND(HASHER, HASH_SHA256),
+ PLUGIN_SDEPEND(HASHER, HASH_SHA512),
+ PLUGIN_SDEPEND(XOF, XOF_MGF1_SHA1),
+ PLUGIN_SDEPEND(XOF, XOF_MGF1_SHA256),
+ PLUGIN_SDEPEND(XOF, XOF_MGF1_SHA512),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_224),
PLUGIN_DEPENDS(HASHER, HASH_SHA224),
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
index 21b420866..aca232c86 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2017 Tobias Brunner
* Copyright (C) 2005 Jan Hutter
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2012 Andreas Steffen
@@ -27,6 +28,7 @@
#include <asn1/oid.h>
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
+#include <credentials/keys/signature_params.h>
#ifdef HAVE_MPZ_POWM_SEC
# undef mpz_powm
@@ -333,6 +335,120 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
return TRUE;
}
+/**
+ * Build a signature using the PKCS#1 EMSA PSS scheme
+ */
+static bool build_emsa_pss_signature(private_gmp_rsa_private_key_t *this,
+ rsa_pss_params_t *params, chunk_t data,
+ chunk_t *signature)
+{
+ ext_out_function_t xof;
+ hasher_t *hasher = NULL;
+ rng_t *rng = NULL;
+ xof_t *mgf = NULL;
+ chunk_t hash, salt = chunk_empty, m, ps, db, dbmask, em;
+ size_t embits, emlen, maskbits;
+ bool success = FALSE;
+
+ if (!params)
+ {
+ return FALSE;
+ }
+ xof = xof_mgf1_from_hash_algorithm(params->mgf1_hash);
+ if (xof == XOF_UNDEFINED)
+ {
+ DBG1(DBG_LIB, "%N is not supported for MGF1", hash_algorithm_names,
+ params->mgf1_hash);
+ return FALSE;
+ }
+ /* emBits = modBits - 1 */
+ embits = mpz_sizeinbase(this->n, 2) - 1;
+ /* emLen = ceil(emBits/8) */
+ emlen = (embits + 7) / BITS_PER_BYTE;
+ /* mHash = Hash(M) */
+ hasher = lib->crypto->create_hasher(lib->crypto, params->hash);
+ if (!hasher)
+ {
+ DBG1(DBG_LIB, "hash algorithm %N not supported",
+ hash_algorithm_names, params->hash);
+ return FALSE;
+ }
+ hash = chunk_alloca(hasher->get_hash_size(hasher));
+ if (!hasher->get_hash(hasher, data, hash.ptr))
+ {
+ goto error;
+ }
+
+ salt.len = hash.len;
+ if (params->salt.len)
+ {
+ salt = params->salt;
+ }
+ else if (params->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
+ {
+ salt.len = params->salt_len;
+ }
+ if (emlen < (hash.len + salt.len + 2))
+ { /* too long */
+ goto error;
+ }
+ if (salt.len && !params->salt.len)
+ {
+ salt = chunk_alloca(salt.len);
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (!rng || !rng->get_bytes(rng, salt.len, salt.ptr))
+ {
+ goto error;
+ }
+ }
+ /* M' = 0x0000000000000000 | mHash | salt */
+ m = chunk_cata("ccc",
+ chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
+ hash, salt);
+ /* H = Hash(M') */
+ if (!hasher->get_hash(hasher, m, hash.ptr))
+ {
+ goto error;
+ }
+ /* PS = 00...<padding depending on hash and salt length> */
+ ps = chunk_alloca(emlen - salt.len - hash.len - 2);
+ memset(ps.ptr, 0, ps.len);
+ /* DB = PS | 0x01 | salt */
+ db = chunk_cata("ccc", ps, chunk_from_chars(0x01), salt);
+ /* dbMask = MGF(H, emLen - hLen - 1) */
+ mgf = lib->crypto->create_xof(lib->crypto, xof);
+ dbmask = chunk_alloca(db.len);
+ if (!mgf)
+ {
+ DBG1(DBG_LIB, "%N not supported", ext_out_function_names, xof);
+ goto error;
+ }
+ if (!mgf->set_seed(mgf, hash) ||
+ !mgf->get_bytes(mgf, dbmask.len, dbmask.ptr))
+ {
+ goto error;
+ }
+ /* maskedDB = DB xor dbMask */
+ memxor(db.ptr, dbmask.ptr, db.len);
+ /* zero out unused bits */
+ maskbits = (8 * emlen) - embits;
+ if (maskbits)
+ {
+ db.ptr[0] &= (0xff >> maskbits);
+ }
+ /* EM = maskedDB | H | 0xbc */
+ em = chunk_cata("ccc", db, hash, chunk_from_chars(0xbc));
+ /* S = RSASP1(K, EM) */
+ *signature = rsasp1(this, em);
+ success = TRUE;
+
+error:
+ DESTROY_IF(hasher);
+ DESTROY_IF(rng);
+ DESTROY_IF(mgf);
+ return success;
+}
+
METHOD(private_key_t, get_type, key_type_t,
private_gmp_rsa_private_key_t *this)
{
@@ -341,7 +457,7 @@ METHOD(private_key_t, get_type, key_type_t,
METHOD(private_key_t, sign, bool,
private_gmp_rsa_private_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t *signature)
+ void *params, chunk_t data, chunk_t *signature)
{
switch (scheme)
{
@@ -367,6 +483,8 @@ METHOD(private_key_t, sign, bool,
return build_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
case SIGN_RSA_EMSA_PKCS1_MD5:
return build_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
+ case SIGN_RSA_EMSA_PSS:
+ return build_emsa_pss_signature(this, params, data, signature);
default:
DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
signature_scheme_names, scheme);
@@ -807,6 +925,82 @@ gmp_rsa_private_key_t *gmp_rsa_private_key_gen(key_type_t type, va_list args)
}
/**
+ * Recover the primes from n, e and d using the algorithm described in
+ * Appendix C of NIST SP 800-56B.
+ */
+static bool calculate_pq(private_gmp_rsa_private_key_t *this)
+{
+ gmp_randstate_t rstate;
+ mpz_t k, r, g, y, n1, x;
+ int i, t, j;
+ bool success = FALSE;
+
+ gmp_randinit_default(rstate);
+ mpz_inits(k, r, g, y, n1, x, NULL);
+ /* k = (d * e) - 1 */
+ mpz_mul(k, *this->d, this->e);
+ mpz_sub_ui(k, k, 1);
+ if (mpz_odd_p(k))
+ {
+ goto error;
+ }
+ /* k = 2^t * r, where r is the largest odd integer dividing k, and t >= 1 */
+ mpz_set(r, k);
+ for (t = 0; !mpz_odd_p(r); t++)
+ { /* r = r/2 */
+ mpz_divexact_ui(r, r, 2);
+ }
+ /* we need n-1 below */
+ mpz_sub_ui(n1, this->n, 1);
+ for (i = 0; i < 100; i++)
+ { /* generate random integer g in [0, n-1] */
+ mpz_urandomm(g, rstate, this->n);
+ /* y = g^r mod n */
+ mpz_powm_sec(y, g, r, this->n);
+ /* try again if y == 1 or y == n-1 */
+ if (mpz_cmp_ui(y, 1) == 0 || mpz_cmp(y, n1) == 0)
+ {
+ continue;
+ }
+ for (j = 0; j < t; j++)
+ { /* x = y^2 mod n */
+ mpz_powm_ui(x, y, 2, this->n);
+ /* stop if x == 1 */
+ if (mpz_cmp_ui(x, 1) == 0)
+ {
+ goto done;
+ }
+ /* retry with new g if x = n-1 */
+ if (mpz_cmp(x, n1) == 0)
+ {
+ break;
+ }
+ /* y = x */
+ mpz_set(y, x);
+ }
+ }
+ goto error;
+
+done:
+ /* p = gcd(y-1, n) */
+ mpz_sub_ui(y, y, 1);
+ mpz_gcd(this->p, y, this->n);
+ /* q = n/p */
+ mpz_divexact(this->q, this->n, this->p);
+ success = TRUE;
+
+error:
+ mpz_clear_sensitive(k);
+ mpz_clear_sensitive(r);
+ mpz_clear_sensitive(g);
+ mpz_clear_sensitive(y);
+ mpz_clear_sensitive(x);
+ mpz_clear(n1);
+ gmp_randclear(rstate);
+ return success;
+}
+
+/**
* See header.
*/
gmp_rsa_private_key_t *gmp_rsa_private_key_load(key_type_t type, va_list args)
@@ -868,9 +1062,30 @@ gmp_rsa_private_key_t *gmp_rsa_private_key_load(key_type_t type, va_list args)
mpz_import(this->n, n.len, 1, 1, 1, 0, n.ptr);
mpz_import(this->e, e.len, 1, 1, 1, 0, e.ptr);
mpz_import(*this->d, d.len, 1, 1, 1, 0, d.ptr);
- mpz_import(this->p, p.len, 1, 1, 1, 0, p.ptr);
- mpz_import(this->q, q.len, 1, 1, 1, 0, q.ptr);
- mpz_import(this->coeff, coeff.len, 1, 1, 1, 0, coeff.ptr);
+ if (p.len)
+ {
+ mpz_import(this->p, p.len, 1, 1, 1, 0, p.ptr);
+ }
+ if (q.len)
+ {
+ mpz_import(this->q, q.len, 1, 1, 1, 0, q.ptr);
+ }
+ if (!p.len && !q.len)
+ { /* p and q missing in key, recalculate from n, e and d */
+ if (!calculate_pq(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ }
+ else if (!p.len)
+ { /* p missing in key, recalculate: p = n / q */
+ mpz_divexact(this->p, this->n, this->q);
+ }
+ else if (!q.len)
+ { /* q missing in key, recalculate: q = n / p */
+ mpz_divexact(this->q, this->n, this->p);
+ }
if (!exp1.len)
{ /* exp1 missing in key, recalculate: exp1 = d mod (p-1) */
mpz_sub_ui(this->exp1, this->p, 1);
@@ -889,6 +1104,14 @@ gmp_rsa_private_key_t *gmp_rsa_private_key_load(key_type_t type, va_list args)
{
mpz_import(this->exp2, exp2.len, 1, 1, 1, 0, exp2.ptr);
}
+ if (!coeff.len)
+ { /* coeff missing in key, recalculate: coeff = q^-1 mod p */
+ mpz_invert(this->coeff, this->q, this->p);
+ }
+ else
+ {
+ mpz_import(this->coeff, coeff.len, 1, 1, 1, 0, coeff.ptr);
+ }
this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
if (check(this) != SUCCESS)
{
@@ -897,4 +1120,3 @@ gmp_rsa_private_key_t *gmp_rsa_private_key_load(key_type_t type, va_list args)
}
return &this->public;
}
-
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
index 065c88903..52bc9fb38 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
@@ -1,7 +1,8 @@
/*
+ * Copyright (C) 2017 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
+ * HSR 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
@@ -27,6 +28,7 @@
#include <asn1/asn1.h>
#include <asn1/asn1_parser.h>
#include <crypto/hashers/hasher.h>
+#include <credentials/keys/signature_params.h>
#ifdef HAVE_MPZ_POWM_SEC
# undef mpz_powm
@@ -126,7 +128,7 @@ static const asn1Object_t digestInfoObjects[] = {
#define DIGEST_INFO_DIGEST 2
/**
- * Verification of an EMPSA PKCS1 signature described in PKCS#1
+ * Verification of an EMSA PKCS1 signature described in PKCS#1
*/
static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
hash_algorithm_t algorithm,
@@ -283,6 +285,124 @@ end:
return success;
}
+/**
+ * Verification of an EMSA PSS signature described in PKCS#1
+ */
+static bool verify_emsa_pss_signature(private_gmp_rsa_public_key_t *this,
+ rsa_pss_params_t *params, chunk_t data,
+ chunk_t signature)
+{
+ ext_out_function_t xof;
+ hasher_t *hasher = NULL;
+ xof_t *mgf = NULL;
+ chunk_t em, hash, salt, db, h, dbmask, m;
+ size_t embits, maskbits;
+ int i;
+ bool success = FALSE;
+
+ if (!params)
+ {
+ return FALSE;
+ }
+ xof = xof_mgf1_from_hash_algorithm(params->mgf1_hash);
+ if (xof == XOF_UNDEFINED)
+ {
+ DBG1(DBG_LIB, "%N is not supported for MGF1", hash_algorithm_names,
+ params->mgf1_hash);
+ return FALSE;
+ }
+ chunk_skip_zero(signature);
+ if (signature.len == 0 || signature.len > this->k)
+ {
+ return FALSE;
+ }
+ /* EM = RSAVP1((n, e), S) */
+ em = rsavp1(this, signature);
+ if (!em.len)
+ {
+ goto error;
+ }
+ /* emBits = modBits - 1 */
+ embits = mpz_sizeinbase(this->n, 2) - 1;
+ /* mHash = Hash(M) */
+ hasher = lib->crypto->create_hasher(lib->crypto, params->hash);
+ if (!hasher)
+ {
+ DBG1(DBG_LIB, "hash algorithm %N not supported",
+ hash_algorithm_names, params->hash);
+ goto error;
+ }
+ hash = chunk_alloca(hasher->get_hash_size(hasher));
+ if (!hasher->get_hash(hasher, data, hash.ptr))
+ {
+ goto error;
+ }
+ /* determine salt length */
+ salt.len = hash.len;
+ if (params->salt_len > RSA_PSS_SALT_LEN_DEFAULT)
+ {
+ salt.len = params->salt_len;
+ }
+ /* verify general structure of EM */
+ maskbits = (8 * em.len) - embits;
+ if (em.len < (hash.len + salt.len + 2) || em.ptr[em.len-1] != 0xbc ||
+ (em.ptr[0] & (0xff << (8-maskbits))))
+ { /* inconsistent */
+ goto error;
+ }
+ /* split EM in maskedDB and H */
+ db = chunk_create(em.ptr, em.len - hash.len - 1);
+ h = chunk_create(em.ptr + db.len, hash.len);
+ /* dbMask = MGF(H, emLen - hLen - 1) */
+ mgf = lib->crypto->create_xof(lib->crypto, xof);
+ if (!mgf)
+ {
+ DBG1(DBG_LIB, "%N not supported", ext_out_function_names, xof);
+ goto error;
+ }
+ dbmask = chunk_alloca(db.len);
+ if (!mgf->set_seed(mgf, h) ||
+ !mgf->get_bytes(mgf, dbmask.len, dbmask.ptr))
+ {
+ DBG1(DBG_LIB, "%N not supported or failed", ext_out_function_names, xof);
+ goto error;
+ }
+ /* DB = maskedDB xor dbMask */
+ memxor(db.ptr, dbmask.ptr, db.len);
+ if (maskbits)
+ {
+ db.ptr[0] &= (0xff >> maskbits);
+ }
+ /* check DB = PS | 0x01 | salt */
+ for (i = 0; i < (db.len - salt.len - 1); i++)
+ {
+ if (db.ptr[i])
+ { /* padding not 0 */
+ goto error;
+ }
+ }
+ if (db.ptr[i++] != 0x01)
+ { /* 0x01 not found */
+ goto error;
+ }
+ salt.ptr = &db.ptr[i];
+ /* M' = 0x0000000000000000 | mHash | salt */
+ m = chunk_cata("ccc",
+ chunk_from_chars(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00),
+ hash, salt);
+ if (!hasher->get_hash(hasher, m, hash.ptr))
+ {
+ goto error;
+ }
+ success = memeq_const(h.ptr, hash.ptr, hash.len);
+
+error:
+ DESTROY_IF(hasher);
+ DESTROY_IF(mgf);
+ free(em.ptr);
+ return success;
+}
+
METHOD(public_key_t, get_type, key_type_t,
private_gmp_rsa_public_key_t *this)
{
@@ -290,7 +410,7 @@ METHOD(public_key_t, get_type, key_type_t,
}
METHOD(public_key_t, verify, bool,
- private_gmp_rsa_public_key_t *this, signature_scheme_t scheme,
+ private_gmp_rsa_public_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t signature)
{
switch (scheme)
@@ -317,6 +437,8 @@ METHOD(public_key_t, verify, bool,
return verify_emsa_pkcs1_signature(this, HASH_SHA1, data, signature);
case SIGN_RSA_EMSA_PKCS1_MD5:
return verify_emsa_pkcs1_signature(this, HASH_MD5, data, signature);
+ case SIGN_RSA_EMSA_PSS:
+ return verify_emsa_pss_signature(this, params, data, signature);
default:
DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
signature_scheme_names, scheme);
diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in
index cddeace7f..8de79663e 100644
--- a/src/libstrongswan/plugins/hmac/Makefile.in
+++ b/src/libstrongswan/plugins/hmac/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/keychain/Makefile.in b/src/libstrongswan/plugins/keychain/Makefile.in
index e072c9225..6573b311d 100644
--- a/src/libstrongswan/plugins/keychain/Makefile.in
+++ b/src/libstrongswan/plugins/keychain/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in
index 229a0cad0..324157bc0 100644
--- a/src/libstrongswan/plugins/ldap/Makefile.in
+++ b/src/libstrongswan/plugins/ldap/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in
index d135c291f..111f53239 100644
--- a/src/libstrongswan/plugins/md4/Makefile.in
+++ b/src/libstrongswan/plugins/md4/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in
index e81213c2a..1a41f73ea 100644
--- a/src/libstrongswan/plugins/md5/Makefile.in
+++ b/src/libstrongswan/plugins/md5/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/mgf1/Makefile.in b/src/libstrongswan/plugins/mgf1/Makefile.in
index 8a2788319..fd69f4042 100644
--- a/src/libstrongswan/plugins/mgf1/Makefile.in
+++ b/src/libstrongswan/plugins/mgf1/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/mgf1/mgf1_plugin.c b/src/libstrongswan/plugins/mgf1/mgf1_plugin.c
index 8df3ac261..a78d2f254 100644
--- a/src/libstrongswan/plugins/mgf1/mgf1_plugin.c
+++ b/src/libstrongswan/plugins/mgf1/mgf1_plugin.c
@@ -44,8 +44,12 @@ METHOD(plugin_t, get_features, int,
PLUGIN_REGISTER(XOF, mgf1_xof_create),
PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA1),
PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA224),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA224),
PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA256),
PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA384),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA384),
PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA512),
PLUGIN_DEPENDS(HASHER, HASH_SHA512),
};
diff --git a/src/libstrongswan/plugins/mgf1/mgf1_xof.c b/src/libstrongswan/plugins/mgf1/mgf1_xof.c
index 0f5fda952..8f5a18f87 100644
--- a/src/libstrongswan/plugins/mgf1/mgf1_xof.c
+++ b/src/libstrongswan/plugins/mgf1/mgf1_xof.c
@@ -244,9 +244,15 @@ mgf1_xof_t *mgf1_xof_create(ext_out_function_t algorithm)
case XOF_MGF1_SHA1:
hash_alg = HASH_SHA1;
break;
+ case XOF_MGF1_SHA224:
+ hash_alg = HASH_SHA224;
+ break;
case XOF_MGF1_SHA256:
hash_alg = HASH_SHA256;
break;
+ case XOF_MGF1_SHA384:
+ hash_alg = HASH_SHA384;
+ break;
case XOF_MGF1_SHA512:
hash_alg = HASH_SHA512;
break;
@@ -261,7 +267,7 @@ mgf1_xof_t *mgf1_xof_create(ext_out_function_t algorithm)
hash_algorithm_names, hash_alg);
return NULL;
}
-
+
INIT(this,
.public = {
.mgf1_interface = {
diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in
index c99e4f806..114507eeb 100644
--- a/src/libstrongswan/plugins/mysql/Makefile.in
+++ b/src/libstrongswan/plugins/mysql/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/newhope/Makefile.in b/src/libstrongswan/plugins/newhope/Makefile.in
index 786337420..81c10d5c9 100644
--- a/src/libstrongswan/plugins/newhope/Makefile.in
+++ b/src/libstrongswan/plugins/newhope/Makefile.in
@@ -253,9 +253,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/newhope/tests/Makefile.in b/src/libstrongswan/plugins/newhope/tests/Makefile.in
index be6ffef28..114035a4a 100644
--- a/src/libstrongswan/plugins/newhope/tests/Makefile.in
+++ b/src/libstrongswan/plugins/newhope/tests/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/nonce/Makefile.in b/src/libstrongswan/plugins/nonce/Makefile.in
index fca8309e5..0e24d4861 100644
--- a/src/libstrongswan/plugins/nonce/Makefile.in
+++ b/src/libstrongswan/plugins/nonce/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/ntru/Makefile.in b/src/libstrongswan/plugins/ntru/Makefile.in
index 2ef9aa8dc..cdfee525b 100644
--- a/src/libstrongswan/plugins/ntru/Makefile.in
+++ b/src/libstrongswan/plugins/ntru/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
index dcf4c2c8a..856055c6a 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.in
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -254,9 +254,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c
index 61cf3e884..88f7a67c2 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crl.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crl.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2017 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -47,14 +50,13 @@
#include <credentials/certificates/x509.h>
#if OPENSSL_VERSION_NUMBER < 0x10100000L
-static inline void X509_CRL_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, const X509_CRL *crl) {
+static inline void X509_CRL_get0_signature(const X509_CRL *crl, ASN1_BIT_STRING **psig, X509_ALGOR **palg) {
if (psig) { *psig = crl->signature; }
if (palg) { *palg = crl->sig_alg; }
}
#define X509_REVOKED_get0_serialNumber(r) ({ (r)->serialNumber; })
#define X509_REVOKED_get0_revocationDate(r) ({ (r)->revocationDate; })
#define X509_CRL_get0_extensions(c) ({ (c)->crl->extensions; })
-#define X509_ALGOR_get0(oid, ppt, ppv, alg) ({ *(oid) = (alg)->algorithm; })
#endif
typedef struct private_openssl_crl_t private_openssl_crl_t;
@@ -85,6 +87,16 @@ struct private_openssl_crl_t {
chunk_t serial;
/**
+ * Number of base CRL (deltaCrlIndicator), if a delta CRL
+ */
+ chunk_t base;
+
+ /**
+ * List of Freshest CRL distribution points
+ */
+ linked_list_t *crl_uris;
+
+ /**
* AuthorityKeyIdentifier of the issuing CA
*/
chunk_t authKeyIdentifier;
@@ -107,7 +119,7 @@ struct private_openssl_crl_t {
/**
* Signature scheme used in this CRL
*/
- signature_scheme_t scheme;
+ signature_params_t *scheme;
/**
* References to this CRL
@@ -140,6 +152,11 @@ typedef struct {
int i;
} crl_enumerator_t;
+/**
+ * from openssl_x509
+ */
+bool openssl_parse_crlDistributionPoints(X509_EXTENSION *ext,
+ linked_list_t *list);
METHOD(enumerator_t, crl_enumerate, bool,
crl_enumerator_t *this, va_list args)
@@ -215,6 +232,26 @@ METHOD(crl_t, get_serial, chunk_t,
return this->serial;
}
+METHOD(crl_t, is_delta_crl, bool,
+ private_openssl_crl_t *this, chunk_t *base_crl)
+{
+ if (this->base.len)
+ {
+ if (base_crl)
+ {
+ *base_crl = this->base;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+METHOD(crl_t, create_delta_crl_uri_enumerator, enumerator_t*,
+ private_openssl_crl_t *this)
+{
+ return this->crl_uris->create_enumerator(this->crl_uris);
+}
+
METHOD(crl_t, get_authKeyIdentifier, chunk_t,
private_openssl_crl_t *this)
{
@@ -246,7 +283,7 @@ METHOD(certificate_t, has_subject_or_issuer, id_match_t,
METHOD(certificate_t, issued_by, bool,
private_openssl_crl_t *this, certificate_t *issuer,
- signature_scheme_t *scheme)
+ signature_params_t **scheme)
{
chunk_t fingerprint, tbs;
public_key_t *key;
@@ -283,23 +320,20 @@ METHOD(certificate_t, issued_by, bool,
return FALSE;
}
}
- if (this->scheme == SIGN_UNKNOWN)
- {
- return FALSE;
- }
/* i2d_re_X509_CRL_tbs() was added with 1.1.0 when X509_CRL became opaque */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
tbs = openssl_i2chunk(re_X509_CRL_tbs, this->crl);
#else
tbs = openssl_i2chunk(X509_CRL_INFO, this->crl->crl);
#endif
- X509_CRL_get0_signature(&sig, NULL, this->crl);
- valid = key->verify(key, this->scheme, tbs, openssl_asn1_str2chunk(sig));
+ X509_CRL_get0_signature(this->crl, &sig, NULL);
+ valid = key->verify(key, this->scheme->scheme, this->scheme->params, tbs,
+ openssl_asn1_str2chunk(sig));
free(tbs.ptr);
key->destroy(key);
if (valid && scheme)
{
- *scheme = this->scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -379,8 +413,12 @@ METHOD(certificate_t, destroy, void,
{
X509_CRL_free(this->crl);
}
+ signature_params_destroy(this->scheme);
+ this->crl_uris->destroy_function(this->crl_uris,
+ (void*)x509_cdp_destroy);
DESTROY_IF(this->issuer);
free(this->authKeyIdentifier.ptr);
+ free(this->base.ptr);
free(this->serial.ptr);
free(this->encoding.ptr);
free(this);
@@ -413,11 +451,12 @@ static private_openssl_crl_t *create_empty()
},
.get_serial = _get_serial,
.get_authKeyIdentifier = _get_authKeyIdentifier,
- .is_delta_crl = (void*)return_false,
- .create_delta_crl_uri_enumerator = (void*)enumerator_create_empty,
+ .is_delta_crl = _is_delta_crl,
+ .create_delta_crl_uri_enumerator = _create_delta_crl_uri_enumerator,
.create_enumerator = _create_enumerator,
},
},
+ .crl_uris = linked_list_create(),
.ref = 1,
);
return this;
@@ -444,21 +483,19 @@ static bool parse_authKeyIdentifier_ext(private_openssl_crl_t *this,
}
/**
- * Parse the crlNumber extension
+ * Quick and dirty INTEGER unwrap for crlNumber/deltaCrlIndicator extensions
*/
-static bool parse_crlNumber_ext(private_openssl_crl_t *this,
- X509_EXTENSION *ext)
+static bool parse_integer_ext(X509_EXTENSION *ext, chunk_t *out)
{
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);
+ free(out->ptr);
+ *out = chunk_clone(chunk);
return TRUE;
}
return FALSE;
@@ -488,7 +525,13 @@ static bool parse_extensions(private_openssl_crl_t *this)
ok = parse_authKeyIdentifier_ext(this, ext);
break;
case NID_crl_number:
- ok = parse_crlNumber_ext(this, ext);
+ ok = parse_integer_ext(ext, &this->serial);
+ break;
+ case NID_delta_crl:
+ ok = parse_integer_ext(ext, &this->base);
+ break;
+ case NID_freshest_crl:
+ ok = openssl_parse_crlDistributionPoints(ext, this->crl_uris);
break;
case NID_issuing_distribution_point:
/* TODO support of IssuingDistributionPoints */
@@ -520,7 +563,7 @@ static bool parse_extensions(private_openssl_crl_t *this)
static bool parse_crl(private_openssl_crl_t *this)
{
const unsigned char *ptr = this->encoding.ptr;
- ASN1_OBJECT *oid;
+ chunk_t sig_scheme;
X509_ALGOR *alg;
this->crl = d2i_X509_CRL(NULL, &ptr, this->encoding.len);
@@ -529,28 +572,16 @@ static bool parse_crl(private_openssl_crl_t *this)
return FALSE;
}
- X509_CRL_get0_signature(NULL, &alg, this->crl);
- X509_ALGOR_get0(&oid, NULL, NULL, alg);
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- if (!chunk_equals(
- openssl_asn1_obj2chunk(this->crl->crl->sig_alg->algorithm),
- openssl_asn1_obj2chunk(this->crl->sig_alg->algorithm)))
+ X509_CRL_get0_signature(this->crl, NULL, &alg);
+ sig_scheme = openssl_i2chunk(X509_ALGOR, alg);
+ INIT(this->scheme);
+ if (!signature_params_parse(sig_scheme, 0, this->scheme))
{
+ DBG1(DBG_ASN, "unable to parse signature algorithm");
+ free(sig_scheme.ptr);
return FALSE;
}
-#elif 0
- /* FIXME: we currently can't do this if X509_CRL is opaque (>= 1.1.0) as
- * X509_CRL_get0_tbs_sigalg() does not exist and there does not seem to be
- * another easy way to get the algorithm from the tbsCertList of the CRL */
- alg = X509_CRL_get0_tbs_sigalg(this->crl);
- X509_ALGOR_get0(&oid_tbs, NULL, NULL, alg);
- if (!chunk_equals(openssl_asn1_obj2chunk(oid),
- openssl_asn1_obj2chunk(oid_tbs)))
- {
- return FALSE;
- }
-#endif
- this->scheme = signature_scheme_from_oid(openssl_asn1_known_oid(oid));
+ free(sig_scheme.ptr);
this->issuer = openssl_x509_name2id(X509_CRL_get_issuer(this->crl));
if (!this->issuer)
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
index f08dfff7e..8e9c1183f 100644
--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
@@ -193,7 +193,7 @@ METHOD(diffie_hellman_t, destroy, void,
* Described in header.
*/
openssl_diffie_hellman_t *openssl_diffie_hellman_create(
- diffie_hellman_group_t group, chunk_t g, chunk_t p)
+ diffie_hellman_group_t group, ...)
{
private_openssl_diffie_hellman_t *this;
const BIGNUM *privkey;
@@ -225,6 +225,9 @@ openssl_diffie_hellman_t *openssl_diffie_hellman_create(
if (group == MODP_CUSTOM)
{
+ chunk_t g, p;
+
+ VA_ARGS_GET(group, g, p);
if (!DH_set0_pqg(this->dh, BN_bin2bn(p.ptr, p.len, NULL), NULL,
BN_bin2bn(g.ptr, g.len, NULL)))
{
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
index 53dc59c78..5de5520b5 100644
--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.h
@@ -40,12 +40,11 @@ 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
+ * @param ... expects generator and prime as chunk_t 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, chunk_t g, chunk_t p);
+ diffie_hellman_group_t group, ...);
#endif /** OPENSSL_DIFFIE_HELLMAN_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
index 22bbf6dc7..364190758 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
@@ -49,6 +49,11 @@ struct private_openssl_ec_private_key_t {
EC_KEY *ec;
/**
+ * TRUE if the key is from an OpenSSL ENGINE and might not be readable
+ */
+ bool engine;
+
+ /**
* reference count
*/
refcount_t ref;
@@ -146,7 +151,7 @@ static bool build_der_signature(private_openssl_ec_private_key_t *this,
METHOD(private_key_t, sign, bool,
private_openssl_ec_private_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t *signature)
+ void *params, chunk_t data, chunk_t *signature)
{
switch (scheme)
{
@@ -226,6 +231,11 @@ METHOD(private_key_t, get_encoding, bool,
{
u_char *p;
+ if (this->engine)
+ {
+ return FALSE;
+ }
+
switch (type)
{
case PRIVKEY_ASN1_DER:
@@ -307,7 +317,7 @@ static private_openssl_ec_private_key_t *create_empty(void)
/*
* See header.
*/
-private_key_t *openssl_ec_private_key_create(EVP_PKEY *key)
+private_key_t *openssl_ec_private_key_create(EVP_PKEY *key, bool engine)
{
private_openssl_ec_private_key_t *this;
EC_KEY *ec;
@@ -320,6 +330,7 @@ private_key_t *openssl_ec_private_key_create(EVP_PKEY *key)
}
this = create_empty();
this->ec = ec;
+ this->engine = engine;
return &this->public.key;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
index 84314f671..56c59cfc8 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
@@ -67,8 +67,9 @@ openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type,
* Wrap an EVP_PKEY object of type EVP_PKEY_EC
*
* @param key EVP_PKEY_EC key object (adopted)
+ * @param engine whether the key was loaded via an engine
* @return loaded key, NULL on failure
*/
-private_key_t *openssl_ec_private_key_create(EVP_PKEY *key);
+private_key_t *openssl_ec_private_key_create(EVP_PKEY *key, bool engine);
#endif /** OPENSSL_EC_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
index a1e56fc5e..faa940839 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
@@ -151,7 +151,7 @@ METHOD(public_key_t, get_type, key_type_t,
METHOD(public_key_t, verify, bool,
private_openssl_ec_public_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t signature)
+ void *params, chunk_t data, chunk_t signature)
{
switch (scheme)
{
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.c b/src/libstrongswan/plugins/openssl/openssl_hasher.c
index 96ee230c9..eb6c50508 100644
--- a/src/libstrongswan/plugins/openssl/openssl_hasher.c
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.c
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2008-2017 Tobias Brunner
+ * HSR 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
@@ -91,16 +91,24 @@ METHOD(hasher_t, destroy, void,
/*
* Described in header
*/
-openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
+const EVP_MD *openssl_get_md(hash_algorithm_t hash)
{
- private_openssl_hasher_t *this;
- char* name;
+ char *name;
- name = enum_to_name(hash_algorithm_short_names, algo);
+ name = enum_to_name(hash_algorithm_short_names, hash);
if (!name)
{
return NULL;
}
+ return EVP_get_digestbyname(name);
+}
+
+/*
+ * Described in header
+ */
+openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
+{
+ private_openssl_hasher_t *this;
INIT(this,
.public = {
@@ -114,7 +122,7 @@ openssl_hasher_t *openssl_hasher_create(hash_algorithm_t algo)
},
);
- this->hasher = EVP_get_digestbyname(name);
+ this->hasher = openssl_get_md(algo);
if (!this->hasher)
{
/* OpenSSL does not support the requested algo */
diff --git a/src/libstrongswan/plugins/openssl/openssl_hasher.h b/src/libstrongswan/plugins/openssl/openssl_hasher.h
index b03f6891b..66b9b505e 100644
--- a/src/libstrongswan/plugins/openssl/openssl_hasher.h
+++ b/src/libstrongswan/plugins/openssl/openssl_hasher.h
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2008-2017 Tobias Brunner
+ * HSR 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
@@ -25,6 +25,8 @@ typedef struct openssl_hasher_t openssl_hasher_t;
#include <crypto/hashers/hasher.h>
+#include <openssl/evp.h>
+
/**
* Implementation of hashers using OpenSSL.
*/
@@ -37,6 +39,14 @@ struct openssl_hasher_t {
};
/**
+ * Determine EVP_MD for the given hash algorithm
+ *
+ * @param hash hash algorithm
+ * @return EVP_MD or NULL if not found/supported
+ */
+const EVP_MD *openssl_get_md(hash_algorithm_t hash);
+
+/**
* Constructor to create openssl_hasher_t.
*
* @param algo algorithm
diff --git a/src/libstrongswan/plugins/openssl/openssl_pkcs7.c b/src/libstrongswan/plugins/openssl/openssl_pkcs7.c
index 83ac8df5b..f94767cf5 100644
--- a/src/libstrongswan/plugins/openssl/openssl_pkcs7.c
+++ b/src/libstrongswan/plugins/openssl/openssl_pkcs7.c
@@ -256,7 +256,7 @@ static auth_cfg_t *verify_signature(CMS_SignerInfo *si, int hash_oid)
key = cert->get_public_key(cert);
if (key)
{
- if (key->verify(key, signature_scheme_from_oid(hash_oid),
+ if (key->verify(key, signature_scheme_from_oid(hash_oid), NULL,
attrs, sig))
{
found = auth->clone(auth);
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index ab73d718f..8b0a7c5c7 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -301,11 +301,11 @@ static private_key_t *openssl_private_key_load(key_type_t type, va_list args)
{
#ifndef OPENSSL_NO_RSA
case EVP_PKEY_RSA:
- return openssl_rsa_private_key_create(key);
+ return openssl_rsa_private_key_create(key, FALSE);
#endif
#ifndef OPENSSL_NO_ECDSA
case EVP_PKEY_EC:
- return openssl_ec_private_key_create(key);
+ return openssl_ec_private_key_create(key, FALSE);
#endif
default:
EVP_PKEY_free(key);
@@ -316,6 +316,152 @@ static private_key_t *openssl_private_key_load(key_type_t type, va_list args)
return NULL;
}
+#ifndef OPENSSL_NO_ENGINE
+/**
+ * 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", (int)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;
+}
+#endif /* OPENSSL_NO_ENGINE */
+
+/**
+ * Load private key via engine
+ */
+static private_key_t *openssl_private_key_connect(key_type_t type,
+ va_list args)
+{
+#ifndef OPENSSL_NO_ENGINE
+ char *engine_id = NULL;
+ char keyname[BUF_LEN];
+ chunk_t keyid = chunk_empty;;
+ EVP_PKEY *key;
+ ENGINE *engine;
+ int slot = -1;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_PKCS11_KEYID:
+ keyid = va_arg(args, chunk_t);
+ continue;
+ 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;
+ default:
+ return NULL;
+ }
+ break;
+ }
+ if (!keyid.len || keyid.len > 40)
+ {
+ return NULL;
+ }
+
+ 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,
+ "%s.plugins.openssl.engine_id", "pkcs11", lib->ns);
+ }
+ engine = ENGINE_by_id(engine_id);
+ if (!engine)
+ {
+ DBG2(DBG_LIB, "engine '%s' is not available", engine_id);
+ return NULL;
+ }
+ if (!ENGINE_init(engine))
+ {
+ DBG1(DBG_LIB, "failed to initialize engine '%s'", engine_id);
+ ENGINE_free(engine);
+ return NULL;
+ }
+ if (!login(engine, keyid))
+ {
+ DBG1(DBG_LIB, "login to engine '%s' failed", engine_id);
+ ENGINE_free(engine);
+ return 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'", keyname, engine_id);
+ ENGINE_free(engine);
+ return NULL;
+ }
+ ENGINE_free(engine);
+
+ switch (EVP_PKEY_base_id(key))
+ {
+#ifndef OPENSSL_NO_RSA
+ case EVP_PKEY_RSA:
+ return openssl_rsa_private_key_create(key, TRUE);
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ case EVP_PKEY_EC:
+ return openssl_ec_private_key_create(key, TRUE);
+#endif
+ default:
+ EVP_PKEY_free(key);
+ break;
+ }
+#endif /* OPENSSL_NO_ENGINE */
+ return NULL;
+}
+
METHOD(plugin_t, get_name, char*,
private_openssl_plugin_t *this)
{
@@ -469,8 +615,6 @@ METHOD(plugin_t, get_features, int,
/* RSA private/public key loading */
PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_load, TRUE),
PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
- PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_connect, FALSE),
- 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, TRUE),
@@ -480,6 +624,10 @@ 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),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, 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),
@@ -554,6 +702,8 @@ METHOD(plugin_t, get_features, int,
/* generic key loader */
PLUGIN_REGISTER(PRIVKEY, openssl_private_key_load, TRUE),
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
+ PLUGIN_REGISTER(PRIVKEY, openssl_private_key_connect, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
PLUGIN_REGISTER(RNG, openssl_rng_create),
PLUGIN_PROVIDE(RNG, RNG_STRONG),
PLUGIN_PROVIDE(RNG, RNG_WEAK),
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
index 54ecf2542..401a51a0b 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2016 Tobias Brunner
+ * Copyright (C) 2008-2017 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
*
@@ -20,16 +20,15 @@
#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>
#include <openssl/rsa.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif /* OPENSSL_NO_ENGINE */
/**
* Public exponent to use for key generation.
@@ -40,6 +39,7 @@
OPENSSL_KEY_FALLBACK(RSA, key, n, e, d)
OPENSSL_KEY_FALLBACK(RSA, factors, p, q)
OPENSSL_KEY_FALLBACK(RSA, crt_params, dmp1, dmq1, iqmp)
+#define BN_secure_new() BN_new()
#endif
typedef struct private_openssl_rsa_private_key_t private_openssl_rsa_private_key_t;
@@ -72,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 an EMPSA PKCS1 signature described in PKCS#1
+ * 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 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)
@@ -92,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();
@@ -142,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)
@@ -152,7 +270,7 @@ METHOD(private_key_t, get_type, key_type_t,
METHOD(private_key_t, sign, bool,
private_openssl_rsa_private_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t *signature)
+ void *params, chunk_t data, chunk_t *signature)
{
switch (scheme)
{
@@ -170,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);
@@ -386,7 +508,7 @@ error:
/*
* See header
*/
-private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key)
+private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key, bool engine)
{
private_openssl_rsa_private_key_t *this;
RSA *rsa;
@@ -399,9 +521,199 @@ private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key)
}
this = create_empty();
this->rsa = rsa;
+ this->engine = engine;
return &this->public.key;
}
+/**
+ * Recover the primes from n, e and d using the algorithm described in
+ * Appendix C of NIST SP 800-56B.
+ */
+static bool calculate_pq(BIGNUM *n, BIGNUM *e, BIGNUM *d,
+ BIGNUM **p, BIGNUM **q)
+{
+ BN_CTX *ctx;
+ BIGNUM *k, *r, *g, *y, *n1, *x;
+ int i, t, j;
+ bool success = FALSE;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ {
+ return FALSE;
+ }
+ BN_CTX_start(ctx);
+ k = BN_CTX_get(ctx);
+ r = BN_CTX_get(ctx);
+ g = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ n1 = BN_CTX_get(ctx);
+ x = BN_CTX_get(ctx);
+ if (!x)
+ {
+ goto error;
+ }
+ /* k = (d * e) - 1 */
+ if (!BN_mul(k, d, e, ctx) || !BN_sub(k, k, BN_value_one()))
+ {
+ goto error;
+ }
+ /* k must be even */
+ if (BN_is_odd(k))
+ {
+ goto error;
+ }
+ /* k = 2^t * r, where r is the largest odd integer dividing k, and t >= 1 */
+ if (!BN_copy(r, k))
+ {
+ goto error;
+ }
+ for (t = 0; !BN_is_odd(r); t++)
+ { /* r = r/2 */
+ if (!BN_rshift(r, r, 1))
+ {
+ goto error;
+ }
+ }
+ /* we need n-1 below */
+ if (!BN_sub(n1, n, BN_value_one()))
+ {
+ goto error;
+ }
+ for (i = 0; i < 100; i++)
+ { /* generate random integer g in [0, n-1] */
+ if (!BN_pseudo_rand_range(g, n))
+ {
+ goto error;
+ }
+ /* y = g^r mod n */
+ if (!BN_mod_exp(y, g, r, n, ctx))
+ {
+ goto error;
+ }
+ /* try again if y == 1 or y == n-1 */
+ if (BN_is_one(y) || BN_cmp(y, n1) == 0)
+ {
+ continue;
+ }
+ for (j = 0; j < t; j++)
+ { /* x = y^2 mod n */
+ if (!BN_mod_sqr(x, y, n, ctx))
+ {
+ goto error;
+ }
+ /* stop if x == 1 */
+ if (BN_is_one(x))
+ {
+ goto done;
+ }
+ /* retry with new g if x = n-1 */
+ if (BN_cmp(x, n1) == 0)
+ {
+ break;
+ }
+ /* y = x */
+ if (!BN_copy(y, x))
+ {
+ goto error;
+ }
+ }
+ }
+ goto error;
+
+done:
+ /* p = gcd(y-1, n) */
+ if (!BN_sub(y, y, BN_value_one()))
+ {
+ goto error;
+ }
+ *p = BN_secure_new();
+ if (!BN_gcd(*p, y, n, ctx))
+ {
+ BN_clear_free(*p);
+ goto error;
+ }
+ /* q = n/p */
+ *q = BN_secure_new();
+ if (!BN_div(*q, NULL, n, *p, ctx))
+ {
+ BN_clear_free(*p);
+ BN_clear_free(*q);
+ goto error;
+ }
+ success = TRUE;
+
+error:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return success;
+}
+
+/**
+ * Calculates dp = d (mod p-1) or dq = d (mod q-1) for the Chinese remainder
+ * algorithm.
+ */
+static BIGNUM *dmodpq1(BIGNUM *d, BIGNUM *pq)
+{
+ BN_CTX *ctx;
+ BIGNUM *res = NULL, *pq1;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ {
+ return NULL;
+ }
+ BN_CTX_start(ctx);
+ pq1 = BN_CTX_get(ctx);
+ /* p|q - 1 */
+ if (!BN_sub(pq1, pq, BN_value_one()))
+ {
+ goto error;
+ }
+ /* d (mod p|q -1) */
+ res = BN_secure_new();
+ if (!BN_mod(res, d, pq1, ctx))
+ {
+ BN_clear_free(res);
+ res = NULL;
+ goto error;
+ }
+
+error:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return res;
+}
+
+/**
+ * Calculates qinv = q^-1 (mod p) for the Chinese remainder algorithm.
+ */
+static BIGNUM *qinv(BIGNUM *q, BIGNUM *p)
+{
+ BN_CTX *ctx;
+ BIGNUM *res = NULL;
+
+ ctx = BN_CTX_new();
+ if (!ctx)
+ {
+ return NULL;
+ }
+ BN_CTX_start(ctx);
+ /* q^-1 (mod p) */
+ res = BN_secure_new();
+ if (!BN_mod_inverse(res, q, p, ctx))
+ {
+ BN_clear_free(res);
+ res = NULL;
+ goto error;
+ }
+
+error:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return res;
+}
+
/*
* See header
*/
@@ -460,7 +772,7 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
return &this->public;
}
}
- else if (n.ptr && e.ptr && d.ptr && p.ptr && q.ptr && coeff.ptr)
+ else if (n.ptr && e.ptr && d.ptr)
{
BIGNUM *bn_n, *bn_e, *bn_d, *bn_p, *bn_q;
BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
@@ -472,178 +784,58 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
bn_d = BN_bin2bn((const u_char*)d.ptr, d.len, NULL);
if (!RSA_set0_key(this->rsa, bn_n, bn_e, bn_d))
{
- destroy(this);
- return NULL;
+ goto error;
}
- bn_p = BN_bin2bn((const u_char*)p.ptr, p.len, NULL);
- bn_q = BN_bin2bn((const u_char*)q.ptr, q.len, NULL);
+ if (p.ptr && q.ptr)
+ {
+ bn_p = BN_bin2bn((const u_char*)p.ptr, p.len, NULL);
+ bn_q = BN_bin2bn((const u_char*)q.ptr, q.len, NULL);
+ }
+ else
+ {
+ if (!calculate_pq(bn_n, bn_e, bn_d, &bn_p, &bn_q))
+ {
+ goto error;
+ }
+ }
if (!RSA_set0_factors(this->rsa, bn_p, bn_q))
{
- destroy(this);
- return NULL;
+ goto error;
}
if (exp1.ptr)
{
dmp1 = BN_bin2bn((const u_char*)exp1.ptr, exp1.len, NULL);
}
- if (exp2.ptr)
+ else
{
- dmq1 = BN_bin2bn((const u_char*)exp2.ptr, exp2.len, NULL);
+ dmp1 = dmodpq1(bn_d, bn_p);
}
- iqmp = BN_bin2bn((const u_char*)coeff.ptr, coeff.len, NULL);
- if (RSA_set0_crt_params(this->rsa, dmp1, dmq1, iqmp) &&
- RSA_check_key(this->rsa) == 1)
+ if (exp2.ptr)
{
- return &this->public;
+ dmq1 = BN_bin2bn((const u_char*)exp2.ptr, exp2.len, NULL);
}
- }
- destroy(this);
- return NULL;
-}
-
-#ifndef OPENSSL_NO_ENGINE
-/**
- * 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", (int)key.len, key.ptr) >= sizeof(pin))
+ else
{
- continue;
+ dmq1 = dmodpq1(bn_d, bn_q);
}
- if (ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0))
+ if (coeff.ptr)
{
- success = TRUE;
- break;
+ iqmp = BN_bin2bn((const u_char*)coeff.ptr, coeff.len, NULL);
}
else
{
- DBG1(DBG_CFG, "setting PIN on engine failed");
+ iqmp = qinv(bn_q, bn_p);
}
- }
- enumerator->destroy(enumerator);
- id->destroy(id);
- if (!found)
- {
- DBG1(DBG_CFG, "no PIN found for %#B", &keyid);
- }
- return success;
-}
-#endif /* OPENSSL_NO_ENGINE */
-
-/*
- * See header.
- */
-openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
- va_list args)
-{
-#ifndef OPENSSL_NO_ENGINE
- private_openssl_rsa_private_key_t *this;
- char *engine_id = NULL;
- char keyname[64];
- chunk_t keyid = chunk_empty;;
- EVP_PKEY *key;
- ENGINE *engine;
- int slot = -1;
-
- while (TRUE)
- {
- switch (va_arg(args, builder_part_t))
+ if (RSA_set0_crt_params(this->rsa, dmp1, dmq1, iqmp) &&
+ RSA_check_key(this->rsa) == 1)
{
- case BUILD_PKCS11_KEYID:
- keyid = va_arg(args, chunk_t);
- continue;
- 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;
- default:
- return NULL;
+ return &this->public;
}
- break;
- }
- if (!keyid.len || keyid.len > 40)
- {
- return NULL;
- }
-
- 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,
- "%s.plugins.openssl.engine_id", "pkcs11", lib->ns);
- }
- engine = ENGINE_by_id(engine_id);
- if (!engine)
- {
- DBG2(DBG_LIB, "engine '%s' is not available", engine_id);
- return NULL;
- }
- if (!ENGINE_init(engine))
- {
- DBG1(DBG_LIB, "failed to initialize engine '%s'", engine_id);
- ENGINE_free(engine);
- return NULL;
- }
- if (!login(engine, keyid))
- {
- DBG1(DBG_LIB, "login to engine '%s' failed", engine_id);
- ENGINE_free(engine);
- return 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'", keyname, engine_id);
- ENGINE_free(engine);
- return NULL;
- }
- ENGINE_free(engine);
-
- 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 */
+error:
+ destroy(this);
return NULL;
-#endif /* OPENSSL_NO_ENGINE */
}
#endif /* OPENSSL_NO_RSA */
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
index 34ce4c776..783181c1d 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
@@ -67,9 +67,10 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
* Wrap an EVP_PKEY object of type EVP_PKEY_RSA
*
* @param key EVP_PKEY_RSA key object (adopted)
+ * @param engine whether the key was loaded via an engine
* @return loaded key, NULL on failure
*/
-private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key);
+private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key, bool engine);
/**
* Connect to a RSA private key on a smartcard.
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
index d3a644f72..20bf30ae9 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
@@ -1,7 +1,7 @@
/*
+ * Copyright (C) 2008-2017 Tobias Brunner
* Copyright (C) 2009 Martin Willi
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * HSR 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
@@ -19,9 +19,11 @@
#ifndef OPENSSL_NO_RSA
#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>
@@ -54,8 +56,138 @@ struct private_openssl_rsa_public_key_t {
refcount_t ref;
};
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+
+/**
+ * Verify RSA signature
+ */
+static bool verify_signature(private_openssl_rsa_public_key_t *this,
+ const EVP_MD *md, rsa_pss_params_t *pss,
+ chunk_t data, chunk_t signature)
+{
+ EVP_PKEY_CTX *pctx = NULL;
+ EVP_MD_CTX *mctx = NULL;
+ EVP_PKEY *key;
+ int rsa_size = RSA_size(this->rsa);
+ bool valid = FALSE;
+
+ /* OpenSSL expects a signature of exactly RSA size (no leading 0x00) */
+ if (signature.len > rsa_size)
+ {
+ signature = chunk_skip(signature, signature.len - rsa_size);
+ }
+
+ 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_DigestVerifyInit(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_DigestVerifyUpdate(mctx, data.ptr, data.len) <= 0)
+ {
+ goto error;
+ }
+ valid = (EVP_DigestVerifyFinal(mctx, signature.ptr, signature.len) == 1);
+
+error:
+ if (key)
+ {
+ EVP_PKEY_free(key);
+ }
+ if (mctx)
+ {
+ EVP_MD_CTX_destroy(mctx);
+ }
+ return valid;
+}
+
/**
- * Verification of an EMPSA PKCS1 signature described in PKCS#1
+ * Verification of a signature without hashing
+ */
+static bool verify_plain_signature(private_openssl_rsa_public_key_t *this,
+ chunk_t data, chunk_t signature)
+{
+ char *buf;
+ int len, rsa_size = RSA_size(this->rsa);
+ bool valid = FALSE;
+
+ /* OpenSSL expects a signature of exactly RSA size (no leading 0x00) */
+ if (signature.len > rsa_size)
+ {
+ signature = chunk_skip(signature, signature.len - rsa_size);
+ }
+ buf = malloc(rsa_size);
+ len = RSA_public_decrypt(signature.len, signature.ptr, buf, this->rsa,
+ RSA_PKCS1_PADDING);
+ if (len != -1)
+ {
+ valid = chunk_equals_const(data, chunk_create(buf, len));
+ }
+ free(buf);
+ return valid;
+}
+
+/**
+ * Verification of an EMSA PKCS1 signature described in PKCS#1
+ */
+static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this,
+ int type, chunk_t data, chunk_t signature)
+{
+ const EVP_MD *md;
+
+ if (type == NID_undef)
+ {
+ return verify_plain_signature(this, data, signature);
+ }
+ md = EVP_get_digestbynid(type);
+ return md && verify_signature(this, md, NULL, data, signature);
+}
+
+/**
+ * Verification of an EMSA PSS signature described in PKCS#1
+ */
+static bool verify_emsa_pss_signature(private_openssl_rsa_public_key_t *this,
+ rsa_pss_params_t *params, chunk_t data,
+ chunk_t signature)
+{
+ const EVP_MD *md;
+
+ if (!params)
+ {
+ return FALSE;
+ }
+ md = openssl_get_md(params->hash);
+ return md && verify_signature(this, md, params, data, signature);
+}
+
+#else /* OPENSSL_VERSION_NUMBER < 1.0 */
+
+/**
+ * Verification of an EMSA PKCS1 signature described in PKCS#1
*/
static bool verify_emsa_pkcs1_signature(private_openssl_rsa_public_key_t *this,
int type, chunk_t data, chunk_t signature)
@@ -129,6 +261,8 @@ error:
return valid;
}
+#endif /* OPENSSL_VERSION_NUMBER < 1.0 */
+
METHOD(public_key_t, get_type, key_type_t,
private_openssl_rsa_public_key_t *this)
{
@@ -137,7 +271,7 @@ METHOD(public_key_t, get_type, key_type_t,
METHOD(public_key_t, verify, bool,
private_openssl_rsa_public_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t signature)
+ void *params, chunk_t data, chunk_t signature)
{
switch (scheme)
{
@@ -155,6 +289,10 @@ METHOD(public_key_t, verify, bool,
return verify_emsa_pkcs1_signature(this, NID_sha1, data, signature);
case SIGN_RSA_EMSA_PKCS1_MD5:
return verify_emsa_pkcs1_signature(this, NID_md5, data, signature);
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ case SIGN_RSA_EMSA_PSS:
+ return verify_emsa_pss_signature(this, params, data, signature);
+#endif
default:
DBG1(DBG_LIB, "signature scheme %N not supported in RSA",
signature_scheme_names, scheme);
diff --git a/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c
index f6df03f12..3a6d2f193 100644
--- a/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c
+++ b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c
@@ -20,6 +20,7 @@
#include "openssl_sha1_prf.h"
#include <openssl/sha.h>
+#include <crypto/hashers/hasher.h>
typedef struct private_openssl_sha1_prf_t private_openssl_sha1_prf_t;
diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c
index e03a4255d..60c08770b 100644
--- a/src/libstrongswan/plugins/openssl/openssl_x509.c
+++ b/src/libstrongswan/plugins/openssl/openssl_x509.c
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2011 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2011-2017 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
@@ -154,7 +154,7 @@ struct private_openssl_x509_t {
/**
* Signature scheme of the certificate
*/
- signature_scheme_t scheme;
+ signature_params_t *scheme;
/**
* subjectAltNames
@@ -189,16 +189,6 @@ struct private_openssl_x509_t {
};
/**
- * Destroy a CRL URI struct
- */
-static void crl_uri_destroy(x509_cdp_t *this)
-{
- free(this->uri);
- DESTROY_IF(this->issuer);
- free(this);
-}
-
-/**
* Convert a GeneralName to an identification_t.
*/
static identification_t *general_name2id(GENERAL_NAME *name)
@@ -394,7 +384,7 @@ METHOD(certificate_t, has_issuer, id_match_t,
METHOD(certificate_t, issued_by, bool,
private_openssl_x509_t *this, certificate_t *issuer,
- signature_scheme_t *scheme)
+ signature_params_t **scheme)
{
public_key_t *key;
bool valid;
@@ -406,7 +396,8 @@ METHOD(certificate_t, issued_by, bool,
{
if (this->flags & X509_SELF_SIGNED)
{
- return TRUE;
+ valid = TRUE;
+ goto out;
}
}
else
@@ -424,10 +415,6 @@ METHOD(certificate_t, issued_by, bool,
return FALSE;
}
}
- if (this->scheme == SIGN_UNKNOWN)
- {
- return FALSE;
- }
key = issuer->get_public_key(issuer);
if (!key)
{
@@ -440,12 +427,15 @@ METHOD(certificate_t, issued_by, bool,
tbs = openssl_i2chunk(X509_CINF, this->x509->cert_info);
#endif
X509_get0_signature(&sig, NULL, this->x509);
- valid = key->verify(key, this->scheme, tbs, openssl_asn1_str2chunk(sig));
+ valid = key->verify(key, this->scheme->scheme, this->scheme->params, tbs,
+ openssl_asn1_str2chunk(sig));
free(tbs.ptr);
key->destroy(key);
+
+out:
if (valid && scheme)
{
- *scheme = this->scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -538,6 +528,7 @@ METHOD(certificate_t, destroy, void,
{
X509_free(this->x509);
}
+ signature_params_destroy(this->scheme);
DESTROY_IF(this->subject);
DESTROY_IF(this->issuer);
DESTROY_IF(this->pubkey);
@@ -549,7 +540,8 @@ METHOD(certificate_t, destroy, void,
offsetof(identification_t, destroy));
this->issuerAltNames->destroy_offset(this->issuerAltNames,
offsetof(identification_t, destroy));
- this->crl_uris->destroy_function(this->crl_uris, (void*)crl_uri_destroy);
+ this->crl_uris->destroy_function(this->crl_uris,
+ (void*)x509_cdp_destroy);
this->ocsp_uris->destroy_function(this->ocsp_uris, free);
this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
offsetof(traffic_selector_t, destroy));
@@ -739,15 +731,15 @@ static bool parse_extKeyUsage_ext(private_openssl_x509_t *this,
/**
* Parse CRL distribution points
*/
-static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this,
- X509_EXTENSION *ext)
+bool openssl_parse_crlDistributionPoints(X509_EXTENSION *ext,
+ linked_list_t *list)
{
CRL_DIST_POINTS *cdps;
DIST_POINT *cdp;
identification_t *id, *issuer;
x509_cdp_t *entry;
char *uri;
- int i, j, k, point_num, name_num, issuer_num;
+ int i, j, k, point_num, name_num, issuer_num, len;
cdps = X509V3_EXT_d2i(ext);
if (!cdps)
@@ -770,7 +762,12 @@ static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this,
cdp->distpoint->name.fullname, j));
if (id)
{
- if (asprintf(&uri, "%Y", id) > 0)
+ len = asprintf(&uri, "%Y", id);
+ if (!len)
+ {
+ free(uri);
+ }
+ else if (len > 0)
{
if (cdp->CRLissuer)
{
@@ -785,8 +782,7 @@ static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this,
.uri = strdup(uri),
.issuer = issuer,
);
- this->crl_uris->insert_last(
- this->crl_uris, entry);
+ list->insert_last(list, entry);
}
}
free(uri);
@@ -796,7 +792,7 @@ static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this,
INIT(entry,
.uri = uri,
);
- this->crl_uris->insert_last(this->crl_uris, entry);
+ list->insert_last(list, entry);
}
}
id->destroy(id);
@@ -820,7 +816,7 @@ static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this,
AUTHORITY_INFO_ACCESS *infos;
ACCESS_DESCRIPTION *desc;
identification_t *id;
- int i, num;
+ int i, num, len;
char *uri;
infos = X509V3_EXT_d2i(ext);
@@ -839,7 +835,12 @@ static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this,
id = general_name2id(desc->location);
if (id)
{
- if (asprintf(&uri, "%Y", id) > 0)
+ len = asprintf(&uri, "%Y", id);
+ if (!len)
+ {
+ free(uri);
+ }
+ else if (len > 0)
{
this->ocsp_uris->insert_last(this->ocsp_uris, uri);
}
@@ -1025,7 +1026,7 @@ static bool parse_extensions(private_openssl_x509_t *this)
ok = parse_extKeyUsage_ext(this, ext);
break;
case NID_crl_distribution_points:
- ok = parse_crlDistributionPoints_ext(this, ext);
+ ok = openssl_parse_crlDistributionPoints(ext, this->crl_uris);
break;
#ifndef OPENSSL_NO_RFC3779
case NID_sbgp_ipAddrBlock:
@@ -1063,8 +1064,8 @@ static bool parse_certificate(private_openssl_x509_t *this)
{
const unsigned char *ptr = this->encoding.ptr;
hasher_t *hasher;
- chunk_t chunk;
- ASN1_OBJECT *oid, *oid_tbs;
+ chunk_t chunk, sig_scheme, sig_scheme_tbs;
+ ASN1_OBJECT *oid;
X509_ALGOR *alg;
this->x509 = d2i_X509(NULL, &ptr, this->encoding.len);
@@ -1089,6 +1090,10 @@ static bool parse_certificate(private_openssl_x509_t *this)
}
switch (openssl_asn1_known_oid(oid))
{
+ case OID_RSASSA_PSS:
+ /* TODO: we should treat such keys special and use the params as
+ * restrictions regarding the use of this key (or rather the
+ * associated private key) */
case OID_RSA_ENCRYPTION:
this->pubkey = lib->creds->create(lib->creds,
CRED_PUBLIC_KEY, KEY_RSA, BUILD_BLOB_ASN1_DER,
@@ -1119,15 +1124,25 @@ static bool parse_certificate(private_openssl_x509_t *this)
/* while X509_ALGOR_cmp() is declared in the headers of older OpenSSL
* versions, at least on Ubuntu 14.04 it is not actually defined */
X509_get0_signature(NULL, &alg, this->x509);
- X509_ALGOR_get0(&oid, NULL, NULL, alg);
+ sig_scheme = openssl_i2chunk(X509_ALGOR, alg);
alg = X509_get0_tbs_sigalg(this->x509);
- X509_ALGOR_get0(&oid_tbs, NULL, NULL, alg);
- if (!chunk_equals(openssl_asn1_obj2chunk(oid),
- openssl_asn1_obj2chunk(oid_tbs)))
+ sig_scheme_tbs = openssl_i2chunk(X509_ALGOR, alg);
+ if (!chunk_equals(sig_scheme, sig_scheme_tbs))
+ {
+ free(sig_scheme_tbs.ptr);
+ free(sig_scheme.ptr);
+ return FALSE;
+ }
+ free(sig_scheme_tbs.ptr);
+
+ INIT(this->scheme);
+ if (!signature_params_parse(sig_scheme, 0, this->scheme))
{
+ DBG1(DBG_ASN, "unable to parse signature algorithm");
+ free(sig_scheme.ptr);
return FALSE;
}
- this->scheme = signature_scheme_from_oid(openssl_asn1_known_oid(oid));
+ free(sig_scheme.ptr);
if (!parse_extensions(this))
{
diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in
index 101119300..02a022d03 100644
--- a/src/libstrongswan/plugins/padlock/Makefile.in
+++ b/src/libstrongswan/plugins/padlock/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in
index 4b69f9f49..37917d441 100644
--- a/src/libstrongswan/plugins/pem/Makefile.in
+++ b/src/libstrongswan/plugins/pem/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/pem/pem_encoder.c b/src/libstrongswan/plugins/pem/pem_encoder.c
index 76b0b7b40..8c6c5dae7 100644
--- a/src/libstrongswan/plugins/pem/pem_encoder.c
+++ b/src/libstrongswan/plugins/pem/pem_encoder.c
@@ -15,6 +15,8 @@
#include "pem_encoder.h"
+#include <library.h>
+
#define BYTES_PER_LINE 48
/**
diff --git a/src/libstrongswan/plugins/pgp/Makefile.in b/src/libstrongswan/plugins/pgp/Makefile.in
index 8104a2a94..10eb82619 100644
--- a/src/libstrongswan/plugins/pgp/Makefile.in
+++ b/src/libstrongswan/plugins/pgp/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/pgp/pgp_builder.c b/src/libstrongswan/plugins/pgp/pgp_builder.c
index fe0be45d9..e8f5c5ddf 100644
--- a/src/libstrongswan/plugins/pgp/pgp_builder.c
+++ b/src/libstrongswan/plugins/pgp/pgp_builder.c
@@ -116,21 +116,17 @@ static private_key_t *parse_rsa_private_key(chunk_t blob)
BUILD_END);
}
-/**
- * Implementation of private_key_t.sign for encryption-only keys
- */
-static bool sign_not_allowed(private_key_t *this, signature_scheme_t scheme,
- chunk_t data, chunk_t *signature)
+METHOD(private_key_t, sign_not_allowed, bool,
+ private_key_t *this, signature_scheme_t scheme, void *params,
+ chunk_t data, chunk_t *signature)
{
DBG1(DBG_LIB, "signing failed - decryption only key");
return FALSE;
}
-/**
- * Implementation of private_key_t.decrypt for signature-only keys
- */
-static bool decrypt_not_allowed(private_key_t *this, encryption_scheme_t scheme,
- chunk_t crypto, chunk_t *plain)
+METHOD(private_key_t, decrypt_not_allowed, bool,
+ private_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
{
DBG1(DBG_LIB, "decryption failed - signature only key");
return FALSE;
@@ -186,7 +182,7 @@ static private_key_t *parse_private_key(chunk_t blob)
BUILD_BLOB_PGP, packet, BUILD_END);
if (key)
{
- key->sign = sign_not_allowed;
+ key->sign = _sign_not_allowed;
}
return key;
case PGP_PUBKEY_ALG_RSA_SIGN_ONLY:
@@ -194,7 +190,7 @@ static private_key_t *parse_private_key(chunk_t blob)
BUILD_BLOB_PGP, packet, BUILD_END);
if (key)
{
- key->decrypt = decrypt_not_allowed;
+ key->decrypt = _decrypt_not_allowed;
}
return key;
case PGP_PUBKEY_ALG_ECDSA:
diff --git a/src/libstrongswan/plugins/pgp/pgp_cert.c b/src/libstrongswan/plugins/pgp/pgp_cert.c
index 0ffce4cfc..392ef5440 100644
--- a/src/libstrongswan/plugins/pgp/pgp_cert.c
+++ b/src/libstrongswan/plugins/pgp/pgp_cert.c
@@ -114,7 +114,7 @@ METHOD(certificate_t, has_issuer, id_match_t,
}
METHOD(certificate_t, issued_by,bool,
- private_pgp_cert_t *this, certificate_t *issuer, signature_scheme_t *scheme)
+ private_pgp_cert_t *this, certificate_t *issuer, signature_params_t **scheme)
{
/* TODO: check signature blobs for a valid signature */
return FALSE;
diff --git a/src/libstrongswan/plugins/pgp/pgp_encoder.c b/src/libstrongswan/plugins/pgp/pgp_encoder.c
index 100f3ef33..eba936b83 100644
--- a/src/libstrongswan/plugins/pgp/pgp_encoder.c
+++ b/src/libstrongswan/plugins/pgp/pgp_encoder.c
@@ -15,6 +15,7 @@
#include "pgp_encoder.h"
+#include <library.h>
#include <utils/debug.h>
/**
diff --git a/src/libstrongswan/plugins/pkcs1/Makefile.in b/src/libstrongswan/plugins/pkcs1/Makefile.in
index 6f6c6237f..ae24d4085 100644
--- a/src/libstrongswan/plugins/pkcs1/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs1/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
index f64294783..967e501d1 100644
--- a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
+++ b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
@@ -57,8 +57,13 @@ static public_key_t *parse_public_key(chunk_t blob)
int oid = asn1_parse_algorithmIdentifier(object,
parser->get_level(parser)+1, NULL);
- if (oid == OID_RSA_ENCRYPTION || oid == OID_RSAES_OAEP)
+ if (oid == OID_RSA_ENCRYPTION || oid == OID_RSAES_OAEP ||
+ oid == OID_RSASSA_PSS)
{
+ /* TODO: we should parse parameters for PSS and pass them
+ * (and the type), or the complete subjectPublicKeyInfo,
+ * along so we can treat these as restrictions when
+ * generating signatures with the associated private key */
type = KEY_RSA;
}
else if (oid == OID_EC_PUBLICKEY)
diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in
index 7bf33d967..00d5a6a5d 100644
--- a/src/libstrongswan/plugins/pkcs11/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs11/Makefile.in
@@ -249,9 +249,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
index c0033bd8e..b0fa41b6a 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
@@ -415,13 +415,15 @@ static chunk_t ecparams_lookup(diffie_hellman_group_t group)
/**
* Described in header.
*/
-pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group,
- chunk_t g, chunk_t p)
+pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group, ...)
{
switch (group)
{
case MODP_CUSTOM:
{
+ chunk_t g, p;
+
+ VA_ARGS_GET(group, g, p);
return create_modp(group, p.len, g, p);
}
case ECP_192_BIT:
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h
index 2654130c0..1ad58e7a1 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h
@@ -40,12 +40,10 @@ struct pkcs11_dh_t {
* Creates a new pkcs11_dh_t object.
*
* @param group Diffie Hellman group number to use
- * @param g generator in case group is MODP_CUSTOM
- * @param p prime in case group is MODP_CUSTOM
+ * @param ... expects generator and prime as chunk_t if MODP_CUSTOM
* @return pkcs11_dh_t object, NULL if not supported
*/
-pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group,
- chunk_t g, chunk_t p);
+pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group, ...);
#endif /** PKCS11_DH_H_ @}*/
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c
index 31bcb0d25..c7dfe69d7 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c
@@ -164,18 +164,13 @@ static void handle_slot(lib_entry_t *entry, CK_SLOT_ID slot, bool hot)
}
}
-/**
- * Dispatch slot events
- */
-static job_requeue_t dispatch_slot_events(lib_entry_t *entry)
+CALLBACK(dispatch_slot_events, job_requeue_t,
+ lib_entry_t *entry)
{
CK_SLOT_ID slot;
CK_RV rv;
- bool old;
- old = thread_cancelability(TRUE);
rv = entry->lib->f->C_WaitForSlotEvent(0, &slot, NULL);
- thread_cancelability(old);
if (rv == CKR_FUNCTION_NOT_SUPPORTED || rv == CKR_NO_EVENT)
{
DBG1(DBG_CFG, "module '%s' does not support hot-plugging, cancelled",
@@ -195,6 +190,16 @@ static job_requeue_t dispatch_slot_events(lib_entry_t *entry)
return JOB_REQUEUE_DIRECT;
}
+CALLBACK(cancel_events, bool,
+ lib_entry_t *entry)
+{
+ /* it's possible other threads still use the API after this call, but we
+ * have no other way to return from C_WaitForSlotEvent() if we can't cancel
+ * the thread because libraries hold locks they don't release */
+ entry->lib->f->C_Finalize(NULL);
+ return TRUE;
+}
+
/**
* Get the slot list of a library
*/
@@ -377,8 +382,8 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
{
query_slots(entry);
lib->processor->queue_job(lib->processor,
- (job_t*)callback_job_create_with_prio((void*)dispatch_slot_events,
- entry, NULL, (void*)return_false, JOB_PRIO_CRITICAL));
+ (job_t*)callback_job_create_with_prio(dispatch_slot_events,
+ entry, NULL, cancel_events, JOB_PRIO_CRITICAL));
}
enumerator->destroy(enumerator);
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
index 1d1016911..6158f6d25 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
@@ -243,7 +243,7 @@ static bool reauth(private_pkcs11_private_key_t *this,
}
METHOD(private_key_t, sign, bool,
- private_pkcs11_private_key_t *this, signature_scheme_t scheme,
+ private_pkcs11_private_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t *signature)
{
CK_MECHANISM_PTR mechanism;
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
index 384777610..36029fa30 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
@@ -201,7 +201,7 @@ METHOD(public_key_t, get_keysize, int,
}
METHOD(public_key_t, verify, bool,
- private_pkcs11_public_key_t *this, signature_scheme_t scheme,
+ private_pkcs11_public_key_t *this, signature_scheme_t scheme, void *params,
chunk_t data, chunk_t sig)
{
CK_MECHANISM_PTR mechanism;
diff --git a/src/libstrongswan/plugins/pkcs12/Makefile.in b/src/libstrongswan/plugins/pkcs12/Makefile.in
index d25a1af44..6bb1b9a36 100644
--- a/src/libstrongswan/plugins/pkcs12/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs12/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/pkcs7/Makefile.in b/src/libstrongswan/plugins/pkcs7/Makefile.in
index e5698a302..f56df39d1 100644
--- a/src/libstrongswan/plugins/pkcs7/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs7/Makefile.in
@@ -248,9 +248,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c
index 413c3fff5..9b6d3a808 100644
--- a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c
+++ b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c
@@ -227,7 +227,8 @@ METHOD(enumerator_t, enumerate, bool,
if (key)
{
chunk = info->attributes->get_encoding(info->attributes);
- if (key->verify(key, scheme, chunk, info->encrypted_digest))
+ if (key->verify(key, scheme, NULL, chunk,
+ info->encrypted_digest))
{
this->auth = auth->clone(auth);
key->destroy(key);
@@ -563,7 +564,7 @@ static bool generate(private_pkcs7_signed_data_t *this, private_key_t *key,
attributes = pkcs9->get_encoding(pkcs9);
- if (!key->sign(key, scheme, attributes, &encryptedDigest))
+ if (!key->sign(key, scheme, NULL, attributes, &encryptedDigest))
{
free(data.ptr);
return FALSE;
diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.in b/src/libstrongswan/plugins/pkcs8/Makefile.in
index 3ff09f5f2..9c408c443 100644
--- a/src/libstrongswan/plugins/pkcs8/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs8/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c
index beb8866f8..6cd5da4fd 100644
--- a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c
+++ b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c
@@ -63,6 +63,17 @@ static private_key_t *parse_private_key(chunk_t blob)
switch (oid)
{
+ case OID_RSASSA_PSS:
+ /* TODO: parameters associated with such keys should be
+ * treated as restrictions later when signing (the type
+ * itself is already a restriction). However, the
+ * builders currently don't expect any parameters for
+ * RSA keys (we also only pass along the params, not the
+ * exact type, so we'd have to guess that params
+ * indicate RSA/PSS, but they are optional so that won't
+ * work for keys without specific restrictions) */
+ params = chunk_empty;
+ /* fall-through */
case OID_RSA_ENCRYPTION:
type = KEY_RSA;
break;
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
index 42d443b7a..7d0cc88ed 100644
--- a/src/libstrongswan/plugins/plugin_loader.c
+++ b/src/libstrongswan/plugins/plugin_loader.c
@@ -438,7 +438,7 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
}
}
if (lib->settings->get_bool(lib->settings, "%s.dlopen_use_rtld_now",
- lib->ns, FALSE))
+ FALSE, lib->ns))
{
flag = RTLD_NOW;
}
@@ -698,7 +698,6 @@ static bool load_dependencies(private_plugin_loader_t *this,
int level)
{
registered_feature_t *registered, lookup;
- int indent = level * 2;
int i;
/* first entry is provided feature, followed by dependencies */
@@ -741,6 +740,7 @@ static bool load_dependencies(private_plugin_loader_t *this,
#ifndef USE_FUZZING
char *name, *provide, *depend;
+ int indent = level * 2;
name = provided->entry->plugin->get_name(provided->entry->plugin);
provide = plugin_feature_get_string(&provided->feature[0]);
@@ -828,7 +828,6 @@ static void load_provided(private_plugin_loader_t *this,
provided_feature_t *provided,
int level)
{
- int indent = level * 2;
if (provided->loaded || provided->failed)
{
@@ -837,6 +836,7 @@ static void load_provided(private_plugin_loader_t *this,
#ifndef USE_FUZZING
char *name, *provide;
+ int indent = level * 2;
name = provided->entry->plugin->get_name(provided->entry->plugin);
provide = plugin_feature_get_string(provided->feature);
diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in
index 02607958f..ff7501c00 100644
--- a/src/libstrongswan/plugins/pubkey/Makefile.in
+++ b/src/libstrongswan/plugins/pubkey/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.c b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
index 0631a6857..81dad65b7 100644
--- a/src/libstrongswan/plugins/pubkey/pubkey_cert.c
+++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
@@ -137,13 +137,16 @@ METHOD(certificate_t, equals, bool,
METHOD(certificate_t, issued_by, bool,
private_pubkey_cert_t *this, certificate_t *issuer,
- signature_scheme_t *scheme)
+ signature_params_t **scheme)
{
- if (scheme)
+ bool valid = equals(this, issuer);
+ if (valid && scheme)
{
- *scheme = SIGN_UNKNOWN;
+ INIT(*scheme,
+ .scheme = SIGN_UNKNOWN,
+ );
}
- return equals(this, issuer);
+ return valid;
}
METHOD(certificate_t, get_public_key, public_key_t*,
diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in
index 98702d0d3..3a22a6316 100644
--- a/src/libstrongswan/plugins/random/Makefile.in
+++ b/src/libstrongswan/plugins/random/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/rc2/Makefile.in b/src/libstrongswan/plugins/rc2/Makefile.in
index b874e9081..d37c9834d 100644
--- a/src/libstrongswan/plugins/rc2/Makefile.in
+++ b/src/libstrongswan/plugins/rc2/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/rdrand/Makefile.in b/src/libstrongswan/plugins/rdrand/Makefile.in
index 40b1d7644..371e34db8 100644
--- a/src/libstrongswan/plugins/rdrand/Makefile.in
+++ b/src/libstrongswan/plugins/rdrand/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/revocation/Makefile.in b/src/libstrongswan/plugins/revocation/Makefile.in
index 8254c1424..15e91b24a 100644
--- a/src/libstrongswan/plugins/revocation/Makefile.in
+++ b/src/libstrongswan/plugins/revocation/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in
index 0c68798a9..ff0a30462 100644
--- a/src/libstrongswan/plugins/sha1/Makefile.in
+++ b/src/libstrongswan/plugins/sha1/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in
index 109726b6a..81284e137 100644
--- a/src/libstrongswan/plugins/sha2/Makefile.in
+++ b/src/libstrongswan/plugins/sha2/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/sha3/Makefile.in b/src/libstrongswan/plugins/sha3/Makefile.in
index a1f79740b..3ca2f5e24 100644
--- a/src/libstrongswan/plugins/sha3/Makefile.in
+++ b/src/libstrongswan/plugins/sha3/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/soup/Makefile.in b/src/libstrongswan/plugins/soup/Makefile.in
index ceccab7f1..47af2c5fd 100644
--- a/src/libstrongswan/plugins/soup/Makefile.in
+++ b/src/libstrongswan/plugins/soup/Makefile.in
@@ -245,9 +245,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in
index 39d705622..f0649b52a 100644
--- a/src/libstrongswan/plugins/sqlite/Makefile.in
+++ b/src/libstrongswan/plugins/sqlite/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/sshkey/Makefile.in b/src/libstrongswan/plugins/sshkey/Makefile.in
index ded2bf8f1..ac644ec0b 100644
--- a/src/libstrongswan/plugins/sshkey/Makefile.in
+++ b/src/libstrongswan/plugins/sshkey/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in
index b7332d4a7..45879e841 100644
--- a/src/libstrongswan/plugins/test_vectors/Makefile.in
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.in
@@ -265,9 +265,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/unbound/Makefile.in b/src/libstrongswan/plugins/unbound/Makefile.in
index 93159ff17..2a4788ee1 100644
--- a/src/libstrongswan/plugins/unbound/Makefile.in
+++ b/src/libstrongswan/plugins/unbound/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/winhttp/Makefile.in b/src/libstrongswan/plugins/winhttp/Makefile.in
index 91033262d..7cd680095 100644
--- a/src/libstrongswan/plugins/winhttp/Makefile.in
+++ b/src/libstrongswan/plugins/winhttp/Makefile.in
@@ -247,9 +247,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
index 3596d1f85..0f54f8cf0 100644
--- a/src/libstrongswan/plugins/x509/Makefile.in
+++ b/src/libstrongswan/plugins/x509/Makefile.in
@@ -246,9 +246,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@
diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
index ba459288b..7a5a31af7 100644
--- a/src/libstrongswan/plugins/x509/x509_ac.c
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2017 Tobias Brunner
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
* Copyright (C) 2003 Martin Berner, Lukas Suter
* Copyright (C) 2002-2017 Andreas Steffen
@@ -116,9 +117,9 @@ struct private_x509_ac_t {
bool noRevAvail;
/**
- * Signature algorithm
+ * Signature scheme
*/
- int algorithm;
+ signature_params_t *scheme;
/**
* Signature
@@ -425,7 +426,7 @@ static bool parse_certificate(private_x509_ac_t *this)
int objectID;
int type = OID_UNKNOWN;
int extn_oid = OID_UNKNOWN;
- int sig_alg = OID_UNKNOWN;
+ signature_params_t sig_alg = {};
bool success = FALSE;
bool critical;
@@ -476,7 +477,11 @@ static bool parse_certificate(private_x509_ac_t *this)
}
break;
case AC_OBJ_SIG_ALG:
- sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ if (!signature_params_parse(object, level, &sig_alg))
+ {
+ DBG1(DBG_ASN, " unable to parse signature algorithm");
+ goto end;
+ }
break;
case AC_OBJ_SERIAL_NUMBER:
this->serialNumber = chunk_clone(object);
@@ -550,12 +555,15 @@ static bool parse_certificate(private_x509_ac_t *this)
break;
}
case AC_OBJ_ALGORITHM:
- this->algorithm = asn1_parse_algorithmIdentifier(object, level,
- NULL);
- if (this->algorithm != sig_alg)
+ INIT(this->scheme);
+ if (!signature_params_parse(object, level, this->scheme))
+ {
+ DBG1(DBG_ASN, " unable to parse signature algorithm");
+ goto end;
+ }
+ if (!signature_params_equal(this->scheme, &sig_alg))
{
DBG1(DBG_ASN, " signature algorithms do not agree");
- success = FALSE;
goto end;
}
break;
@@ -570,6 +578,7 @@ static bool parse_certificate(private_x509_ac_t *this)
end:
parser->destroy(parser);
+ signature_params_clear(&sig_alg);
return success;
}
@@ -742,13 +751,13 @@ static chunk_t build_extensions(private_x509_ac_t *this)
/**
* build attributeCertificateInfo
*/
-static chunk_t build_attr_cert_info(private_x509_ac_t *this)
+static chunk_t build_attr_cert_info(private_x509_ac_t *this, chunk_t sig_scheme)
{
- return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmm",
+ return asn1_wrap(ASN1_SEQUENCE, "cmmcmmmm",
ASN1_INTEGER_1,
build_holder(this),
build_v2_form(this),
- asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
+ sig_scheme,
asn1_simple_object(ASN1_INTEGER, this->serialNumber),
build_attr_cert_validity(this),
build_attributes(this),
@@ -758,20 +767,39 @@ static chunk_t build_attr_cert_info(private_x509_ac_t *this)
/**
* build an X.509 attribute certificate
*/
-static bool build_ac(private_x509_ac_t *this)
+static bool build_ac(private_x509_ac_t *this, hash_algorithm_t digest_alg)
{
- chunk_t signatureValue, attributeCertificateInfo;
+ chunk_t signatureValue, attributeCertificateInfo, sig_scheme;
+ private_key_t *key = this->signerKey;
- attributeCertificateInfo = build_attr_cert_info(this);
- if (!this->signerKey->sign(this->signerKey, SIGN_RSA_EMSA_PKCS1_SHA1,
- attributeCertificateInfo, &signatureValue))
+ if (!this->scheme)
+ {
+ INIT(this->scheme,
+ .scheme = signature_scheme_from_oid(
+ hasher_signature_algorithm_to_oid(digest_alg,
+ key->get_type(key))),
+ );
+ }
+ if (this->scheme->scheme == SIGN_UNKNOWN)
+ {
+ return FALSE;
+ }
+ if (!signature_params_build(this->scheme, &sig_scheme))
+ {
+ return FALSE;
+ }
+
+ attributeCertificateInfo = build_attr_cert_info(this, sig_scheme);
+ if (!key->sign(key, this->scheme->scheme, this->scheme->params,
+ attributeCertificateInfo, &signatureValue))
{
free(attributeCertificateInfo.ptr);
+ free(sig_scheme.ptr);
return FALSE;
}
this->encoding = asn1_wrap(ASN1_SEQUENCE, "mmm",
attributeCertificateInfo,
- asn1_algorithmIdentifier(OID_SHA1_WITH_RSA),
+ sig_scheme,
asn1_bitstring("m", signatureValue));
return TRUE;
}
@@ -886,10 +914,10 @@ METHOD(certificate_t, has_issuer, id_match_t,
}
METHOD(certificate_t, issued_by, bool,
- private_x509_ac_t *this, certificate_t *issuer, signature_scheme_t *schemep)
+ private_x509_ac_t *this, certificate_t *issuer,
+ signature_params_t **scheme)
{
public_key_t *key;
- signature_scheme_t scheme;
bool valid;
x509_t *x509 = (x509_t*)issuer;
@@ -926,18 +954,16 @@ METHOD(certificate_t, issued_by, bool,
}
}
- /* determine signature scheme */
- scheme = signature_scheme_from_oid(this->algorithm);
-
- if (scheme == SIGN_UNKNOWN || key == NULL)
+ if (!key)
{
return FALSE;
}
- valid = key->verify(key, scheme, this->certificateInfo, this->signature);
+ valid = key->verify(key, this->scheme->scheme, this->scheme->params,
+ this->certificateInfo, this->signature);
key->destroy(key);
- if (valid && schemep)
+ if (valid && scheme)
{
- *schemep = scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -1020,6 +1046,7 @@ METHOD(certificate_t, destroy, void,
DESTROY_IF(this->signerCert);
DESTROY_IF(this->signerKey);
this->groups->destroy_function(this->groups, (void*)group_destroy);
+ signature_params_destroy(this->scheme);
free(this->serialNumber.ptr);
free(this->authKeyIdentifier.ptr);
free(this->encoding.ptr);
@@ -1126,6 +1153,7 @@ static void add_groups_from_list(private_x509_ac_t *this, linked_list_t *list)
*/
x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args)
{
+ hash_algorithm_t digest_alg = HASH_SHA1;
private_x509_ac_t *ac;
ac = create_empty();
@@ -1157,6 +1185,13 @@ x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args)
ac->signerKey = va_arg(args, private_key_t*);
ac->signerKey->get_ref(ac->signerKey);
continue;
+ case BUILD_SIGNATURE_SCHEME:
+ ac->scheme = va_arg(args, signature_params_t*);
+ ac->scheme = signature_params_clone(ac->scheme);
+ continue;
+ case BUILD_DIGEST_ALG:
+ digest_alg = va_arg(args, int);
+ continue;
case BUILD_END:
break;
default:
@@ -1170,7 +1205,7 @@ x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args)
ac->holderCert->get_type(ac->holderCert) == CERT_X509 &&
ac->signerCert->get_type(ac->signerCert) == CERT_X509)
{
- if (build_ac(ac))
+ if (build_ac(ac, digest_alg))
{
return &ac->public;
}
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index 974e687f9..d1f9d9aac 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -4,7 +4,7 @@
* Copyright (C) 2002 Mario Strasser
* Copyright (C) 2000-2017 Andreas Steffen
* Copyright (C) 2006-2009 Martin Willi
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2017 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -197,9 +197,9 @@ struct private_x509_cert_t {
x509_flag_t flags;
/**
- * Signature algorithm
+ * Signature scheme
*/
- int algorithm;
+ signature_params_t *scheme;
/**
* Signature
@@ -241,16 +241,6 @@ static bool gn_to_string(identification_t *id, char **uri)
}
/**
- * Destroy a CertificateDistributionPoint
- */
-static void crl_uri_destroy(x509_cdp_t *this)
-{
- free(this->uri);
- DESTROY_IF(this->issuer);
- free(this);
-}
-
-/**
* Destroy a CertificatePolicy
*/
static void cert_policy_destroy(x509_cert_policy_t *this)
@@ -1385,7 +1375,7 @@ static bool parse_certificate(private_x509_cert_t *this)
chunk_t object;
int objectID;
int extn_oid = OID_UNKNOWN;
- int sig_alg = OID_UNKNOWN;
+ signature_params_t sig_alg = {};
bool success = FALSE;
bool critical = FALSE;
@@ -1416,7 +1406,11 @@ static bool parse_certificate(private_x509_cert_t *this)
this->serialNumber = object;
break;
case X509_OBJ_SIG_ALG:
- sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ if (!signature_params_parse(object, level, &sig_alg))
+ {
+ DBG1(DBG_ASN, " unable to parse signature algorithm");
+ goto end;
+ }
break;
case X509_OBJ_ISSUER:
this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
@@ -1570,8 +1564,13 @@ static bool parse_certificate(private_x509_cert_t *this)
break;
}
case X509_OBJ_ALGORITHM:
- this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
- if (this->algorithm != sig_alg)
+ INIT(this->scheme);
+ if (!signature_params_parse(object, level, this->scheme))
+ {
+ DBG1(DBG_ASN, " unable to parse signature algorithm");
+ goto end;
+ }
+ if (!signature_params_equal(this->scheme, &sig_alg))
{
DBG1(DBG_ASN, " signature algorithms do not agree");
goto end;
@@ -1588,6 +1587,7 @@ static bool parse_certificate(private_x509_cert_t *this)
end:
parser->destroy(parser);
+ signature_params_clear(&sig_alg);
if (success)
{
hasher_t *hasher;
@@ -1687,10 +1687,9 @@ METHOD(certificate_t, has_issuer, id_match_t,
METHOD(certificate_t, issued_by, bool,
private_x509_cert_t *this, certificate_t *issuer,
- signature_scheme_t *schemep)
+ signature_params_t **scheme)
{
public_key_t *key;
- signature_scheme_t scheme;
bool valid;
x509_t *x509 = (x509_t*)issuer;
@@ -1698,6 +1697,10 @@ METHOD(certificate_t, issued_by, bool,
{
if (this->flags & X509_SELF_SIGNED)
{
+ if (scheme)
+ {
+ *scheme = signature_params_clone(this->scheme);
+ }
return TRUE;
}
}
@@ -1717,23 +1720,18 @@ METHOD(certificate_t, issued_by, bool,
return FALSE;
}
- /* determine signature scheme */
- scheme = signature_scheme_from_oid(this->algorithm);
- if (scheme == SIGN_UNKNOWN)
- {
- return FALSE;
- }
/* get the public key of the issuer */
key = issuer->get_public_key(issuer);
if (!key)
{
return FALSE;
}
- valid = key->verify(key, scheme, this->tbsCertificate, this->signature);
+ valid = key->verify(key, this->scheme->scheme, this->scheme->params,
+ this->tbsCertificate, this->signature);
key->destroy(key);
- if (valid && schemep)
+ if (valid && scheme)
{
- *schemep = scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -1920,7 +1918,8 @@ METHOD(certificate_t, destroy, void,
{
this->subjectAltNames->destroy_offset(this->subjectAltNames,
offsetof(identification_t, destroy));
- this->crl_uris->destroy_function(this->crl_uris, (void*)crl_uri_destroy);
+ this->crl_uris->destroy_function(this->crl_uris,
+ (void*)x509_cdp_destroy);
this->ocsp_uris->destroy_function(this->ocsp_uris, free);
this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
offsetof(traffic_selector_t, destroy));
@@ -1932,6 +1931,7 @@ METHOD(certificate_t, destroy, void,
(void*)cert_policy_destroy);
this->policy_mappings->destroy_function(this->policy_mappings,
(void*)policy_mapping_destroy);
+ signature_params_destroy(this->scheme);
DESTROY_IF(this->issuer);
DESTROY_IF(this->subject);
DESTROY_IF(this->public_key);
@@ -2187,10 +2187,9 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
chunk_t crlDistributionPoints = chunk_empty, authorityInfoAccess = chunk_empty;
chunk_t policyConstraints = chunk_empty, inhibitAnyPolicy = chunk_empty;
chunk_t ikeIntermediate = chunk_empty, msSmartcardLogon = chunk_empty;
- chunk_t ipAddrBlocks = chunk_empty;
+ chunk_t ipAddrBlocks = chunk_empty, sig_scheme = chunk_empty;
identification_t *issuer, *subject;
chunk_t key_info;
- signature_scheme_t scheme;
hasher_t *hasher;
enumerator_t *enumerator;
char *uri;
@@ -2223,18 +2222,28 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
cert->notAfter = cert->notBefore + 60 * 60 * 24 * 365;
}
- /* select signature scheme */
- cert->algorithm = hasher_signature_algorithm_to_oid(digest_alg,
- sign_key->get_type(sign_key));
- if (cert->algorithm == OID_UNKNOWN)
+ /* select signature scheme, if not already specified */
+ if (!cert->scheme)
+ {
+ INIT(cert->scheme,
+ .scheme = signature_scheme_from_oid(
+ hasher_signature_algorithm_to_oid(digest_alg,
+ sign_key->get_type(sign_key))),
+ );
+ }
+ if (cert->scheme->scheme == SIGN_UNKNOWN)
+ {
+ return FALSE;
+ }
+ if (!signature_params_build(cert->scheme, &sig_scheme))
{
return FALSE;
}
- scheme = signature_scheme_from_oid(cert->algorithm);
if (!cert->public_key->get_encoding(cert->public_key,
PUBKEY_SPKI_ASN1_DER, &key_info))
{
+ chunk_free(&sig_scheme);
return FALSE;
}
@@ -2559,10 +2568,10 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
ipAddrBlocks));
}
- cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmmcmcmm",
+ cert->tbsCertificate = asn1_wrap(ASN1_SEQUENCE, "mmccmcmm",
asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2),
asn1_integer("c", cert->serialNumber),
- asn1_algorithmIdentifier(cert->algorithm),
+ sig_scheme,
issuer->get_encoding(issuer),
asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_from_time(&cert->notBefore, ASN1_UTCTIME),
@@ -2570,12 +2579,14 @@ static bool generate(private_x509_cert_t *cert, certificate_t *sign_cert,
subject->get_encoding(subject),
key_info, extensions);
- if (!sign_key->sign(sign_key, scheme, cert->tbsCertificate, &cert->signature))
+ if (!sign_key->sign(sign_key, cert->scheme->scheme, cert->scheme->params,
+ cert->tbsCertificate, &cert->signature))
{
+ chunk_free(&sig_scheme);
return FALSE;
}
cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm", cert->tbsCertificate,
- asn1_algorithmIdentifier(cert->algorithm),
+ sig_scheme,
asn1_bitstring("c", cert->signature));
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
@@ -2639,7 +2650,7 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
private_x509_cert_t *cert;
certificate_t *sign_cert = NULL;
private_key_t *sign_key = NULL;
- hash_algorithm_t digest_alg = HASH_SHA1;
+ hash_algorithm_t digest_alg = HASH_SHA256;
u_int constraint;
cert = create_empty();
@@ -2831,6 +2842,10 @@ x509_cert_t *x509_cert_gen(certificate_type_t type, va_list args)
case BUILD_SERIAL:
cert->serialNumber = chunk_clone(va_arg(args, chunk_t));
continue;
+ case BUILD_SIGNATURE_SCHEME:
+ cert->scheme = va_arg(args, signature_params_t*);
+ cert->scheme = signature_params_clone(cert->scheme);
+ continue;
case BUILD_DIGEST_ALG:
digest_alg = va_arg(args, int);
continue;
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
index d8913ad73..699ac5a39 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.c
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2014-2017 Tobias Brunner
* Copyright (C) 2008-2009 Martin Willi
* Copyright (C) 2017 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
@@ -121,9 +122,9 @@ struct private_x509_crl_t {
chunk_t baseCrlNumber;
/**
- * Signature algorithm
+ * Signature scheme
*/
- int algorithm;
+ signature_params_t *scheme;
/**
* Signature
@@ -225,7 +226,7 @@ static bool parse(private_x509_crl_t *this)
chunk_t extnID = chunk_empty;
chunk_t userCertificate = chunk_empty;
int objectID;
- int sig_alg = OID_UNKNOWN;
+ signature_params_t sig_alg = {};
bool success = FALSE;
bool critical = FALSE;
revoked_t *revoked = NULL;
@@ -246,7 +247,11 @@ static bool parse(private_x509_crl_t *this)
DBG2(DBG_ASN, " v%d", this->version);
break;
case CRL_OBJ_SIG_ALG:
- sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
+ if (!signature_params_parse(object, level, &sig_alg))
+ {
+ DBG1(DBG_ASN, " unable to parse signature algorithm");
+ goto end;
+ }
break;
case CRL_OBJ_ISSUER:
this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
@@ -342,8 +347,13 @@ static bool parse(private_x509_crl_t *this)
}
case CRL_OBJ_ALGORITHM:
{
- this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
- if (this->algorithm != sig_alg)
+ INIT(this->scheme);
+ if (!signature_params_parse(object, level, this->scheme))
+ {
+ DBG1(DBG_ASN, " unable to parse signature algorithm");
+ goto end;
+ }
+ if (!signature_params_equal(this->scheme, &sig_alg))
{
DBG1(DBG_ASN, " signature algorithms do not agree");
goto end;
@@ -361,6 +371,7 @@ static bool parse(private_x509_crl_t *this)
end:
parser->destroy(parser);
+ signature_params_clear(&sig_alg);
return success;
}
@@ -457,10 +468,10 @@ METHOD(certificate_t, has_issuer, id_match_t,
}
METHOD(certificate_t, issued_by, bool,
- private_x509_crl_t *this, certificate_t *issuer, signature_scheme_t *schemep)
+ private_x509_crl_t *this, certificate_t *issuer,
+ signature_params_t **scheme)
{
public_key_t *key;
- signature_scheme_t scheme;
bool valid;
x509_t *x509 = (x509_t*)issuer;
chunk_t keyid = chunk_empty;
@@ -492,21 +503,17 @@ METHOD(certificate_t, issued_by, bool,
}
}
- scheme = signature_scheme_from_oid(this->algorithm);
- if (scheme == SIGN_UNKNOWN)
- {
- return FALSE;
- }
key = issuer->get_public_key(issuer);
if (!key)
{
return FALSE;
}
- valid = key->verify(key, scheme, this->tbsCertList, this->signature);
+ valid = key->verify(key, this->scheme->scheme, this->scheme->params,
+ this->tbsCertList, this->signature);
key->destroy(key);
- if (valid && schemep)
+ if (valid && scheme)
{
- *schemep = scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -585,23 +592,15 @@ static void revoked_destroy(revoked_t *revoked)
free(revoked);
}
-/**
- * Destroy a CDP entry
- */
-static void cdp_destroy(x509_cdp_t *this)
-{
- free(this->uri);
- DESTROY_IF(this->issuer);
- free(this);
-}
-
METHOD(certificate_t, destroy, void,
private_x509_crl_t *this)
{
if (ref_put(&this->ref))
{
this->revoked->destroy_function(this->revoked, (void*)revoked_destroy);
- this->crl_uris->destroy_function(this->crl_uris, (void*)cdp_destroy);
+ this->crl_uris->destroy_function(this->crl_uris,
+ (void*)x509_cdp_destroy);
+ signature_params_destroy(this->scheme);
DESTROY_IF(this->issuer);
free(this->authKeyIdentifier.ptr);
free(this->encoding.ptr);
@@ -718,6 +717,7 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
{
chunk_t extensions = chunk_empty, certList = chunk_empty, serial;
chunk_t crlDistributionPoints = chunk_empty, baseCrlNumber = chunk_empty;
+ chunk_t sig_scheme = chunk_empty;
enumerator_t *enumerator;
crl_reason_t reason;
time_t date;
@@ -730,10 +730,20 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
this->authKeyIdentifier = chunk_clone(x509->get_subjectKeyIdentifier(x509));
- /* select signature scheme */
- this->algorithm = hasher_signature_algorithm_to_oid(digest_alg,
- key->get_type(key));
- if (this->algorithm == OID_UNKNOWN)
+ /* select signature scheme, if not already specified */
+ if (!this->scheme)
+ {
+ INIT(this->scheme,
+ .scheme = signature_scheme_from_oid(
+ hasher_signature_algorithm_to_oid(digest_alg,
+ key->get_type(key))),
+ );
+ }
+ if (this->scheme->scheme == SIGN_UNKNOWN)
+ {
+ return FALSE;
+ }
+ if (!signature_params_build(this->scheme, &sig_scheme))
{
return FALSE;
}
@@ -787,23 +797,24 @@ static bool generate(private_x509_crl_t *this, certificate_t *cert,
asn1_integer("c", this->crlNumber))),
crlDistributionPoints, baseCrlNumber));
- this->tbsCertList = asn1_wrap(ASN1_SEQUENCE, "cmcmmmm",
+ this->tbsCertList = asn1_wrap(ASN1_SEQUENCE, "cccmmmm",
ASN1_INTEGER_1,
- asn1_algorithmIdentifier(this->algorithm),
+ sig_scheme,
this->issuer->get_encoding(this->issuer),
asn1_from_time(&this->thisUpdate, ASN1_UTCTIME),
asn1_from_time(&this->nextUpdate, ASN1_UTCTIME),
asn1_wrap(ASN1_SEQUENCE, "m", certList),
extensions);
- if (!key->sign(key, signature_scheme_from_oid(this->algorithm),
+ if (!key->sign(key, this->scheme->scheme, this->scheme->params,
this->tbsCertList, &this->signature))
{
+ chunk_free(&sig_scheme);
return FALSE;
}
this->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
this->tbsCertList,
- asn1_algorithmIdentifier(this->algorithm),
+ sig_scheme,
asn1_bitstring("c", this->signature));
return TRUE;
}
@@ -842,6 +853,10 @@ x509_crl_t *x509_crl_gen(certificate_type_t type, va_list args)
crl->crlNumber = va_arg(args, chunk_t);
crl->crlNumber = chunk_clone(crl->crlNumber);
continue;
+ case BUILD_SIGNATURE_SCHEME:
+ crl->scheme = va_arg(args, signature_params_t*);
+ crl->scheme = signature_params_clone(crl->scheme);
+ continue;
case BUILD_DIGEST_ALG:
digest_alg = va_arg(args, int);
continue;
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
index aef76af32..de22ab6be 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
@@ -276,7 +276,7 @@ static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this,
return chunk_empty;
}
- if (!this->key->sign(this->key, scheme, tbsRequest, &signature))
+ if (!this->key->sign(this->key, scheme, NULL, tbsRequest, &signature))
{
DBG1(DBG_LIB, "creating OCSP signature failed, skipped");
return chunk_empty;
@@ -372,7 +372,7 @@ METHOD(certificate_t, has_issuer, id_match_t,
METHOD(certificate_t, issued_by, bool,
private_x509_ocsp_request_t *this, certificate_t *issuer,
- signature_scheme_t *scheme)
+ signature_params_t **scheme)
{
DBG1(DBG_LIB, "OCSP request validation not implemented!");
return FALSE;
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
index 140e9bfa9..aa4999cbd 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -1,4 +1,5 @@
-/**
+/*
+ * Copyright (C) 2017 Tobias Brunner
* Copyright (C) 2008-2009 Martin Willi
* Copyright (C) 2007-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
@@ -63,9 +64,9 @@ struct private_x509_ocsp_response_t {
chunk_t tbsResponseData;
/**
- * signature algorithm (OID)
+ * signature scheme
*/
- int signatureAlgorithm;
+ signature_params_t *scheme;
/**
* signature
@@ -576,8 +577,13 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
}
break;
case BASIC_RESPONSE_ALGORITHM:
- this->signatureAlgorithm = asn1_parse_algorithmIdentifier(object,
- parser->get_level(parser)+1, NULL);
+ INIT(this->scheme);
+ if (!signature_params_parse(object, parser->get_level(parser)+1,
+ this->scheme))
+ {
+ DBG1(DBG_ASN, " unable to parse signature algorithm");
+ goto end;
+ }
break;
case BASIC_RESPONSE_SIGNATURE:
this->signature = chunk_skip(object, 1);
@@ -703,10 +709,9 @@ METHOD(certificate_t, has_issuer, id_match_t,
METHOD(certificate_t, issued_by, bool,
private_x509_ocsp_response_t *this, certificate_t *issuer,
- signature_scheme_t *schemep)
+ signature_params_t **scheme)
{
public_key_t *key;
- signature_scheme_t scheme;
bool valid;
x509_t *x509 = (x509_t*)issuer;
@@ -743,21 +748,17 @@ METHOD(certificate_t, issued_by, bool,
return FALSE;
}
- /* get the public key of the issuer */
key = issuer->get_public_key(issuer);
-
- /* determine signature scheme */
- scheme = signature_scheme_from_oid(this->signatureAlgorithm);
-
- if (scheme == SIGN_UNKNOWN || key == NULL)
+ if (!key)
{
return FALSE;
}
- valid = key->verify(key, scheme, this->tbsResponseData, this->signature);
+ valid = key->verify(key, this->scheme->scheme, this->scheme->params,
+ this->tbsResponseData, this->signature);
key->destroy(key);
- if (valid && schemep)
+ if (valid && scheme)
{
- *schemep = scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -839,6 +840,7 @@ METHOD(certificate_t, destroy, void,
{
this->certs->destroy_offset(this->certs, offsetof(certificate_t, destroy));
this->responses->destroy_function(this->responses, free);
+ signature_params_destroy(this->scheme);
DESTROY_IF(this->responderId);
free(this->encoding.ptr);
free(this);
@@ -879,7 +881,6 @@ static x509_ocsp_response_t *load(chunk_t blob)
.producedAt = UNDEFINED_TIME,
.usableUntil = UNDEFINED_TIME,
.responses = linked_list_create(),
- .signatureAlgorithm = OID_UNKNOWN,
.certs = linked_list_create(),
);
diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c
index e39e24bff..587fbd5d6 100644
--- a/src/libstrongswan/plugins/x509/x509_pkcs10.c
+++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c
@@ -72,9 +72,9 @@ struct private_x509_pkcs10_t {
chunk_t challengePassword;
/**
- * Signature algorithm
+ * Signature scheme
*/
- int algorithm;
+ signature_params_t *scheme;
/**
* Signature
@@ -124,10 +124,9 @@ METHOD(certificate_t, has_subject, id_match_t,
METHOD(certificate_t, issued_by, bool,
private_x509_pkcs10_t *this, certificate_t *issuer,
- signature_scheme_t *schemep)
+ signature_params_t **scheme)
{
public_key_t *key;
- signature_scheme_t scheme;
bool valid;
if (&this->public.interface.interface != issuer)
@@ -136,27 +135,22 @@ METHOD(certificate_t, issued_by, bool,
}
if (this->self_signed)
{
- return TRUE;
+ valid = TRUE;
}
-
- /* determine signature scheme */
- scheme = signature_scheme_from_oid(this->algorithm);
- if (scheme == SIGN_UNKNOWN)
+ else
{
- return FALSE;
- }
-
- /* get the public key contained in the certificate request */
- key = this->public_key;
- if (!key)
- {
- return FALSE;
+ /* get the public key contained in the certificate request */
+ key = this->public_key;
+ if (!key)
+ {
+ return FALSE;
+ }
+ valid = key->verify(key, this->scheme->scheme, this->scheme->params,
+ this->certificationRequestInfo, this->signature);
}
- valid = key->verify(key, scheme, this->certificationRequestInfo,
- this->signature);
- if (valid && schemep)
+ if (valid && scheme)
{
- *schemep = scheme;
+ *scheme = signature_params_clone(this->scheme);
}
return valid;
}
@@ -410,7 +404,7 @@ static bool parse_certificate_request(private_x509_pkcs10_t *this)
case PKCS10_SUBJECT_PUBLIC_KEY_INFO:
this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
- if (this->public_key == NULL)
+ if (!this->public_key)
{
goto end;
}
@@ -438,7 +432,12 @@ static bool parse_certificate_request(private_x509_pkcs10_t *this)
}
break;
case PKCS10_ALGORITHM:
- this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
+ INIT(this->scheme);
+ if (!signature_params_parse(object, level, this->scheme))
+ {
+ DBG1(DBG_ASN, " unable to parse signature algorithm");
+ goto end;
+ }
break;
case PKCS10_SIGNATURE:
this->signature = chunk_skip(object, 1);
@@ -474,6 +473,7 @@ METHOD(certificate_t, destroy, void,
{
this->subjectAltNames->destroy_offset(this->subjectAltNames,
offsetof(identification_t, destroy));
+ signature_params_destroy(this->scheme);
DESTROY_IF(this->subject);
DESTROY_IF(this->public_key);
chunk_free(&this->encoding);
@@ -530,25 +530,34 @@ static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
{
chunk_t key_info, subjectAltNames, attributes;
chunk_t extensionRequest = chunk_empty;
- chunk_t challengePassword = chunk_empty;
- signature_scheme_t scheme;
+ chunk_t challengePassword = chunk_empty, sig_scheme = chunk_empty;
identification_t *subject;
subject = cert->subject;
cert->public_key = sign_key->get_public_key(sign_key);
- /* select signature scheme */
- cert->algorithm = hasher_signature_algorithm_to_oid(digest_alg,
- sign_key->get_type(sign_key));
- if (cert->algorithm == OID_UNKNOWN)
+ /* select signature scheme, if not already specified */
+ if (!cert->scheme)
+ {
+ INIT(cert->scheme,
+ .scheme = signature_scheme_from_oid(
+ hasher_signature_algorithm_to_oid(digest_alg,
+ sign_key->get_type(sign_key))),
+ );
+ }
+ if (cert->scheme->scheme == SIGN_UNKNOWN)
+ {
+ return FALSE;
+ }
+ if (!signature_params_build(cert->scheme, &sig_scheme))
{
return FALSE;
}
- scheme = signature_scheme_from_oid(cert->algorithm);
if (!cert->public_key->get_encoding(cert->public_key,
PUBKEY_SPKI_ASN1_DER, &key_info))
{
+ chunk_free(&sig_scheme);
return FALSE;
}
@@ -584,15 +593,16 @@ static bool generate(private_x509_pkcs10_t *cert, private_key_t *sign_key,
key_info,
attributes);
- if (!sign_key->sign(sign_key, scheme, cert->certificationRequestInfo,
- &cert->signature))
+ if (!sign_key->sign(sign_key, cert->scheme->scheme, cert->scheme->params,
+ cert->certificationRequestInfo, &cert->signature))
{
+ chunk_free(&sig_scheme);
return FALSE;
}
cert->encoding = asn1_wrap(ASN1_SEQUENCE, "cmm",
cert->certificationRequestInfo,
- asn1_algorithmIdentifier(cert->algorithm),
+ sig_scheme,
asn1_bitstring("c", cert->signature));
return TRUE;
}
@@ -674,6 +684,10 @@ x509_pkcs10_t *x509_pkcs10_gen(certificate_type_t type, va_list args)
case BUILD_CHALLENGE_PWD:
cert->challengePassword = chunk_clone(va_arg(args, chunk_t));
continue;
+ case BUILD_SIGNATURE_SCHEME:
+ cert->scheme = va_arg(args, signature_params_t*);
+ cert->scheme = signature_params_clone(cert->scheme);
+ continue;
case BUILD_DIGEST_ALG:
digest_alg = va_arg(args, int);
continue;
diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in
index d5d47694f..3a39037bc 100644
--- a/src/libstrongswan/plugins/xcbc/Makefile.in
+++ b/src/libstrongswan/plugins/xcbc/Makefile.in
@@ -244,9 +244,11 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
+FUZZING_LDFLAGS = @FUZZING_LDFLAGS@
GEM = @GEM@
GENHTML = @GENHTML@
GPERF = @GPERF@
+GPERF_LEN_TYPE = @GPERF_LEN_TYPE@
GPRBUILD = @GPRBUILD@
GREP = @GREP@
INSTALL = @INSTALL@