summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2019-04-25 08:12:40 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2019-04-25 08:12:40 +0000
commit1ee821191870e425b2e645476b5c311dddb66938 (patch)
treeb0cdafe10adf4988cc20b13d9cb3549538130d1a
parentc951c13f3814e02fc2df7ce8b2408337d3770660 (diff)
parent86640a54f758f24fd13c83ec2c64a3270e461794 (diff)
downloadgnutls-1ee821191870e425b2e645476b5c311dddb66938.tar.gz
Merge branch 'tmp-rsa-pss-cert-fix' into 'master'
certtool: generate RSA-PSS certificates from RSA keys See merge request gnutls/gnutls!980
-rw-r--r--src/certtool-args.def4
-rw-r--r--src/certtool.c67
-rwxr-xr-xtests/cert-tests/certtool-rsa-pss65
-rwxr-xr-xtests/cert-tests/rsa-pss-pad4
4 files changed, 115 insertions, 25 deletions
diff --git a/src/certtool-args.def b/src/certtool-args.def
index 27ca2c8ed4..35741a21c8 100644
--- a/src/certtool-args.def
+++ b/src/certtool-args.def
@@ -200,7 +200,9 @@ flag = {
arg-type = string;
descrip = "Specify the key type to use on key generation";
doc = "This option can be combined with --generate-privkey, to specify
-the key type to be generated. Valid options are, 'rsa', 'rsa-pss', 'dsa', 'ecdsa', and 'ed25519'.";
+the key type to be generated. Valid options are, 'rsa', 'rsa-pss', 'dsa', 'ecdsa', and 'ed25519'.
+When combined with certificate generation it can be used to specify an
+RSA-PSS certificate when an RSA key is given.";
};
flag = {
diff --git a/src/certtool.c b/src/certtool.c
index 11dc27a6fd..6623b86385 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -92,9 +92,11 @@ static gnutls_digest_algorithm_t get_dig(gnutls_x509_crt_t crt, common_info_st *
FILE *outfile;
static const char *outfile_name = NULL; /* to delete on exit */
+#define REQ_KEY_TYPE_DEFAULT GNUTLS_PK_RSA
+
FILE *infile;
static unsigned int incert_format, outcert_format;
-static unsigned int req_key_type = GNUTLS_PK_RSA;
+static unsigned int req_key_type = REQ_KEY_TYPE_DEFAULT;
gnutls_certificate_print_formats_t full_format = GNUTLS_CRT_PRINT_FULL;
/* non interactive operation if set
@@ -128,6 +130,21 @@ int main(int argc, char **argv)
return 0;
}
+#define SET_SPKI_PARAMS(spki, cinfo) \
+ do { \
+ unsigned _salt_size; \
+ if (!cinfo->hash) { \
+ fprintf(stderr, "You must provide the hash algorithm and optionally the salt size for RSA-PSS\n"); \
+ app_exit(1); \
+ } \
+ if (HAVE_OPT(SALT_SIZE)) { \
+ _salt_size = OPT_VALUE_SALT_SIZE; \
+ } else { \
+ _salt_size = gnutls_hash_get_len(cinfo->hash); \
+ } \
+ gnutls_x509_spki_set_rsa_pss_params(spki, cinfo->hash, _salt_size); \
+ } while(0)
+
static gnutls_x509_privkey_t
generate_private_key_int(common_info_st * cinfo)
{
@@ -220,20 +237,8 @@ generate_private_key_int(common_info_st * cinfo)
}
if (key_type == GNUTLS_PK_RSA_PSS && (cinfo->hash || HAVE_OPT(SALT_SIZE))) {
- unsigned salt_size;
-
- if (!cinfo->hash) {
- fprintf(stderr, "You must provide the hash algorithm and optionally the salt size for RSA-PSS\n");
- app_exit(1);
- }
-
- if (HAVE_OPT(SALT_SIZE)) {
- salt_size = OPT_VALUE_SALT_SIZE;
- } else {
- salt_size = gnutls_hash_get_len(cinfo->hash);
- }
- gnutls_x509_spki_set_rsa_pss_params(spki, cinfo->hash, salt_size);
+ SET_SPKI_PARAMS(spki, cinfo);
kdata[kdata_size].type = GNUTLS_KEYGEN_SPKI;
kdata[kdata_size].data = (void*)spki;
@@ -308,6 +313,7 @@ generate_certificate(gnutls_privkey_t * ret_key,
common_info_st * cinfo)
{
gnutls_x509_crt_t crt;
+ gnutls_x509_spki_t spki;
gnutls_privkey_t key = NULL;
gnutls_pubkey_t pubkey;
size_t size;
@@ -715,11 +721,17 @@ generate_certificate(gnutls_privkey_t * ret_key,
app_exit(1);
}
+ if ((HAVE_OPT(KEY_TYPE) || req_key_type != REQ_KEY_TYPE_DEFAULT) && req_key_type != pk) {
+ if (pk != GNUTLS_PK_RSA || req_key_type != GNUTLS_PK_RSA_PSS) {
+ fprintf(stderr, "cannot set certificate type (%s) incompatible with the key (%s)\n",
+ gnutls_pk_get_name(req_key_type), gnutls_pk_get_name(pk));
+ app_exit(1);
+ }
+ }
+
/* Set algorithm parameter restriction in CAs.
*/
if (pk == GNUTLS_PK_RSA_PSS && ca_status && key) {
- gnutls_x509_spki_t spki;
-
result = gnutls_x509_spki_init(&spki);
if (result < 0) {
fprintf(stderr, "spki_init: %s\n",
@@ -738,6 +750,25 @@ generate_certificate(gnutls_privkey_t * ret_key,
}
gnutls_x509_spki_deinit(spki);
+
+ } else if (pk == GNUTLS_PK_RSA && req_key_type == GNUTLS_PK_RSA_PSS) {
+ result = gnutls_x509_spki_init(&spki);
+ if (result < 0) {
+ fprintf(stderr, "spki_init: %s\n",
+ gnutls_strerror(result));
+ app_exit(1);
+ }
+
+ SET_SPKI_PARAMS(spki, cinfo);
+
+ result = gnutls_x509_crt_set_spki(crt, spki, 0);
+ if (result < 0) {
+ fprintf(stderr, "error setting RSA-PSS SPKI information: %s\n",
+ gnutls_strerror(result));
+ app_exit(1);
+ }
+
+ gnutls_x509_spki_deinit(spki);
}
*ret_key = key;
@@ -1235,7 +1266,9 @@ static void cmd_parser(int argc, char **argv)
outcert_format = GNUTLS_X509_FMT_PEM;
/* legacy options */
- if (HAVE_OPT(DSA)) {
+ if (HAVE_OPT(RSA)) {
+ req_key_type = GNUTLS_PK_RSA;
+ } else if (HAVE_OPT(DSA)) {
req_key_type = GNUTLS_PK_DSA;
} else if (HAVE_OPT(ECC)) {
req_key_type = GNUTLS_PK_ECDSA;
diff --git a/tests/cert-tests/certtool-rsa-pss b/tests/cert-tests/certtool-rsa-pss
index f8126a5523..617591377d 100755
--- a/tests/cert-tests/certtool-rsa-pss
+++ b/tests/cert-tests/certtool-rsa-pss
@@ -25,6 +25,7 @@ CERTTOOL="${CERTTOOL:-../../src/certtool${EXEEXT}}"
DIFF="${DIFF:-diff -b -B}"
OUTFILE=cert-pss-privkey.$$.tmp
TMPFILE=cert-pss.$$.tmp
+TMPFILE2=cert2-pss.$$.tmp
if ! test -x "${CERTTOOL}"; then
exit 77
@@ -49,7 +50,7 @@ if test "${rc}" != "0"; then
exit 1
fi
-${VALGRIND} "${CERTTOOL}" -k --password '' --infile "$OUTFILE"
+${VALGRIND} "${CERTTOOL}" -k --password '' --infile "$OUTFILE" >/dev/null
rc=$?
if test "${rc}" != "0"; then
echo "Could not read generated an RSA-PSS key ($i)"
@@ -60,7 +61,7 @@ fi
${VALGRIND} "${CERTTOOL}" --generate-self-signed \
--pkcs8 --load-privkey "$OUTFILE" --password '' \
--template "${srcdir}/templates/template-test.tmpl" \
- --outfile "${TMPFILE}" --hash $i 2>/dev/null
+ --outfile "${TMPFILE}" --hash $i
rc=$?
if test "${rc}" != "0"; then
@@ -68,13 +69,15 @@ if test "${rc}" != "0"; then
exit 1
fi
+rm -f "${TMPFILE}"
+
# Create an RSA-PSS certificate from an RSA-PSS private key, with
# mismatched parameters
for j in sha256 sha384 sha512;do
${VALGRIND} "${CERTTOOL}" --generate-self-signed \
--pkcs8 --load-privkey "$OUTFILE" --password '' \
--template "${srcdir}/templates/template-test.tmpl" \
- --outfile "${TMPFILE}" --hash $j 2>/dev/null
+ --outfile "${TMPFILE}" --hash $j
rc=$?
if test "$j" != "$j" && "${rc}" = "0"; then
@@ -82,6 +85,7 @@ if test "$j" != "$j" && "${rc}" = "0"; then
exit 1
fi
done
+rm -f "${TMPFILE}"
# Create an RSA-PSS certificate from an RSA key
${VALGRIND} "${CERTTOOL}" --generate-certificate --key-type rsa-pss \
@@ -89,7 +93,7 @@ ${VALGRIND} "${CERTTOOL}" --generate-certificate --key-type rsa-pss \
--load-ca-privkey "${srcdir}/../../doc/credentials/x509/ca-key.pem" \
--load-ca-certificate "${srcdir}/../../doc/credentials/x509/ca.pem" \
--template "${srcdir}/templates/template-test.tmpl" \
- --outfile "${TMPFILE}" --hash $i 2>/dev/null
+ --outfile "${TMPFILE}" --hash $i
rc=$?
if test "${rc}" != "0"; then
@@ -97,19 +101,68 @@ if test "${rc}" != "0"; then
exit 1
fi
+${CERTTOOL} -i --infile ${TMPFILE}|grep -i "Subject Public Key Algorithm: RSA-PSS"
+if test $? != 0;then
+ echo "Generated certificate is not RSA-PSS"
+ cat ${TMPFILE}
+ exit 1
+fi
+
+rm -f "${TMPFILE}"
+
+# Create an RSA certificate from an RSA key, with wrong key-type, should fail
+${VALGRIND} "${CERTTOOL}" --generate-certificate --key-type ecdsa \
+ --load-privkey "${srcdir}/../../doc/credentials/x509/key-rsa.pem" \
+ --load-ca-privkey "${srcdir}/../../doc/credentials/x509/ca-key.pem" \
+ --load-ca-certificate "${srcdir}/../../doc/credentials/x509/ca.pem" \
+ --template "${srcdir}/templates/template-test.tmpl" \
+ --outfile "${TMPFILE}"
+rc=$?
+
+if test "${rc}" = "0"; then
+ echo "Succeeded with wrong key type"
+ exit 1
+fi
+
# Create an RSA certificate from an RSA key, and sign it with RSA-PSS
${VALGRIND} "${CERTTOOL}" --generate-certificate --rsa --sign-params rsa-pss \
--load-privkey "${srcdir}/../../doc/credentials/x509/key-rsa.pem" \
--load-ca-privkey "${srcdir}/../../doc/credentials/x509/ca-key.pem" \
--load-ca-certificate "${srcdir}/../../doc/credentials/x509/ca.pem" \
--template "${srcdir}/templates/template-test.tmpl" \
- --outfile "${TMPFILE}" --hash $i 2>/dev/null
+ --outfile "${TMPFILE}" --hash $i
rc=$?
if test "${rc}" != "0"; then
echo "Could not generate an RSA-PSS certificate"
exit 1
fi
+
+${CERTTOOL} -i --infile ${TMPFILE}|tr -d '\r' > ${TMPFILE2}
+grep -i 'Subject Public Key Algorithm: RSA$' ${TMPFILE2} >/dev/null
+if test $? != 0;then
+ echo "Generated certificate is not RSA"
+ cat ${TMPFILE}
+ exit 1
+fi
+
+grep -i "Signature Algorithm: RSA-PSS" ${TMPFILE2}
+if test $? != 0;then
+ echo "Generated certificate is not signed with RSA-PSS"
+ cat ${TMPFILE}
+ exit 1
+fi
+
+grep -i "Signature Algorithm: RSA-PSS-${i}" ${TMPFILE2}
+if test $? != 0;then
+ echo "Generated certificate is not signed with RSA-PSS-${i}"
+ cat ${TMPFILE}
+ exit 1
+fi
+
+rm -f "${TMPFILE}"
+rm -f "${TMPFILE2}"
+
done
# Convert an RSA-PSS key to an RSA key
@@ -133,6 +186,8 @@ fi
echo "RSA-PSS to RSA conversion was successful"
+rm -f "${TMPFILE}"
+
export TZ="UTC"
. ${srcdir}/../scripts/common.sh
diff --git a/tests/cert-tests/rsa-pss-pad b/tests/cert-tests/rsa-pss-pad
index e2eccfbe8e..d9a05e4e0f 100755
--- a/tests/cert-tests/rsa-pss-pad
+++ b/tests/cert-tests/rsa-pss-pad
@@ -44,9 +44,9 @@ check_for_datefudge
for i in sha256 sha384 sha512;do
datefudge -s "2007-04-22" \
"${CERTTOOL}" --generate-self-signed --key-type rsa-pss \
- --load-privkey "${srcdir}/data/template-test.key" \
+ --load-privkey "${srcdir}/data/privkey1.pem" \
--template "${srcdir}/templates/template-test.tmpl" \
- --outfile "${TMPFILE}" --hash $i 2>/dev/null
+ --outfile "${TMPFILE}" --hash $i
rc=$?
if test -f "${srcdir}/data/template-rsa-$i.pem";then