summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2018-12-15 21:10:28 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2018-12-15 21:10:28 +0000
commitc18c0d9dccfa5a161c47f5c0f9c197cbcabf6ed7 (patch)
tree49000dc71f92facdb409986c87c47bd11f27ff04
parent69633606e29b6e8d3fd946e8e8fb1906e0c8bf6c (diff)
parent565efaeac828e89d2c1bac7a88c27303d1b62547 (diff)
downloadgnutls-c18c0d9dccfa5a161c47f5c0f9c197cbcabf6ed7.tar.gz
Merge branch 'rfc7250_rawpk_mr' into 'master'
RFC7250 Raw public keys Closes #280 and #26 See merge request gnutls/gnutls!650
-rw-r--r--.gitignore2
-rw-r--r--NEWS325
-rw-r--r--doc/Makefile.am8
-rw-r--r--doc/cha-cert-auth.texi32
-rw-r--r--doc/cha-gtls-app.texi46
-rw-r--r--doc/cha-tokens.texi16
-rw-r--r--doc/manpages/Makefile.am4
-rw-r--r--lib/Makefile.am6
-rw-r--r--lib/algorithms/cert_types.c4
-rw-r--r--lib/auth/cert.c312
-rw-r--r--lib/auth/cert.h13
-rw-r--r--lib/auth/rsa.c2
-rw-r--r--lib/cert-cred-rawpk.c360
-rw-r--r--lib/cert-cred-x509.c241
-rw-r--r--lib/cert-cred.c197
-rw-r--r--lib/cert-cred.h53
-rw-r--r--lib/cert-session.c18
-rw-r--r--lib/ext/cert_types.h37
-rw-r--r--lib/ext/client_cert_type.c48
-rw-r--r--lib/ext/server_cert_type.c48
-rw-r--r--lib/gnutls_int.h34
-rw-r--r--lib/includes/gnutls/abstract.h8
-rw-r--r--lib/includes/gnutls/gnutls.h.in50
-rw-r--r--lib/libgnutls.map9
-rw-r--r--lib/pcert.c152
-rw-r--r--lib/pkcs11x.c2
-rw-r--r--lib/session.c13
-rw-r--r--lib/state.c36
-rw-r--r--lib/str_array.h20
-rw-r--r--lib/tls13/certificate_verify.c2
-rw-r--r--lib/verify-tofu.c116
-rw-r--r--lib/x509.h3
-rw-r--r--lib/x509/common.c2
-rw-r--r--lib/x509/common.h2
-rw-r--r--m4/hooks.m412
-rw-r--r--src/tests.c1
-rw-r--r--symbols.last5
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/cert-common.h128
-rw-r--r--tests/certs/rawpk_priv.pem39
-rw-r--r--tests/certs/rawpk_pub.pem11
-rw-r--r--tests/common-cert-key-exchange.c71
-rw-r--r--tests/common-cert-key-exchange.h31
-rw-r--r--tests/crt_type-neg-common.c103
-rw-r--r--tests/rawpk-api.c143
-rw-r--r--tests/ssl30-cert-key-exchange.c14
-rw-r--r--tests/tls-crt_type-neg.c373
-rw-r--r--tests/tls10-cert-key-exchange.c30
-rw-r--r--tests/tls11-cert-key-exchange.c30
-rw-r--r--tests/tls12-cert-key-exchange.c104
-rw-r--r--tests/tls13-cert-key-exchange.c97
-rw-r--r--tests/trustdb-tofu.c81
52 files changed, 2556 insertions, 941 deletions
diff --git a/.gitignore b/.gitignore
index 2ffe7b8aab..bd0f8d6e46 100644
--- a/.gitignore
+++ b/.gitignore
@@ -600,6 +600,7 @@ tests/privkey-verify-broken
tests/psk-file
tests/pskself
tests/pubkey-import-export
+tests/rawpk-api
tests/random-art
tests/record-pad
tests/record-retvals
@@ -688,6 +689,7 @@ tests/sign-verify-ed25519-rfc8080
tests/sign-verify-ext
tests/sign-verify-ext4
tests/simple
+tests/slow/cipher-api-test
tests/slow/cipher-compat
tests/slow/cipher-openssl-compat
tests/slow/cipher-override
diff --git a/NEWS b/NEWS
index a0848ff33a..b55cd07be5 100644
--- a/NEWS
+++ b/NEWS
@@ -53,6 +53,11 @@ See the end for copying conditions.
** certtool: Add parameter --no-text that prevents certtool from outputting
text before PEM-encoded private key, public key, certificate, CRL or CSR.
+** libgnutls: Added support for raw public-key authentication as defined in RFC7250.
+ Raw public-keys can be negotiated by enabling the corresponding certificate
+ types via the priority strings. The raw public-key mechanism must be explicitly
+ enabled via the GNUTLS_ENABLE_RAWPK init flag.
+
** API and ABI modifications:
GNUTLS_AUTO_REAUTH: Added
GNUTLS_CIPHER_AES_128_CFB8: Added
@@ -60,6 +65,8 @@ GNUTLS_CIPHER_AES_192_CFB8: Added
GNUTLS_CIPHER_AES_256_CFB8: Added
GNUTLS_MAC_AES_CMAC_128: Added
GNUTLS_MAC_AES_CMAC_256: Added
+GNUTLS_ENABLE_RAWPK: Added
+GNUTLS_ENABLE_CERT_TYPE_NEG: Removed
gnutls_record_get_max_early_data_size: Added
gnutls_record_send_early_data: Added
gnutls_record_recv_early_data: Added
@@ -169,7 +176,7 @@ gnutls_ffdhe_6144_key_bits: Added
** Improved counter-measures for TLS CBC record padding. Kenny Paterson, Eyal Ronen
and Adi Shamir reported that the existing counter-measures had certain issues and
- were insufficient when the attacker has additional access to the CPU cache and
+ were insufficient when the attacker has additional access to the CPU cache and
performs a chosen-plaintext attack. This affected the legacy CBC ciphersuites. [CVSS: medium]
** Introduced the %FORCE_ETM priority string option. This option prevents the negotiation
@@ -514,7 +521,7 @@ GNUTLS_SFLAGS_RFC7919: Added
a flag.
** libgnutls: Improved TPM key handling. Check authorization requirements
- prior to using a key and fix issue on loop for PIN input. Patches by
+ prior to using a key and fix issue on loop for PIN input. Patches by
James Bottomley.
** libgnutls: In all functions accepting UTF-8 passwords, ensure that
@@ -592,7 +599,7 @@ gnutls_x509_crq_get_dn3: Added
not identical to CVE-2016-8610, due to the difference in alert handling
of the libraries (gnutls delegates that handling to applications).
-** libgnutls: Reverted the change which made the gnutls_certificate_set_*key*
+** libgnutls: Reverted the change which made the gnutls_certificate_set_*key*
functions return an index (introduced in 3.5.5), to avoid affecting programs
which explicitly check success of the function as equality to zero. In order
for these functions to return an index an explicit call to gnutls_certificate_set_flags
@@ -952,11 +959,11 @@ gnutls_session_get_master_secret: Added
** libgnutls: Removed support for pthread_atfork() as it has undefined
semantics when used with dlopen(), and may lead to a crash.
-** libgnutls: corrected failure when importing plain files
+** libgnutls: corrected failure when importing plain files
with gnutls_x509_privkey_import2(), and a password was provided.
** libgnutls: Don't reject certificates if a CA has the URI or IP address
- name constraints, and the end certificate doesn't have an IP address
+ name constraints, and the end certificate doesn't have an IP address
name or a URI set.
** libgnutls: set and read the hint in DHE-PSK and ECDHE-PSK ciphersuites.
@@ -1052,7 +1059,7 @@ explicitly enabled, since they reduce the overall security level.
** libgnutls: Added support for Chacha20-Poly1305 ciphersuites following
draft-mavrogiannopoulos-chacha-tls-05 and draft-irtf-cfrg-chacha20-poly1305-10.
That is currently provided as technology preview and is not enabled by
-default, since there are no assigned ciphersuite points by IETF and there
+default, since there are no assigned ciphersuite points by IETF and there
is no guarrantee of compatibility between draft versions. The ciphersuite
priority string to enable it is "+CHACHA20-POLY1305".
@@ -1104,14 +1111,14 @@ applications closing all open file descriptors on startup.
** libgnutls: If a key purpose (extended key usage) is specified for verification,
it is applied into intermediate certificates. The verification result
-GNUTLS_CERT_PURPOSE_MISMATCH is also introduced.
+GNUTLS_CERT_PURPOSE_MISMATCH is also introduced.
** libgnutls: When gnutls_certificate_set_x509_key_file2() is used in
combination with PKCS #11, or TPM URLs, it will utilize the provided
password as PIN if required. That removes the requirement for the
application to set a callback for PINs in that case.
-** libgnutls: priority strings VERS-TLS-ALL and VERS-DTLS-ALL are
+** libgnutls: priority strings VERS-TLS-ALL and VERS-DTLS-ALL are
restricted to the corresponding protocols only, and the VERS-ALL
string is introduced to catch all possible protocols.
@@ -1163,14 +1170,14 @@ when available.
** gnutls-cli: added options --priority-list and --save-cert.
-** guile: Deprecated priority API has been removed. The old priority API,
+** guile: Deprecated priority API has been removed. The old priority API,
which had been deprecated for some time, is now gone; use 'set-session-priorities!'
instead.
-** guile: Remove RSA parameters and related procedures. This API had been
-deprecated.
+** guile: Remove RSA parameters and related procedures. This API had been
+deprecated.
-** guile: Fix compilation on MinGW. Previously only the static version of the
+** guile: Fix compilation on MinGW. Previously only the static version of the
'guile-gnutls-v-2' library would be built, preventing dynamic loading from Guile.
** API and ABI modifications:
@@ -1300,7 +1307,7 @@ being usable after a reinitialization.
** libgnutls: fixed PKCS #11 ECDSA key generation.
-** libgnutls: The GNUTLS_CPUID_OVERRIDE environment variable can be used to
+** libgnutls: The GNUTLS_CPUID_OVERRIDE environment variable can be used to
explicitly enable/disable the use of certain CPU capabilities. Note that CPU
detection cannot be overridden, i.e., VIA options cannot be enabled on an Intel
CPU. The currently available options are:
@@ -1467,7 +1474,7 @@ were moved to self-test.h.
different recv and send pointers have been specified. Reported and
investigated by JMRecio.
-** libgnutls: Fixed issue in the RSA-PSK key exchange, which would
+** libgnutls: Fixed issue in the RSA-PSK key exchange, which would
result to illegal memory access if a server hint was provided. Reported
by André Klitzing.
@@ -1494,7 +1501,7 @@ That avoids long delays in gnutls initialization due to broken PKCS #11
modules.
** libgnutls: The PKCS #11 subsystem is re-initialized "automatically"
-on the first PKCS #11 API call after a fork.
+on the first PKCS #11 API call after a fork.
** libgnutls: certificate verification profiles were introduced
that can be specified as flags to verification functions. They
@@ -1508,15 +1515,15 @@ specified configuration file to be used to read pre-configured priority
strings from. That can be used to impose system specific policies.
** libgnutls: Increased the default security level of priority
-strings (NORMAL and PFS strings require at minimum a 1008 DH prime),
-and set a verification profile by default. The LEGACY keyword is
+strings (NORMAL and PFS strings require at minimum a 1008 DH prime),
+and set a verification profile by default. The LEGACY keyword is
introduced to set the old defaults.
** libgnutls: Added support for the name constraints PKIX extension.
Currently only DNS names and e-mails are supported (no URIs, IPs
or DNs).
-** libgnutls: Security parameter SEC_PARAM_NORMAL was renamed to
+** libgnutls: Security parameter SEC_PARAM_NORMAL was renamed to
SEC_PARAM_MEDIUM to avoid confusion with the priority string NORMAL.
** libgnutls: Added new API in x509-ext.h to handle X.509 extensions.
@@ -1573,7 +1580,7 @@ to SHA1.
That option enables (when running on FIPS140-enabled system):
o RSA, DSA and DH key generation as in FIPS-186-4 (using provable primes)
o The DRBG-CTR-AES256 deterministic random generator from SP800-90A.
- o Self-tests on initialization on ciphers/MACs, public key algorithms
+ o Self-tests on initialization on ciphers/MACs, public key algorithms
and the random generator.
o HMAC-SHA256 verification of the library on load.
o MD5 is included for TLS purposes but cannot be used by the high level
@@ -1685,7 +1692,7 @@ GCM mode is prioritized over CBC in all of the default priority strings.
** libgnutls: Added ciphersuite GNUTLS_ECDHE_RSA_AES_256_CBC_SHA384.
** libgnutls: Fixed ciphersuites GNUTLS_ECDHE_ECDSA_CAMELLIA_256_CBC_SHA384,
-GNUTLS_ECDHE_RSA_CAMELLIA_256_CBC_SHA384 and GNUTLS_PSK_CAMELLIA_128_GCM_SHA256.
+GNUTLS_ECDHE_RSA_CAMELLIA_256_CBC_SHA384 and GNUTLS_PSK_CAMELLIA_128_GCM_SHA256.
Reported by Stefan Buehler.
** libgnutls: Added support for ISO OID for RSA-SHA1 signatures.
@@ -1727,7 +1734,7 @@ by Christian Grothoff.
** srptool: Fixed index command line option. Patch by Attila Molnar.
** gnutls-cli: Added support for inline commands, using the
---inline-commands-prefix and --inline-commands options. Patch by Raj Raman.
+--inline-commands-prefix and --inline-commands options. Patch by Raj Raman.
** certtool: pathlen constraint is now read correctly. Reported by
Christoph Seitz.
@@ -1764,13 +1771,13 @@ gnutls_record_set_timeout: Exported
** libgnutls: Fixes in parsing of priority strings. Patch by Stefan Buehler.
-** libgnutls: Solve issue with received TLS packets that exceed 2^14.
+** libgnutls: Solve issue with received TLS packets that exceed 2^14.
(this fixes a bug that was accidentally introduced in 3.2.2)
** libgnutls: Removed gnulib modules under LGPLv3 that could possibly be
used by the library.
-** libgnutls: Fixes in gnutls_record_send_range(). Report and initial fix by
+** libgnutls: Fixes in gnutls_record_send_range(). Report and initial fix by
Alfredo Pironti.
** API and ABI modifications:
@@ -1835,7 +1842,7 @@ gnutls_session_set_id: Added
** libgnutls: Added UMAC-96 and UMAC-128
** libgnutls: Added ciphersuites involving Salsa20 and UMAC-96.
-As they are not standardized they are defined using private ciphersuite
+As they are not standardized they are defined using private ciphersuite
numbers.
** libgnutls: Added support for DTLS 1.2.
@@ -1856,7 +1863,7 @@ gnutls_mac_get_nonce_size: Added
* Version 3.1.10 (released 2013-03-22)
-** certtool: When generating PKCS #12 files use by default the
+** certtool: When generating PKCS #12 files use by default the
ARCFOUR (RC4) cipher to be compatible with devices that don't
support AES with PKCS #12.
@@ -1873,12 +1880,12 @@ cards are present.
** libgnutls: Corrected issue in the (deprecated) external key
signing interface, when used with TLS 1.2. Reported by Bjorn H. Christensen.
-** libgnutls: Fixes in openpgp handshake with fingerprints. Reported by
+** libgnutls: Fixes in openpgp handshake with fingerprints. Reported by
Joke de Buhr.
** libgnutls-dane: Updated DANE verification options.
-** configure: Trust store file must be explicitly set or unset when
+** configure: Trust store file must be explicitly set or unset when
cross compiling.
** API and ABI modifications:
@@ -1901,7 +1908,7 @@ a PKCS #12 file from an encrypted key file. Reported by Yan Fiz.
** libgnutls: Corrected issue in gnutls_pubkey_verify_data().
-** libgnutls: Corrected parsing issue in XMPP within a subject
+** libgnutls: Corrected parsing issue in XMPP within a subject
alternative name. Reported by James Cloos.
** libgnutls: gnutls_pkcs11_reinit() will reinitialize all PKCS #11
@@ -1932,7 +1939,7 @@ with encrypted keys. Reported by Yan Fiz.
PERFORMANCE was set to previous defaults 727 bits. Reported by Diego
Elio Petteno.
-** libgnutls: Corrected issue which prevented gnutls_pubkey_verify_hash()
+** libgnutls: Corrected issue which prevented gnutls_pubkey_verify_hash()
to operate with long keys. Reported by Erik A Jensen.
** API and ABI modifications:
@@ -1956,7 +1963,7 @@ in a template from an RFC4514 string.
** libgnutls: DN variable 'T' was expanded to 'title'.
-** libgnutls: Fixes in record padding parsing to prevent a timing attack.
+** libgnutls: Fixes in record padding parsing to prevent a timing attack.
Issue reported by Kenny Paterson and Nadhem Alfardan.
** libgnutls: Added functions to directly set the DN in a certificate
@@ -1972,17 +1979,17 @@ by the specified priority string. The current values correspond to the
previous defaults (727 bits), except for the SECURE128 and SECURE192
strings which increase the minimum to 1248 and 1776 respectively.
-** libgnutls: Added the gnutls_record_cork() and uncork API to enable
+** libgnutls: Added the gnutls_record_cork() and uncork API to enable
buffering in sending application data.
-** libgnutls: Removed default random padding, and added a length-hiding interface
-instead. Both the server and the client must support this extension. Whether
+** libgnutls: Removed default random padding, and added a length-hiding interface
+instead. Both the server and the client must support this extension. Whether
length-hiding can be used on a given session can be checked using
gnutls_record_can_use_length_hiding(). Contributed by Alfredo Pironti.
-** libgnutls: Added the experimental %NEW_PADDING priority string. It enables
+** libgnutls: Added the experimental %NEW_PADDING priority string. It enables
a new padding mechanism in TLS allowing arbitrary padding in TLS records
-in all ciphersuites, which makes length-hiding more efficient and solves
+in all ciphersuites, which makes length-hiding more efficient and solves
the issues with timing attacks on CBC ciphersuites.
** libgnutls: Corrected gnutls_cipher_decrypt2() when used with AEAD
@@ -2054,10 +2061,10 @@ extension.
** libgnutls: Handle BMPString (UCS-2) encoding in the Distinguished
Name by translating it to UTF-8 (works on windows or systems with iconv).
-** libgnutls: Added PKCS #11 key generation function that returns the
+** libgnutls: Added PKCS #11 key generation function that returns the
public key on generation.
-** libgnutls: Corrected bug in priority string parsing, that mostly
+** libgnutls: Corrected bug in priority string parsing, that mostly
affected combined levels. Patch by Tim Kosse.
** certtool: The --pubkey-info option can be combined with the
@@ -2065,7 +2072,7 @@ affected combined levels. Patch by Tim Kosse.
** certtool: It is able to set certificate policies via a template.
-** certtool: Added --hex-numbers option which prints big numbers in
+** certtool: Added --hex-numbers option which prints big numbers in
an easier to parse format.
** p11tool: After key generation, outputs the public key (useful in
@@ -2101,7 +2108,7 @@ gnutls_certificate_verify_peers3().
Contributed by Martin Storsjo.
** libgnutls: The X.509 verification functions check the key
-usage bits and pathlen constraints and on failure output
+usage bits and pathlen constraints and on failure output
GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE.
** libgnutls: gnutls_x509_crl_verify() includes the time checks.
@@ -2176,7 +2183,7 @@ GNUTLS_NO_EXTENSIONS can be used to prevent that.
is fully RFC6091 compliant and RFC5081 support is only supported in client
mode.
-** libgnutls-dane: Added. It is a library to provide DANE with DNSSEC
+** libgnutls-dane: Added. It is a library to provide DANE with DNSSEC
certificate verification.
** gnutls-cli: Added --dane option to enable DANE certificate verification.
@@ -2228,10 +2235,10 @@ of certificates in the windows platform.
** libgnutls: Added support for DTLS/TLS heartbeats by Olga Smolenchuk.
(the work was done during Google Summer of Code).
-** libgnutls: Added X.509 certificate verification flag
+** libgnutls: Added X.509 certificate verification flag
GNUTLS_VERIFY_ALLOW_UNSORTED_CHAIN. This flag allows the verification
of unsorted certificate chains and is enabled by default for
-TLS certificate verification (if gnutls_certificate_set_verify_flags()
+TLS certificate verification (if gnutls_certificate_set_verify_flags()
does not override it).
** libgnutls: Prints warning on certificates that contain keys of
@@ -2273,7 +2280,7 @@ GNUTLS_SEC_PARAM_INSECURE: Added
** certtool: Changes in password handling of certtool.
Ask password when required and only if the '--password' option is not
-given. If the '--password' option is given during key generation then
+given. If the '--password' option is given during key generation then
assume the PKCS #8 file format, instead of ignoring the password.
** tpmtool: No longer asks for key password in registered keys.
@@ -2302,7 +2309,7 @@ gnutls_sign_get_pk_algorithm: Added
* Version 3.1.0 (released 2012-08-15)
-** libgnutls: Added direct support for TPM as a cryptographic module
+** libgnutls: Added direct support for TPM as a cryptographic module
in gnutls/tpm.h. TPM keys can be used in functions accepting files
using URLs of the following types:
tpmkey:file=/path/to/file
@@ -2328,8 +2335,8 @@ the whole certificate chain (if any) to the credentials structure, instead
of only the end-user certificate.
** libgnutls: Key import functions such as gnutls_pkcs12_simple_parse()
-and gnutls_x509_privkey_import_pkcs8(), return consistently
-GNUTLS_E_DECRYPTION_FAILED if the input structure is encrypted but no
+and gnutls_x509_privkey_import_pkcs8(), return consistently
+GNUTLS_E_DECRYPTION_FAILED if the input structure is encrypted but no
password was provided.
** libgnutls: Added gnutls_handshake_set_timeout() a function that
@@ -2418,11 +2425,11 @@ No changes since last version.
* Version 3.0.21 (released 2012-07-02)
-** libgnutls: fixed bug in gnutls_x509_privkey_import()
+** libgnutls: fixed bug in gnutls_x509_privkey_import()
that prevented the loading of EC private keys when DER
encoded. Reported by David Woodhouse.
-** libgnutls: In DTLS larger to mtu records result to
+** libgnutls: In DTLS larger to mtu records result to
GNUTLS_E_LARGE_PACKET instead of being truncated.
** libgnutls: gnutls_dtls_get_data_mtu() is more precise. Based
@@ -2431,11 +2438,11 @@ on patch by David Woodhouse.
** libgnutls: Fixed memory leak in PKCS #8 key import.
** libgnutls: Added support for an old version of the DTLS protocol
-used by openconnect vpn client for compatibility with Cisco's AnyConnect
+used by openconnect vpn client for compatibility with Cisco's AnyConnect
SSL VPN. It is marked as GNUTLS_DTLS0_9. Do not use it for newer protocols
as it has issues.
-** libgnutls: Corrected bug that prevented resolving PKCS #11 URLs
+** libgnutls: Corrected bug that prevented resolving PKCS #11 URLs
if only the label is specified. Patch by David Woodhouse.
** libgnutls: When EMSGSIZE errno is seen then GNUTLS_E_LARGE_PACKET
@@ -2465,7 +2472,7 @@ name type in certtool.
** certtool: Increase to 128 the maximum number of distinct options
(e.g. dns_names) allowed.
-** gnutls-cli: If --print-cert is given, print the certificate,
+** gnutls-cli: If --print-cert is given, print the certificate,
even on verification failure.
** API and ABI modifications:
@@ -2482,7 +2489,7 @@ by David Smith.
** libgnutls: gnutls_record_check_pending() no longer
returns unprocessed data, and thus ensure the non-blocking
-of the next call to gnutls_record_recv().
+of the next call to gnutls_record_recv().
** libgnutls: Added strict tests in Diffie-Hellman and
SRP key exchange public keys.
@@ -2509,7 +2516,7 @@ is returned on premature termination (and added unit test).
** libgnutls: Fixes for W64 API. Patch by B. Scott Michel.
-** libgnutls: Corrected VIA padlock detection for old
+** libgnutls: Corrected VIA padlock detection for old
VIA processors. Reported by Kris Karas.
** libgnutls: Updated assembler files.
@@ -2544,7 +2551,7 @@ No changes since last version.
** libgnutls: included assembler files for MacOSX.
-** p11tool: Small fixes in handling of the --private command
+** p11tool: Small fixes in handling of the --private command
line option.
** certtool: The template option allows for setting the domain
@@ -2560,7 +2567,7 @@ gnutls_x509_crt_set_authority_info_access: Added
** test suite: Only run under valgrind in the development
system (the full git repository)
-** command line apps: Link with local libopts if the
+** command line apps: Link with local libopts if the
installed is an old one.
** libgnutls: Eliminate double free during SRP
@@ -2620,7 +2627,7 @@ status from an ocsp server.
** command line apps: Use gnu autogen (libopts) to parse command
line arguments and template files.
-** tests: Added stress test for DTLS packet losses and
+** tests: Added stress test for DTLS packet losses and
out-of-order receival. Contributed by Sean Buckheister.
** libgnutls: Several updates and corrections in the DTLS
@@ -2699,7 +2706,7 @@ correctly aligned in rare circumstances.
** libgnutls: Corrected memory leaks in DH parameter
generation and ecc_projective_check_point().
-** libgnutls: Added gnutls_x509_dn_oid_name() to
+** libgnutls: Added gnutls_x509_dn_oid_name() to
return a descriptive name of a DN OID.
** API and ABI modifications:
@@ -2745,7 +2752,7 @@ gnutls_ocsp_resp_verify: Added.
* Version 3.0.11 (released 2012-01-06)
-** libgnutls: Corrected functionality of
+** libgnutls: Corrected functionality of
gnutls_record_get_direction(). Reported by Philip Allison.
** libgnutls: Provide less timing information when decoding
@@ -2772,7 +2779,7 @@ issue in windows systems.
** libgnutls: Added ciphersuites: GNUTLS_PSK_WITH_AES_256_GCM_SHA384
and GNUTLS_DHE_PSK_WITH_AES_256_GCM_SHA384.
-** libgnutls: Added function gnutls_random_art() to convert
+** libgnutls: Added function gnutls_random_art() to convert
fingerprints to images (currently ascii-art).
** libgnutls: Corrected bug in DSA private key parsing, which
@@ -2855,13 +2862,13 @@ No changes since last version.
** gnutls-guile: Compilation fixes.
-** libgnutls: Fixed possible buffer overflow in
+** libgnutls: Fixed possible buffer overflow in
gnutls_session_get_data(). Reported and fix by Alban Crequy.
** libgnutls: Bug fixes in the ciphersuites with NULL cipher.
Reported by Fabrice Gautier.
-** libgnutls: Bug fixes in ECC code for 64-bit MIPS systems.
+** libgnutls: Bug fixes in ECC code for 64-bit MIPS systems.
Thanks to Joseph Graham for providing access to such a system.
** libgnutls: Correctly report ECC private key parsing errors.
@@ -2884,7 +2891,7 @@ No changes since last version.
** libgnutls: Corrections in VIA padlock code for VIA C5 processor
and new detection of PHE with support for partial hashing.
-** libgnutls: Corrected bug in gnutls_x509_data2hex. Report and fix
+** libgnutls: Corrected bug in gnutls_x509_data2hex. Report and fix
by Vincent Untz.
** minitasn1: Upgraded to libtasn1 version 2.10.
@@ -2902,7 +2909,7 @@ removed.
SHA256 and elliptic curves.
** gnutls-cli: Added --benchmark-soft-ciphers to benchmark
-the software version of the ciphers instead of hw accelerated
+the software version of the ciphers instead of hw accelerated
(where available)
** libgnutls: Public key ID calculation is consistent among
@@ -2917,13 +2924,13 @@ used with a gnutls_privkey_t and a gnutls_pcert_st
structure using gnutls_certificate_set_key().
** libgnutls: Fixes to enable external signing callback to
-operate with TLS 1.2.
+operate with TLS 1.2.
-** libgnutls: Fixed crash when printing ECDSA certificate key
+** libgnutls: Fixed crash when printing ECDSA certificate key
ID. Reported by Erik Jensen.
-** libgnutls: Corrected VIA padlock code for C3. In C3 benchmarks
-show a 50x increase in AES speed and a 14x increase in VIA nano. Added
+** libgnutls: Corrected VIA padlock code for C3. In C3 benchmarks
+show a 50x increase in AES speed and a 14x increase in VIA nano. Added
support for hashes and HMACs.
** libgnutls: Compilation fixed when p11-kit is not detected.
@@ -2955,13 +2962,13 @@ number of discarded records in a DTLS session.
** libgnutls: All functions related to RSA-EXPORT were deprecated.
Support for RSA-EXPORT ciphersuites will be ceased in future versions.
-** libgnutls: Memory leak fixes in credentials private key
+** libgnutls: Memory leak fixes in credentials private key
deinitialization. Reported by Dan Winship.
** libgnutls: Memory leak fixes in ECC ciphersuites.
-** libgnutls: Do not send an empty extension structure in server
-hello. This affected old implementations that do not support extensions.
+** libgnutls: Do not send an empty extension structure in server
+hello. This affected old implementations that do not support extensions.
Reported by J. Cameijo Cerdeira.
** libgnutls: Allow CA importing of 0 certificates to succeed.
@@ -2977,11 +2984,11 @@ PKCS #11.
** libgnutls: Added gnutls_pkcs11_privkey_generate()
to allow generating a key in a token.
-** p11tool: Added generate-rsa, generate-dsa and
+** p11tool: Added generate-rsa, generate-dsa and
generate-ecc options to allow generating private
keys in the token.
-** libgnutls: gnutls_transport_set_lowat dummy macro was
+** libgnutls: gnutls_transport_set_lowat dummy macro was
removed.
** API and ABI modifications:
@@ -3002,7 +3009,7 @@ by default.
** libgnutls: Corrected issue in gnutls_record_recv()
triggered on encryption or compression error.
-** libgnutls: Compatibility fixes in CPU ID detection
+** libgnutls: Compatibility fixes in CPU ID detection
for i386 and old GCC.
** gnutls-cli: Benchmark applications were incorporated
@@ -3025,16 +3032,16 @@ GNUTLS_PRIVKEY_IMPORT_COPY: new gnutls_privkey_import() flag
* Version 3.0.1 (released 2011-08-20)
-** libgnutls: gnutls_certificate_set_x509_key_file() and
-friends support server name indication. If multiple
-certificates are set using these functions the proper one
-will be selected during a handshake.
+** libgnutls: gnutls_certificate_set_x509_key_file() and
+friends support server name indication. If multiple
+certificates are set using these functions the proper one
+will be selected during a handshake.
** libgnutls: Added AES-256-GCM which was left out from
the previous release. Reported by Benjamin Hof.
-** libgnutls: When asking for a PKCS# 11 PIN multiple
-times, the flags in the callback were not being updated
+** libgnutls: When asking for a PKCS# 11 PIN multiple
+times, the flags in the callback were not being updated
to reflect for PIN low count or final try.
** libgnutls: Do not allow second instances of PKCS #11
@@ -3046,11 +3053,11 @@ modules.
is being read if provided.
** libgnutls: Ensure that a certificate list specified
-using gnutls_certificate_set_x509_key() and friends, is
+using gnutls_certificate_set_x509_key() and friends, is
sorted according to TLS specification (from subject to issuer).
** libgnutls: Added GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED flag for
-gnutls_x509_crt_list_import. It checks whether the list to be
+gnutls_x509_crt_list_import. It checks whether the list to be
imported is properly sorted.
** crywrap: Added to the distribution. It is an application
@@ -3109,10 +3116,10 @@ strings to enable the NSA SuiteB cryptography ciphersuites.
** libgnutls: Added gnutls_pubkey_verify_data2() that will
verify data provided the signature algorithm.
-** libgnutls: Simplified the handling of handshake messages to
-be hashed. Instead of hashing during the handshake process we now
-keep the data until handshake is over and hash them on request.
-This uses more memory but eliminates issues with TLS 1.2 and
+** libgnutls: Simplified the handling of handshake messages to
+be hashed. Instead of hashing during the handshake process we now
+keep the data until handshake is over and hash them on request.
+This uses more memory but eliminates issues with TLS 1.2 and
simplifies code.
** libgnutls: Added AES-GCM optimizations using the PCLMULQDQ
@@ -3204,7 +3211,7 @@ GNUTLS_PK_ECC: New public key algorithm
GNUTLS_SIGN_ECDSA_SHA1: New signature algorithm
GNUTLS_SIGN_ECDSA_SHA256: New signature algorithm
GNUTLS_SIGN_ECDSA_SHA384: New signature algorithm
-GNUTLS_SIGN_ECDSA_SHA512: New signature algorithm
+GNUTLS_SIGN_ECDSA_SHA512: New signature algorithm
GNUTLS_SIGN_ECDSA_SHA224: New signature algorithm
GNUTLS_ECC_CURVE_INVALID: New curve definition
GNUTLS_ECC_CURVE_SECP224R1: New curve definition
@@ -3222,7 +3229,7 @@ GNUTLS_ECC_CURVE_SECP521R1: New curve definition
** libgnutls: Added support for AES-NI if detected. Uses
Andy Polyakov's AES-NI code.
-** libgnutls: Restored HMAC-MD5 for compatibility. Although considered
+** libgnutls: Restored HMAC-MD5 for compatibility. Although considered
weak, several sites require it for connection. It is enabled for
"NORMAL" and "PERFORMANCE" priority strings.
@@ -3266,10 +3273,10 @@ by Todd A. Ouska.
every error and not only on fatal ones. This allows easier
handling of errors.
-** libgnutls: Corrected issue in DHE-PSK ciphersuites that ignored
+** libgnutls: Corrected issue in DHE-PSK ciphersuites that ignored
the PSK callback.
-** libgnutls: SRP and PSK are no longer set on the default priorities.
+** libgnutls: SRP and PSK are no longer set on the default priorities.
They have to be explicitly set.
** libgnutls: During handshake message verification using DSS
@@ -3284,7 +3291,7 @@ on unexpected EOF, instead of GNUTLS_E_UNEXPECTED_PACKET_LENGTH.
It was never standardized nor published as an RFC.
** libgnutls: Added new certificate verification functions, that
-can provide more details and are more efficient. Check
+can provide more details and are more efficient. Check
gnutls_x509_trust_list_*.
** certtool: Uses the new certificate verification functions for
@@ -3386,7 +3393,7 @@ the incompatibility with TLS other than 1.2.
** libgnutls: Modified signature algorithm selection in client
certificate request, to avoid failures in DSA certificates.
-** libgnutls: Instead of failing with internal error, return
+** libgnutls: Instead of failing with internal error, return
GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL if an incompatible DSA
key with the negotiated protocol is encountered.
@@ -3413,9 +3420,9 @@ gnutls_pubkey_import_openpgp: MODIFIED
replaced by gnutls_privkey_sign_hash2().
** libgnutls: gnutls_pubkey_verify_data, gnutls_pubkey_verify_hash,
-gnutls_x509_privkey_verify_data, gnutls_x509_crt_verify_data,
-gnutls_x509_crt_verify_hash return the negative error code
-GNUTLS_E_PK_SIG_VERIFY_FAILED if verification fails to simplify error
+gnutls_x509_privkey_verify_data, gnutls_x509_crt_verify_data,
+gnutls_x509_crt_verify_hash return the negative error code
+GNUTLS_E_PK_SIG_VERIFY_FAILED if verification fails to simplify error
checking.
** libgnutls: Added helper functions for signature verification:
@@ -3473,7 +3480,7 @@ gnutls_privkey_sign_hash: REMOVED (was added in 2.11.0)
SSL 3.0. To restore the previous default behavior use %LATEST_RECORD_VERSION
priority string.
-** libgnutls: Use ASN1_NULL when writing parameters for RSA signatures.
+** libgnutls: Use ASN1_NULL when writing parameters for RSA signatures.
This makes us comply with RFC3279. Reported by Michael Rommel.
** gnutls-serv: Corrected a buffer overflow. Reported and patch by Tomas Mraz.
@@ -3573,7 +3580,7 @@ backend crypto library.
** libgnutls: Several updates in the buffering internal interface.
-** libgnutls: Is now more liberal in the PEM decoding. That is spaces and
+** libgnutls: Is now more liberal in the PEM decoding. That is spaces and
tabs are being skipped.
** libgnutls: Added support for draft-pechanec-pkcs11uri-02.
@@ -3625,7 +3632,7 @@ jurisdictionOfIncorporationLocalityName,
jurisdictionOfIncorporationStateOrProvinceName,
jurisdictionOfIncorporationCountryName
-** libgnutls: Added support for DSA signing/verifying with bit
+** libgnutls: Added support for DSA signing/verifying with bit
length over 1024.
** libgnutls-extra: When in FIPS mode gnutls_global_init_extra()
@@ -3648,7 +3655,7 @@ imported from tokens, and operations can be performed on private keys.
** libgnutls: Added abstract gnutls_privkey_t and gnutls_pubkey_t
** libgnutls: Added initial support for the nettle library. It uses
-the system's random generator for seeding. That is /dev/urandom in Linux,
+the system's random generator for seeding. That is /dev/urandom in Linux,
system calls in Win32 and EGD on other systems.
** libgnutls: Corrected issue on the %SSL3_RECORD_VERSION priority string. It now
@@ -3868,8 +3875,8 @@ Instead new error code GNUTLS_E_UNKNOWN_SRP_USERNAME is added.
** certtool: Corrected two issues that affected certificate request generation.
(1) Null padding is added on integers (found thanks to Wilankar Trupti),
(2) In optional SignatureAlgorithm parameters field for DSA keys the DSA
-parameters were added. Those were rejected by Verisign. Gnutls no longer adds
-those parameters there since other implementations don't do either and having
+parameters were added. Those were rejected by Verisign. Gnutls no longer adds
+those parameters there since other implementations don't do either and having
them does not seem to offer anything (anyway you need the signer's certificate
to verify thus public key will be available). Found thanks to Boyan Kasarov.
This however has the side-effect that public key IDs shown by certtool are
@@ -3958,7 +3965,7 @@ with gnutls_sign_algorithm_get_requested() whether the certificate
they send complies with the peer's preferences in signature
algorithms.
-** libgnutls: In server side when resuming a session do not overwrite the
+** libgnutls: In server side when resuming a session do not overwrite the
** initial session data with the resumed session data.
** libgnutls: Added support for AES-128, AES-192 and AES-256 in PKCS #8
@@ -4201,7 +4208,7 @@ No changes since last version.
* Version 2.8.5 (released 2009-11-02)
-** libgnutls: In server side when resuming a session do not overwrite the
+** libgnutls: In server side when resuming a session do not overwrite the
** initial session data with the resumed session data.
** libgnutls: Fix PKCS#12 encoding.
@@ -4441,7 +4448,7 @@ The symbols are:
_gnutls*
gnutls_asn1_tab
-
+
Normally when symbols are removed, the shared library version has to
be incremented. This leads to a significant cost for everyone using
the library. Because none of the above symbols have ever been
@@ -4702,7 +4709,7 @@ Reported by Roman Bogorodskiy <novel@FreeBSD.org> in
It is currently only used by the core library. This will enable a new
domain 'gnutls' for translations of the command line tools.
-** Corrected possible memory corruption on signature verification failure.
+** Corrected possible memory corruption on signature verification failure.
Reported by Miroslav Kratochvil <exa.exa@gmail.com>
** API and ABI modifications:
@@ -4732,8 +4739,8 @@ information. This avoids code duplication.
They can be used to override the default certificate chain validation
behaviour.
-** libgnutls: Added %SSL3_RECORD_VERSION priority string that allows to
-specify the client hello message record version. Used to overcome buggy
+** libgnutls: Added %SSL3_RECORD_VERSION priority string that allows to
+specify the client hello message record version. Used to overcome buggy
TLS servers. Report by Martin von Gagern.
** libgnutls: gnutls_x509_crt_print prints signature algorithm in oneline mode.
@@ -5912,7 +5919,7 @@ The crash can be triggered remotely before authentication, which can
lead to a Daniel of Service attack to disable the server. The bug
cause gnutls to read memory beyond the end of the received record.
-** libgnutlsxx: Updated API according to patches from Eduardo
+** libgnutlsxx: Updated API according to patches from Eduardo
Villanueva Che (discussion at
<http://lists.gnu.org/archive/html/gnutls-devel/2007-02/msg00017.html>)
@@ -6098,7 +6105,7 @@ gnutls_openpgp_crt_get_auth_subkey: MODIFIED
** Finish renaming of gnutls_certificate_export_x509_cas etc.
They weren't renamed in the public header file.
-** Added functions to register a cipher/mac/digest. This allows to
+** Added functions to register a cipher/mac/digest. This allows to
override the included ones.
** Fix a bunch of compiler warnings.
@@ -6658,7 +6665,7 @@ No changes since last version.
* Version 2.1.4 (released 2007-10-27)
** Added the --v1 option to certtool, to allow generating X.509
-version 1 certificates.
+version 1 certificates.
** certtool: Add option --disable-quick-random to enable the old behaviour
of using /dev/random to generate keys.
@@ -6668,7 +6675,7 @@ of using /dev/random to generate keys.
** Added gnutls_set_default_priority2() which accepts a flag to indicate
priorities preferences.
-** Added gnutls_record_disable_padding() to allow servers talking to
+** Added gnutls_record_disable_padding() to allow servers talking to
buggy clients that complain if the TLS 1.0 record protocol padding is
used.
@@ -6816,7 +6823,7 @@ gnutls_oprfi_enable_server: ADD, new function.
* Version 2.0.4 (released 2007-11-16)
-** Corrected bug in decompression of expanded compression data.
+** Corrected bug in decompression of expanded compression data.
** API and ABI modifications:
No changes since last version.
@@ -7963,13 +7970,13 @@ Protover SSL. Libtasn1 0.2.18 is now required, which contains the
previous bug fix. The included libtasn1 version in GnuTLS has been
updated.
-** Fixed bug in non-blocking gnutls_bye(). gnutls_record_send() will no
-longer invalidate a session if the underlying send fails, but it will
+** Fixed bug in non-blocking gnutls_bye(). gnutls_record_send() will no
+longer invalidate a session if the underlying send fails, but it will
prevent future writes. That is to allow reading the already received data.
Patches and bug reports by Yoann Vandoorselaere <yoann@prelude-ids.org>
** Corrected bugs in gnutls_certificate_set_x509_crl() and
-gnutls_certificate_set_x509_trust(), that caused memory corruption if
+gnutls_certificate_set_x509_trust(), that caused memory corruption if
more than one certificates were added. Report and patch by Max Kellermann.
** Fix build problems of OpenCDK on AIX.
@@ -8244,8 +8251,8 @@ Use size_t instead of int for output size parameter:
- Corrected bugs in gnutls_certificate_set_x509_crl() and
gnutls_certificate_set_x509_trust(), that caused memory corruption if
more than one certificates were added. Report and patch by Max Kellermann.
-- Fixed bug in non-blocking gnutls_bye(). gnutls_record_send() will no
- longer invalidate a session if the underlying send fails, but it will
+- Fixed bug in non-blocking gnutls_bye(). gnutls_record_send() will no
+ longer invalidate a session if the underlying send fails, but it will
prevent future writes. That is to allow reading the already received data.
Patches and bug reports by Yoann Vandoorselaere <yoann@prelude-ids.org>
@@ -8361,7 +8368,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
<dalgoda@ix.netcom.com>.
- Fixed off-by-one bug in the size parameter of gnutls_x509_crt_get*_dn,
reported by Adam Langley <alangley@gmail.com>.
-- Corrected some stuff in minilzo detection. Pointed out by
+- Corrected some stuff in minilzo detection. Pointed out by
Sergey Lipnevich.
- MiniLZO updated to version 2.00.
- gnutls_x509_crt_list_import now accept a DER formatted CRL.
@@ -8424,7 +8431,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
<pierre42d@9online.fr>.
- Eliminated some memory leaks in DHE and RSA-EXPORT cipher suites.
Reported by Yoann Vandoorselaere <yoann@prelude-ids.org>.
-- If the library has been compiled with features disabled, a warning is
+- If the library has been compiled with features disabled, a warning is
issued during the compilation of any program.
- API and ABI modifications:
gnutls_x509_crt_list_import(): Add
@@ -8436,7 +8443,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
* Version 1.2.0 (2005-01-27)
- Added the definitions and OIDs for the RIPEMD-160 hash algorithm.
-- Introduced gnutls_x509_crt_sign2(), gnutls_x509_crq_sign2() and
+- Introduced gnutls_x509_crt_sign2(), gnutls_x509_crq_sign2() and
gnutls_x509_crl_sign2().
- Fixed license header in source code files.
@@ -8560,14 +8567,14 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- Changed the makefiles to be more portable.
- SRP ciphersuites were moved to the gnutls library.
- Added some default limits in the verification of certificate
- chains, to avoid denial of service attacks. Also added
+ chains, to avoid denial of service attacks. Also added
gnutls_certificate_set_verify_limits() to override them.
Issue pointed out by Patrik Hornik <patrik@hornik.sk>.
- Added gnutls_certificate_verify_peers2().
* Version 1.1.11 (2004-07-16)
- Added the '_t' suffix to all exported symbols.
-- Fixed bug in RSA encryption, report and patch by Martijn Koster
+- Fixed bug in RSA encryption, report and patch by Martijn Koster
<mak@greenhills.co.uk>.
- Corrected a bug in certificate verification. Pointed out by
Yoann Vandoorselaere <yoann@prelude-ids.org>
@@ -8575,7 +8582,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
verification functions.
- The ephemeral DH and RSA parameters are no longer stored in the
session resume DB.
-- Do not free the SRP (prime and generator) parameters obtained from the
+- Do not free the SRP (prime and generator) parameters obtained from the
callback if they are the static ones defined in extra.h
- Eliminated some memory leaks. Reported by Yoann Vandoorselaere.
@@ -8621,14 +8628,14 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- Optimized the copying of rsa_params.
* Version 1.1.7 (2004-03-29)
-- Added gnutls_certificate_set_params_function() and
+- Added gnutls_certificate_set_params_function() and
gnutls_anon_set_params_function() that set the RSA or DH
parameters using a callback.
- Added functions gnutls_rsa_params_cpy(), gnutls_dh_params_cpy()
and gnutls_x509_privkey_cpy().
- Corrected a compilation issue when opencdk was installed in a
non standard directory.
-- Deprecated: gnutls_srp_server_set_select_function(),
+- Deprecated: gnutls_srp_server_set_select_function(),
gnutls_certificate_client_set_select_function(), gnutls_srp_server_set_select_function().
* Version 1.1.6 (2004-02-24)
@@ -8740,19 +8747,19 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
compatibility with previous versions.
- Changed the makefiles to be more portable.
- Added some default limits in the verification of certificate
- chains, to avoid denial of service attacks. Also added
+ chains, to avoid denial of service attacks. Also added
gnutls_certificate_set_verify_limits() to override them.
Issue pointed out by Patrik Hornik <patrik@hornik.sk>.
- Added gnutls_certificate_verify_peers2().
* Version 1.0.16 (2004-07-10)
-- Do not free the SRP (prime and generator) parameters obtained from the
+- Do not free the SRP (prime and generator) parameters obtained from the
callback if they are the static ones defined in extra.h.
- Eliminated some memory leaks. Reported by Yoann Vandoorselaere.
- Some fixes in the makefiles.
* Version 1.0.15 (2004-06-29)
-- Fixed bug in RSA encryption, report and patch by Martijn Koster
+- Fixed bug in RSA encryption, report and patch by Martijn Koster
<mak@greenhills.co.uk>.
- Corrected a bug in certificate verification. Pointed out by
Yoann Vandoorselaere <yoann@prelude-ids.org>.
@@ -8796,7 +8803,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- Corrected bug in SSL 3.0 authentication.
* Version 1.0.9 (2004-03-29)
-- Added gnutls_certificate_set_params_function() and
+- Added gnutls_certificate_set_params_function() and
gnutls_anon_set_params_function() that set the RSA or DH
parameters using a callback.
- Added functions gnutls_rsa_params_cpy(), gnutls_dh_params_cpy()
@@ -8875,7 +8882,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
* Version 0.9.99 (2003-11-28)
- Some fixes in the gnutls.h header for the gnutls_server_name_set()
and gnutls_server_name_get() prototypes.
-- Exported the gnutls_x509_privkey_sign_data(), gnutls_x509_privkey_verify_data()
+- Exported the gnutls_x509_privkey_sign_data(), gnutls_x509_privkey_verify_data()
and gnutls_x509_crt_verify_data().
- Some fixes in the openpgp authentication.
- Removed the Twofish cipher.
@@ -8914,7 +8921,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
* Version 0.9.94 (2003-10-30)
- Added manpages for the included programs.
-- Documented and improved the certtool utility.
+- Documented and improved the certtool utility.
- Added PKCS #12 support to certtool utility.
* Version 0.9.93 (2003-10-26)
@@ -8946,7 +8953,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- The library can now decrypt PKCS #12 files encrypted with
the RC2-40 cipher.
- The missing rfc2818_hostname object is now included.
-- Several corrections and bug fixes in the library by
+- Several corrections and bug fixes in the library by
Arne Thomassen <arne@arne-thomassen.de>.
- CR is now allowed in the base64 decoder.
@@ -8977,7 +8984,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- Added functionality to generate PKCS #7 structures (with certificates).
* Version 0.9.3 (2003-03-24)
-- Support for MD2 was dropped.
+- Support for MD2 was dropped.
- Improved the error logging functions, by adding a level, and
by allowing debugging messages just by increasing the level.
- The diffie Hellman ciphersuites are now of higher priority than
@@ -8986,18 +8993,18 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- Implemented the counter measure discussed in the paper "Attacking
RSA-based Sessions in SSL/TLS", against the attack described in the
same paper.
-- Added the functions: gnutls_handshake_get_last_in(),
+- Added the functions: gnutls_handshake_get_last_in(),
gnutls_handshake_get_last_out().
-- The gnutls_certificate_set_rsa_params() was renamed to
+- The gnutls_certificate_set_rsa_params() was renamed to
gnutls_certificate_set_rsa_export_params().
- Added the new functions: gnutls_certificate_set_x509_key()
gnutls_certificate_set_x509_trust(), gnutls_certificate_set_x509_crl(),
gnutls_x509_crt_export(), gnutls_x509_crl_export().
-- Added support for encoding and decoding PKCS #8 2.0 encrypted
+- Added support for encoding and decoding PKCS #8 2.0 encrypted
RSA private keys.
* Version 0.9.2 (2003-03-15)
-- Some corrections in the memory mapping code (file is unmapped after
+- Some corrections in the memory mapping code (file is unmapped after
it is read).
- Added support for PKCS#10 certificate requests generation.
@@ -9015,27 +9022,27 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- Added an strnstr() function and the requirement in some functions to
use null terminated PEM structures is no more.
- Use mmap() if available to read files.
-- Fixed a memory leak in SRP code reported by Rupert Kittinger
+- Fixed a memory leak in SRP code reported by Rupert Kittinger
<r.kittinger@efkon.com>.
* Version 0.9.0 (2003-03-03)
- This version is not binary compatible with the previous ones.
-- The library notifies the application on empty and illegal SRP usernames,
+- The library notifies the application on empty and illegal SRP usernames,
so that proper notification (via an alert) is sent to the peer.
- Added ability to send some messages back to the application using
the gnutls_global_set_log_function().
-- gnutls_dh_params_generate() and gnutls_rsa_params_generate() now use
+- gnutls_dh_params_generate() and gnutls_rsa_params_generate() now use
gnutls_malloc() to allocate the output parameters.
- Added support for MD2 algorithm in certificate signature verification.
- The RSA and DH parameter generation interface was changed. Added
- ability to import and export from and to PKCS3 structures. This
+ ability to import and export from and to PKCS3 structures. This
was needed to read parameters generated using the openssl dhparam tool.
-- Several changes in the temporary (DH/RSA) parameter codebase. No DH
- parameters are now included in the library. Also the credentials structure
+- Several changes in the temporary (DH/RSA) parameter codebase. No DH
+ parameters are now included in the library. Also the credentials structure
can now hold only one temporary parameter of a kind.
-- Added a new Certificate, CRL, Private key and PKCS7 structures handling
+- Added a new Certificate, CRL, Private key and PKCS7 structures handling
API, defined in gnutls/x509.h
-- Added gnutls_certificate_set_verify_flags() function to allow setting the
+- Added gnutls_certificate_set_verify_flags() function to allow setting the
verification flags in the credentials structure. They will be used in the
*verify_peers functions.
- Added protection against the new TLS 1.0 record layer timing attack.
@@ -9053,19 +9060,19 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- Some fixes which now allow compilation.
* Version 0.8.0 (2003-01-20)
-- Added gnutls_x509_extract_dn_string() which returns a
+- Added gnutls_x509_extract_dn_string() which returns a
distinguished name in a single string.
- Added gnutls_openpgp_extract_key_name_string() which returns
an openpgp user ID in a single string.
- Added gnutls_x509_extract_certificate_ca_status() which returns
the CA status of the given certificate.
- Added SRP-6 support. Follows draft-ietf-tls-srp-04.
-- If libtasn1 is not present in the system, it is included in
+- If libtasn1 is not present in the system, it is included in
the main gnutls library.
- If liblzo is present in the system, then the included minilzo
will not be used, and libgnutls-extra will depend on liblzo.
-- GNUTLS_E_PARSING_ERROR error code was replaced by GNUTLS_E_BASE64_DECODING_ERROR,
- and GNUTLS_E_SRP_PWD_PARSING_ERROR. GNUTLS_E_ASCII_ARMOR_ERROR was also
+- GNUTLS_E_PARSING_ERROR error code was replaced by GNUTLS_E_BASE64_DECODING_ERROR,
+ and GNUTLS_E_SRP_PWD_PARSING_ERROR. GNUTLS_E_ASCII_ARMOR_ERROR was also
replaced by GNUTLS_E_BASE64_DECODING_ERROR.
* Version 0.6.0 (2002-12-08)
@@ -9095,7 +9102,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
these are binary compatible.
* Version 0.5.11 (2002-11-05)
-- Some fixes in 'gnutls-cli' client program to prevent some segmentation
+- Some fixes in 'gnutls-cli' client program to prevent some segmentation
faults at exit.
- Example programs found in the documentation can now be generated by
running "make examples" in doc/tex directory.
@@ -9121,7 +9128,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
starttls implementations.
- Added gnutls_x509_extract_key_pk_algorithm() function which extracts
the private key type, of a DER encoded key.
-- Added gnutls_x509_extract_certificate_dn_string() which returns the
+- Added gnutls_x509_extract_certificate_dn_string() which returns the
certificate's distinguished name in a single string.
- Added gnutls_set_default_priority() and gnutls_set_default_export_priority()
functions, to avoid calling all the *_priority() functions if the defaults
@@ -9145,7 +9152,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- Corrected bug in session resuming code in server side.
* Version 0.5.6 (2002-09-06)
-- Corrected bugs in SRP implementation, which prevented gnutls
+- Corrected bugs in SRP implementation, which prevented gnutls
to interoperate with other implementations. (interoperability testing
was done by David Taylor)
- Corrected bug in cert_type extension.
@@ -9157,10 +9164,10 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
* Version 0.5.5 (2002-09-03)
- Updated the SRP implementation to the latest draft. The blowfish
crypt implementation was removed, since the new draft does not allow
- other hash algorithms except for the srpsha.
+ other hash algorithms except for the srpsha.
- Renamed all the constructed types in order to have more consistent
- names.
-- Improved the certificate and key read functions. Now they can read
+ names.
+- Improved the certificate and key read functions. Now they can read
the certificate and the private key from the same file.
- Updated and corrected documentation.
@@ -9190,7 +9197,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
<gnutls/gnutls.h>
- Documentation fixes
- Added gnutls_transport_set_ptr2() function, which accepts two
- different pointers, to be used while receiving, and
+ different pointers, to be used while receiving, and
while sending data.
- Semantic changes in gnutls_record_set_max_size(). The requested
size is now immediately enforced at the output buffers.
@@ -9272,15 +9279,15 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- Corrections in session resumption
- Rehandshake can now handle negotiation of different authentication
type.
-- gnutls-cli, gnutls-serv, gnutls-srpcrypt and gnutls-cli-debug are
+- gnutls-cli, gnutls-serv, gnutls-srpcrypt and gnutls-cli-debug are
now being installed.
* Version 0.3.90 (2002-02-24)
-- Handshake messages are not kept in memory any more. Now we use
+- Handshake messages are not kept in memory any more. Now we use
less memory during a handshake
- Added support for certificates with DSA parameters
- Added DHE_DSS cipher suites
-- Key exchange methods changed so they do not depend on the
+- Key exchange methods changed so they do not depend on the
certificate type. Added certificate type negotiation TLS extension.
- Added openpgp key support (EXPERIMENTAL)
- Improved Diffie Hellman key exchange support.
@@ -9289,7 +9296,7 @@ LIBGNUTLS_VERSION_NUMBER: New CPP symbols, indicating the GnuTLS
- TLS extensions now use a 16 bit type field.
- Added a minimal string library to assist in ASN.1 parsing
- Changes in ASN.1 parser to work with the new bison
-- Added gnutls_x509_extract_subject_alt_name(), which deprecates
+- Added gnutls_x509_extract_subject_alt_name(), which deprecates
gnutls_x509_extract_subject_dns_name()
- gnutls_x509_set_trust_(file/mem) can now be called multiple times
- gnutls_srp_server_set_cred_file() can now be called multiple times
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 8a9a712091..59b3e67e5b 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -763,6 +763,10 @@ FUNCS += functions/gnutls_certificate_set_params_function
FUNCS += functions/gnutls_certificate_set_params_function.short
FUNCS += functions/gnutls_certificate_set_pin_function
FUNCS += functions/gnutls_certificate_set_pin_function.short
+FUNCS += functions/gnutls_certificate_set_rawpk_key_file
+FUNCS += functions/gnutls_certificate_set_rawpk_key_file.short
+FUNCS += functions/gnutls_certificate_set_rawpk_key_mem
+FUNCS += functions/gnutls_certificate_set_rawpk_key_mem.short
FUNCS += functions/gnutls_certificate_set_retrieve_function
FUNCS += functions/gnutls_certificate_set_retrieve_function.short
FUNCS += functions/gnutls_certificate_set_retrieve_function2
@@ -1265,6 +1269,10 @@ FUNCS += functions/gnutls_pcert_import_openpgp
FUNCS += functions/gnutls_pcert_import_openpgp.short
FUNCS += functions/gnutls_pcert_import_openpgp_raw
FUNCS += functions/gnutls_pcert_import_openpgp_raw.short
+FUNCS += functions/gnutls_pcert_import_rawpk
+FUNCS += functions/gnutls_pcert_import_rawpk.short
+FUNCS += functions/gnutls_pcert_import_rawpk_raw
+FUNCS += functions/gnutls_pcert_import_rawpk_raw.short
FUNCS += functions/gnutls_pcert_import_x509
FUNCS += functions/gnutls_pcert_import_x509.short
FUNCS += functions/gnutls_pcert_import_x509_list
diff --git a/doc/cha-cert-auth.texi b/doc/cha-cert-auth.texi
index 0a9da1c9f8..8695415a9a 100644
--- a/doc/cha-cert-auth.texi
+++ b/doc/cha-cert-auth.texi
@@ -53,6 +53,7 @@ to use this key exchange algorithm.
@menu
* X.509 certificates::
* OpenPGP certificates::
+* Raw public-keys::
* Advanced certificate verification::
* Digital signatures::
@end menu
@@ -478,6 +479,37 @@ use-cases, is a distraction that consumes considerable resources for
improving and testing the library. For that we have decided to drop
this functionality completely in 3.6.0.
+@node Raw public-keys
+@subsection Raw public-keys
+@cindex Raw public-keys
+
+There are situations in which a rather large certificate / certificate chain is undesirable or impractical.
+An example could be a resource contrained sensor network in which you do want to use authentication of and
+encryption between your devices but where your devices lack loads of memory or processing power. Furthermore,
+there are situations in which you don't want to or can't rely on a PKIX. TLS is, next to a PKIX environment,
+also commonly used with self-signed certificates in smaller deployments where the self-signed certificates
+are distributed to all involved protocol endpoints out-of-band. This practice does, however, still require
+the overhead of the certificate generation even though none of the information found in the certificate is
+actually used.
+
+With raw public-keys, only a subset of the information found in typical certificates is utilized: namely,
+the SubjectPublicKeyInfo structure (in ASN.1 format) of a PKIX certificate that carries the parameters
+necessary to describe the public-key. Other parameters found in PKIX certificates are omitted. By omitting
+various certificate-related structures, the resulting raw public-key is kept fairly small in comparison to
+the original certificate, and the code to process the keys can be simpler.
+
+It should be noted however, that the authenticity of these raw keys must be verified by an out-of-band mechanism
+or something like @acronym{TOFU}.
+
+@menu
+* Importing raw public-keys::
+@end menu
+
+@node Importing raw public-keys
+@subsubsection Importing raw public-keys
+Raw public-keys and their private counterparts can best be handled by using the abstract types
+@code{gnutls_pubkey_t} and @code{gnutls_privkey_t} respectively. To learn how to use these
+see @ref{Abstract key types}.
@node Advanced certificate verification
@subsection Advanced certificate verification
diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi
index 5d72707dfa..028d1ab778 100644
--- a/doc/cha-gtls-app.texi
+++ b/doc/cha-gtls-app.texi
@@ -476,6 +476,7 @@ current session using @funcref{gnutls_credentials_set}.
@menu
* Certificate credentials::
+* Raw public-key credentials::
* SRP credentials::
* PSK credentials::
* Anonymous credentials::
@@ -492,7 +493,7 @@ with the credential types is shown in @ref{tab:key-exchange-cred}.
@headitem Authentication method @tab Key exchange @tab Client credentials @tab Server credentials
-@item Certificate
+@item Certificate and Raw public-key
@tab @code{KX_RSA},
@code{KX_DHE_RSA},
@code{KX_DHE_DSS},
@@ -537,6 +538,10 @@ a pair, but a server could require it. In this section we discuss
general issues applying to both client and server certificates. The next
section will elaborate on issues arising from client authentication only.
+In order to use certificate credentials one must first initialize a credentials
+structure of type @code{gnutls_certificate_credentials_t}. After use this structure must
+be freed. This can be done with the following functions.
+
@showfuncB{gnutls_certificate_allocate_credentials,gnutls_certificate_free_credentials}
After the credentials structures are initialized, the certificate
@@ -578,7 +583,7 @@ In that case a certificate should be selected according the peer's signature
algorithm preferences. To get those preferences use
@funcref{gnutls_sign_algorithm_get_requested}. Both functions are shown below.
-@showfuncC{gnutls_certificate_set_retrieve_function,gnutls_certificate_set_retrieve_function2,gnutls_sign_algorithm_get_requested}
+@showfuncD{gnutls_certificate_set_retrieve_function,gnutls_certificate_set_retrieve_function2,gnutls_certificate_set_retrieve_function3,gnutls_sign_algorithm_get_requested}
The functions above do not handle the requested server name automatically.
A server would need to check the name requested by the client
@@ -613,8 +618,8 @@ available in certificate authentication.
@subsubheading Client certificate authentication
If a certificate is to be requested from the client during the handshake, the server
-will send a certificate request message. This behavior is controlled @funcref{gnutls_certificate_server_set_request}.
-The request contains a list of the acceptable by the server certificate signers. This list
+will send a certificate request message. This behavior is controlled by @funcref{gnutls_certificate_server_set_request}.
+The request contains a list of the by the server accepted certificate signers. This list
is constructed using the trusted certificate authorities of the server.
In cases where the server supports a large number of certificate authorities
it makes sense not to advertise all of the names to save bandwidth. That can
@@ -640,6 +645,7 @@ using the @code{GNUTLS_FORCE_CLIENT_CERT} flag in @funcref{gnutls_init}.
@showfuncC{gnutls_certificate_set_x509_key_file,gnutls_certificate_set_x509_simple_pkcs12_file,gnutls_certificate_set_retrieve_function2}
+
@subsubheading Client or server certificate verification
Certificate verification is possible by loading the trusted
@@ -671,6 +677,22 @@ can be printed using @funcref{gnutls_certificate_verification_status_print}.
@showfuncB{gnutls_certificate_verify_peers3,gnutls_certificate_set_verify_function}
+Note that when using raw public-keys verification will not work because there is no corresponding
+certificate body belonging to the raw key that can be verified. In that case the @funcref{gnutls_certificate_verify_peers}
+family of functions will return a GNUTLS_E_INVALID_REQUEST error code. For authenticating raw public-keys
+one must use an out-of-band mechanism, e.g. by comparing hashes or using trust on first use
+(see @ref{Verifying a certificate using trust on first use authentication}).
+
+
+@node Raw public-key credentials
+@subsection Raw public-keys
+As of version 3.6.6 GnuTLS supports @ref{Raw public-keys}. With raw public-keys only the
+public-key part (that is normally embedded in a certificate) is transmitted to the peer.
+In order to load a raw public-key and its corresponding private key in a credentials
+structure one can use the following functions.
+
+@showfuncC{gnutls_certificate_set_key,gnutls_certificate_set_rawpk_key_mem,gnutls_certificate_set_rawpk_key_file}
+
@node SRP credentials
@subsection SRP
@@ -1438,16 +1460,16 @@ that the CURVE keyword is kept for backwards compatibility only, for new
applications see the GROUP keyword above.
@item Certificate types @tab
-Certificate type negotitation must be explicitly enabled via the
-GNUTLS_ENABLE_CERT_TYPE_NEG flag in gnutls_init().
Certificate types can be given in a symmetric fashion (i.e. the same for
both client and server) or, as of GnuTLS 3.6.4, in an asymmetric fashion
-(i.e. different for the client than for the server).
-
-Currently supported types are:
-CTYPE-X509 or CTYPE-X.509. Catch all is CTYPE-ALL.
-CTYPE-CLI-X509 or CTYPE-CLI-X.509, CTYPE-SRV-X509 or CTYPE-SRV-X.509.
-Catch all is CTYPE-CLI-ALL and CTYPE-SRV-ALL.
+(i.e. different for the client than for the server). Alternative certificate
+types must be explicitly enabled via flags in @funcref{gnutls_init}.
+
+The currently supported types are CTYPE-X509, CTYPE-RAWPK which apply both to
+client and server; catch all is CTYPE-ALL. The types CTYPE-CLI-X509, CTYPE-SRV-X509,
+CTYPE-CLI-RAWPK, CTYPE-SRV-RAWPK can be used to specialize on client or server;
+catch all is CTYPE-CLI-ALL and CTYPE-SRV-ALL. The type 'X509' is aliased to 'X.509'
+for legacy reasons.
@end multitable
@caption{The supported algorithm keywords in priority strings.}
diff --git a/doc/cha-tokens.texi b/doc/cha-tokens.texi
index d984afcc4d..529829bf29 100644
--- a/doc/cha-tokens.texi
+++ b/doc/cha-tokens.texi
@@ -80,8 +80,12 @@ gnutls_privkey_t abs_key;
@node Abstract public keys
@subsection Public keys
-An abstract @code{gnutls_pubkey_t} can be initialized
-using the functions below. It can be imported through
+An abstract @code{gnutls_pubkey_t} can be initialized and freed by
+using the functions below.
+
+@showfuncB{gnutls_pubkey_init,gnutls_pubkey_deinit}
+
+After initialization its values can be imported from
an existing structure like @code{gnutls_x509_crt_t},
or through an ASN.1 encoding of the X.509 @code{SubjectPublicKeyInfo}
sequence.
@@ -120,8 +124,12 @@ To export the key-specific parameters, or obtain a unique key ID the following f
@node Abstract private keys
@subsection Private keys
-An abstract @code{gnutls_privkey_t} can be initialized
-using the functions below. It can be imported through
+An abstract @code{gnutls_privkey_t} can be initialized and freed by
+using the functions below.
+
+@showfuncB{gnutls_privkey_init,gnutls_privkey_deinit}
+
+After initialization its values can be imported from
an existing structure like @code{gnutls_x509_privkey_t},
but unlike public keys it cannot be exported. That is
to allow abstraction over keys stored in hardware that
diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am
index 7db892d880..2ef5b5bcee 100644
--- a/doc/manpages/Makefile.am
+++ b/doc/manpages/Makefile.am
@@ -183,6 +183,8 @@ APIMANS += gnutls_certificate_set_ocsp_status_request_function2.3
APIMANS += gnutls_certificate_set_ocsp_status_request_mem.3
APIMANS += gnutls_certificate_set_params_function.3
APIMANS += gnutls_certificate_set_pin_function.3
+APIMANS += gnutls_certificate_set_rawpk_key_file.3
+APIMANS += gnutls_certificate_set_rawpk_key_mem.3
APIMANS += gnutls_certificate_set_retrieve_function.3
APIMANS += gnutls_certificate_set_retrieve_function2.3
APIMANS += gnutls_certificate_set_retrieve_function3.3
@@ -434,6 +436,8 @@ APIMANS += gnutls_pcert_export_openpgp.3
APIMANS += gnutls_pcert_export_x509.3
APIMANS += gnutls_pcert_import_openpgp.3
APIMANS += gnutls_pcert_import_openpgp_raw.3
+APIMANS += gnutls_pcert_import_rawpk.3
+APIMANS += gnutls_pcert_import_rawpk_raw.3
APIMANS += gnutls_pcert_import_x509.3
APIMANS += gnutls_pcert_import_x509_list.3
APIMANS += gnutls_pcert_import_x509_raw.3
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 32a8511b33..e7c5c7f40e 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -80,7 +80,7 @@ COBJECTS = range.c record.c compress.c debug.c cipher.c gthreads.h handshake-tls
system-keys.h urls.c urls.h prf.c auto-verify.c dh-session.c \
cert-session.c handshake-checks.c dtls-sw.c dh-primes.c openpgp_compat.c \
crypto-selftests.c crypto-selftests-pk.c secrets.c extv.c extv.h \
- hello_ext_lib.c hello_ext_lib.h ocsp-api.c stek.c
+ hello_ext_lib.c hello_ext_lib.h ocsp-api.c stek.c cert-cred-rawpk.c
if WINDOWS
COBJECTS += system/keys-win.c
@@ -124,7 +124,7 @@ HFILES = abstract_int.h debug.h cipher.h \
srp.h auth/srp_kx.h auth/srp_passwd.h \
file.h supplemental.h crypto.h random.h system.h\
locks.h mbuffers.h ecc.h pin.h fips.h \
- priority_options.h secrets.h stek.h
+ priority_options.h secrets.h stek.h cert-cred.h
if ENABLE_PKCS11
HFILES += pkcs11_int.h pkcs11x.h
@@ -216,7 +216,7 @@ libgnutlsxx_la_CPPFLAGS = -I$(top_srcdir)/includes -I$(top_builddir)/includes -I
AM_CXXFLAGS = \
-I$(srcdir)/includes \
- -I$(builddir)/includes
+ -I$(builddir)/includes
lib_LTLIBRARIES += libgnutlsxx.la
diff --git a/lib/algorithms/cert_types.c b/lib/algorithms/cert_types.c
index 6ae4b7e160..9671e508d9 100644
--- a/lib/algorithms/cert_types.c
+++ b/lib/algorithms/cert_types.c
@@ -64,8 +64,7 @@ gnutls_certificate_type_t gnutls_certificate_type_get_id(const char *name)
if (c_strcasecmp(name, "X.509") == 0
|| c_strcasecmp(name, "X509") == 0)
return GNUTLS_CRT_X509;
- if (c_strcasecmp(name, "RAWPK") == 0
- || c_strcasecmp(name, "RAWPUBKEY") == 0)
+ if (c_strcasecmp(name, "RAWPK") == 0)
return GNUTLS_CRT_RAWPK;
return ret;
@@ -73,6 +72,7 @@ gnutls_certificate_type_t gnutls_certificate_type_get_id(const char *name)
static const gnutls_certificate_type_t supported_certificate_types[] = {
GNUTLS_CRT_X509,
+ GNUTLS_CRT_RAWPK,
0
};
diff --git a/lib/auth/cert.c b/lib/auth/cert.c
index 574514649c..b6bd3bf91e 100644
--- a/lib/auth/cert.c
+++ b/lib/auth/cert.c
@@ -60,7 +60,7 @@ selected_certs_set(gnutls_session_t session,
typedef enum CertificateSigType { RSA_SIGN = 1, DSA_SIGN = 2, ECDSA_SIGN = 64
} CertificateSigType;
-/* Moves data from a internal certificate struct (gnutls_pcert_st) to
+/* Moves data from an internal certificate struct (gnutls_pcert_st) to
* another internal certificate struct (cert_auth_info_t), and deinitializes
* the former.
*/
@@ -188,9 +188,14 @@ find_x509_client_cert(gnutls_session_t session,
* then send that one.
*/
if (cred->ncerts == 1 &&
- (data_size == 0 || (session->internals.flags & GNUTLS_FORCE_CLIENT_CERT))) {
+ (data_size == 0
+ || (session->internals.flags & GNUTLS_FORCE_CLIENT_CERT))) {
+ if (cred->certs[0].cert_list[0].type == GNUTLS_CRT_X509) {
+ /* This check is necessary to prevent sending other certificate
+ * credentials that are set (e.g. raw public-key). */
*indx = 0;
return 0;
+ }
}
do {
@@ -250,6 +255,47 @@ find_x509_client_cert(gnutls_session_t session,
}
+
+/* Locates the first raw public-key.
+ * Currently it only makes sense to associate one raw pubkey per session.
+ * Associating more raw pubkeys with a session has no use because we
+ * don't know how to select the correct one.
+ */
+static int
+find_rawpk_client_cert(gnutls_session_t session,
+ const gnutls_certificate_credentials_t cred,
+ const gnutls_pk_algorithm_t* pk_algos,
+ int pk_algos_length, int* indx)
+{
+ unsigned i;
+ gnutls_pk_algorithm_t pk;
+
+ *indx = -1;
+
+ for (i = 0; i < cred->ncerts; i++) {
+ /* We know that our list length will be 1, therefore we can
+ * ignore the rest.
+ */
+ if (cred->certs[i].cert_list_length == 1) {
+ pk = gnutls_pubkey_get_pk_algorithm(cred->certs[i].
+ cert_list[0].pubkey, NULL);
+
+ /* Check whether the public-key algorithm of our credential is in
+ * the list with supported public-key algorithms and whether the
+ * cert type matches. */
+ if ((check_pk_algo_in_list(pk_algos, pk_algos_length, pk) == 0)
+ && (cred->certs[i].cert_list[0].type == GNUTLS_CRT_RAWPK)) {
+ // We found a compatible credential
+ *indx = i;
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
/* Returns the number of issuers in the server's
* certificate request packet.
*/
@@ -308,7 +354,7 @@ get_issuers(gnutls_session_t session,
int i;
unsigned size;
- if (gnutls_certificate_type_get2(session, GNUTLS_CTYPE_CLIENT) != GNUTLS_CRT_X509)
+ if (get_certificate_type(session, GNUTLS_CTYPE_CLIENT) != GNUTLS_CRT_X509)
return 0;
/* put the requested DNs to req_dn, only in case
@@ -363,19 +409,10 @@ call_get_cert_callback(gnutls_session_t session,
return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
}
- /* Correctly set the certificate type depending on whether we
- * have explicitly negotiated certificate types (RFC7250).
- */
- if (_gnutls_has_negotiate_ctypes(session)) {
- if (IS_SERVER(session)) {
- type = gnutls_certificate_type_get2(session, GNUTLS_CTYPE_SERVER);
- } else { // Client mode
- type = gnutls_certificate_type_get2(session, GNUTLS_CTYPE_CLIENT);
- }
- } else {
- type = DEFAULT_CERT_TYPE;
- }
+ /* Correctly set the certificate type for ourselves */
+ type = get_certificate_type(session, GNUTLS_CTYPE_OURS);
+ /* Check whether a callback is set and call it */
if (cred->get_cert_callback3) {
struct gnutls_cert_retr_st info;
unsigned int flags = 0;
@@ -411,8 +448,7 @@ call_get_cert_callback(gnutls_session_t session,
return 0;
} else {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
}
}
@@ -435,6 +471,7 @@ _gnutls_select_client_cert(gnutls_session_t session,
ssize_t data_size = _data_size;
int issuers_dn_length;
gnutls_datum_t *issuers_dn = NULL;
+ gnutls_certificate_type_t cert_type;
cred = (gnutls_certificate_credentials_t)
_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE);
@@ -443,11 +480,13 @@ _gnutls_select_client_cert(gnutls_session_t session,
return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
}
+ cert_type = get_certificate_type(session, GNUTLS_CTYPE_CLIENT);
+
if (cred->get_cert_callback3 != NULL) {
/* use a callback to get certificate
*/
- if (session->security_parameters.client_ctype == GNUTLS_CRT_X509) {
+ if (cert_type == GNUTLS_CRT_X509) {
issuers_dn_length =
get_issuers_num(session, data, data_size);
if (issuers_dn_length < 0) {
@@ -486,16 +525,23 @@ _gnutls_select_client_cert(gnutls_session_t session,
} else {
/* If we have no callbacks, try to guess.
*/
- if (session->security_parameters.client_ctype == GNUTLS_CRT_X509) {
- result =
- find_x509_client_cert(session, cred, _data, _data_size,
- pk_algos, pk_algos_length, &indx);
- } else {
- result = GNUTLS_E_UNIMPLEMENTED_FEATURE;
+ switch (cert_type) {
+ case GNUTLS_CRT_X509:
+ result = find_x509_client_cert(session, cred, _data,
+ _data_size, pk_algos,
+ pk_algos_length, &indx);
+ break;
+ case GNUTLS_CRT_RAWPK:
+ result = find_rawpk_client_cert(session, cred,
+ pk_algos, pk_algos_length, &indx);
+ break;
+ default:
+ result = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
+ break;
}
+
if (result < 0) {
- gnutls_assert();
- return result;
+ return gnutls_assert_val(result);
}
if (indx >= 0) {
@@ -575,27 +621,83 @@ static int gen_x509_crt(gnutls_session_t session, gnutls_buffer_st * data)
return data->length - init_pos;
}
+
+/* Generates a Raw Public Key certificate message that holds only the
+ * SubjectPublicKeyInfo part of a regular certificate message.
+ *
+ * Returns the number of bytes sent or a negative error code.
+ */
+int
+_gnutls_gen_rawpk_crt(gnutls_session_t session, gnutls_buffer_st* data)
+{
+ int ret;
+ gnutls_pcert_st *apr_cert_list;
+ gnutls_privkey_t apr_pkey;
+ int apr_cert_list_length;
+
+ if((ret = _gnutls_get_selected_cert(session, &apr_cert_list,
+ &apr_cert_list_length, &apr_pkey)) < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ /* Since we are transmitting a raw public key with no additional
+ * certificate credentials attached to it, it doesn't make sense to
+ * have more than one certificate set (i.e. to have a certificate chain).
+ * This is enforced by the API so having a value other than 1 should
+ * be an impossible situation.
+ */
+ assert(apr_cert_list_length == 1);
+
+ /* Write our certificate containing only the SubjectPublicKeyInfo to
+ * the output buffer. We always have exactly one certificate that
+ * contains our raw public key. Our message looks like:
+ * <length++certificate> where
+ * length = 3 bytes and
+ * certificate = length bytes.
+ */
+ ret = _gnutls_buffer_append_data_prefix(data, 24,
+ apr_cert_list[0].cert.data,
+ apr_cert_list[0].cert.size);
+
+ if (ret < 0) return gnutls_assert_val(ret);
+
+ return data->length;
+}
+
+
int
_gnutls_gen_cert_client_crt(gnutls_session_t session, gnutls_buffer_st * data)
{
- switch (session->security_parameters.client_ctype) {
- case GNUTLS_CRT_X509:
- return gen_x509_crt(session, data);
- default:
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
+ gnutls_certificate_type_t cert_type;
+
+ // Retrieve the (negotiated) certificate type for the client
+ cert_type = get_certificate_type(session, GNUTLS_CTYPE_CLIENT);
+
+ switch (cert_type) {
+ case GNUTLS_CRT_X509:
+ return gen_x509_crt(session, data);
+ case GNUTLS_CRT_RAWPK:
+ return _gnutls_gen_rawpk_crt(session, data);
+ default:
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
}
}
int
_gnutls_gen_cert_server_crt(gnutls_session_t session, gnutls_buffer_st * data)
{
- switch (session->security_parameters.server_ctype) {
- case GNUTLS_CRT_X509:
- return gen_x509_crt(session, data);
- default:
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
+ gnutls_certificate_type_t cert_type;
+
+ // Retrieve the (negotiated) certificate type for the server
+ cert_type = get_certificate_type(session, GNUTLS_CTYPE_SERVER);
+
+ switch (cert_type) {
+ case GNUTLS_CRT_X509:
+ return gen_x509_crt(session, data);
+ case GNUTLS_CRT_RAWPK:
+ return _gnutls_gen_rawpk_crt(session, data);
+ default:
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
}
}
@@ -765,6 +867,99 @@ _gnutls_proc_x509_crt(gnutls_session_t session,
}
+
+int _gnutls_proc_rawpk_crt(gnutls_session_t session,
+ uint8_t * data, size_t data_size)
+{
+ int cert_size, ret;
+ cert_auth_info_t info;
+ gnutls_pcert_st* peer_certificate;
+ gnutls_datum_t tmp_cert;
+
+ uint8_t *p = data;
+ ssize_t dsize = data_size;
+
+ /* We assume data != null and data_size > 0 because
+ * the caller checks this for us. */
+
+ /* Read the length of our certificate. We always have exactly
+ * one certificate that contains our raw public key. Our message
+ * looks like:
+ * <length++certificate> where
+ * length = 3 bytes and
+ * certificate = length bytes.
+ */
+ DECR_LEN(dsize, 3);
+ cert_size = _gnutls_read_uint24(p);
+ p += 3;
+
+ /* Ensure no discrepancy in data */
+ if (cert_size != dsize)
+ return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
+
+
+ if (cert_size == 0) {
+ // No certificate was sent. This is not OK.
+ return gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
+ }
+
+ DECR_LEN_FINAL(dsize, cert_size);
+
+ /* We are now going to read our certificate and store it into
+ * the authentication info structure.
+ */
+ tmp_cert.size = cert_size;
+ tmp_cert.data = p;
+
+ peer_certificate = gnutls_calloc(1, sizeof(*peer_certificate));
+ if (peer_certificate == NULL) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
+ // Import our raw certificate holding only a raw public key into this pcert
+ ret = gnutls_pcert_import_rawpk_raw(peer_certificate, &tmp_cert, GNUTLS_X509_FMT_DER, 0, 0);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ // Check whether the PK algo is compatible with the negotiated KX
+ ret = check_pk_compat(session, peer_certificate->pubkey);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ ret = _gnutls_auth_info_init(session, GNUTLS_CRD_CERTIFICATE,
+ sizeof(cert_auth_info_st), 1);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ info = _gnutls_get_auth_info(session, GNUTLS_CRD_CERTIFICATE);
+
+ /* Copy our imported certificate into the auth info structure
+ * and free our temporary cert storage peer_certificate.
+ */
+ ret = _gnutls_pcert_to_auth_info(info, peer_certificate, 1);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ return GNUTLS_E_SUCCESS;
+
+cleanup:
+ if (peer_certificate != NULL) {
+ gnutls_pcert_deinit(peer_certificate);
+ gnutls_free(peer_certificate);
+ }
+
+ return ret;
+}
+
+
int _gnutls_proc_crt(gnutls_session_t session, uint8_t * data, size_t data_size)
{
int ret;
@@ -779,22 +974,17 @@ int _gnutls_proc_crt(gnutls_session_t session, uint8_t * data, size_t data_size)
return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
}
- /* Determine what certificate type we need to process */
- if (IS_SERVER(session)) {
- // We are the server therefore we process the client certificate
- cert_type = gnutls_certificate_type_get2(session, GNUTLS_CTYPE_CLIENT);
- } else {
- // We are the client therefore we process the server certificate
- cert_type = gnutls_certificate_type_get2(session, GNUTLS_CTYPE_SERVER);
- }
+ /* Determine what certificate type we need to process.
+ * We need to process the certificate of the peer. */
+ cert_type = get_certificate_type(session, GNUTLS_CTYPE_PEERS);
switch (cert_type) {
case GNUTLS_CRT_X509:
- ret = _gnutls_proc_x509_crt(session, data, data_size);
- break;
+ return _gnutls_proc_x509_crt(session, data, data_size);
+ case GNUTLS_CRT_RAWPK:
+ return _gnutls_proc_rawpk_crt(session, data, data_size);
default:
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
}
return ret;
@@ -1148,8 +1338,7 @@ _gnutls_get_selected_cert(gnutls_session_t session,
return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
}
- } else { /* CLIENT SIDE
- */
+ } else { /* CLIENT SIDE */
/* _gnutls_select_client_cert() must have been called before.
*/
*apr_cert_list = session->internals.selected_cert_list;
@@ -1267,7 +1456,7 @@ int cert_select_sign_algorithm(gnutls_session_t session,
assert(IS_SERVER(session));
/* Retrieve the server certificate type */
- ctype = gnutls_certificate_type_get2(session, GNUTLS_CTYPE_SERVER);
+ ctype = get_certificate_type(session, GNUTLS_CTYPE_SERVER);
if (ctype != cert_type) {
return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
@@ -1333,10 +1522,6 @@ _gnutls_select_server_cert(gnutls_session_t session, const gnutls_cipher_suite_e
* certificate and then check its compatibility with
* the ciphersuites.
*/
-
- /* If the callback which retrieves the certificate has been set,
- * use it and leave. We make sure that this is called once.
- */
if (cred->get_cert_callback3) {
if (session->internals.selected_cert_list_length == 0) {
ret = call_get_cert_callback(session, NULL, 0, NULL, 0);
@@ -1407,10 +1592,10 @@ _gnutls_select_server_cert(gnutls_session_t session, const gnutls_cipher_suite_e
_gnutls_handshake_log
("HSK[%p]: checking compat of %s with certificate[%d] (%s/%s)\n",
session, cs->name, i,
- gnutls_pk_get_name(cred->certs[i].cert_list[0].pubkey->params.algo),
- gnutls_certificate_type_get_name(cred->certs
- [i].cert_list
- [0].type));
+ gnutls_pk_get_name(cred->certs[i].cert_list[0].pubkey->
+ params.algo),
+ gnutls_certificate_type_get_name(cred->certs[i].
+ cert_list[0].type));
ret = cert_select_sign_algorithm(session,
&cred->certs[i].cert_list[0],
@@ -1457,9 +1642,8 @@ _gnutls_select_server_cert(gnutls_session_t session, const gnutls_cipher_suite_e
ocsp_func,
ocsp_ptr);
} else {
- gnutls_assert();
/* Certificate does not support REQUESTED_ALGO. */
- return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
+ return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
}
return 0;
@@ -1603,7 +1787,7 @@ _gnutls_proc_dhe_signature(gnutls_session_t session, uint8_t * data,
signature.size = sigsize;
// Retrieve the negotiated certificate type
- cert_type = gnutls_certificate_type_get2(session, GNUTLS_CTYPE_SERVER);
+ cert_type = get_certificate_type(session, GNUTLS_CTYPE_SERVER);
if ((ret =
_gnutls_get_auth_info_pcert(&peer_cert, cert_type, info)) < 0) {
diff --git a/lib/auth/cert.h b/lib/auth/cert.h
index fe3210f922..3f57ec1c74 100644
--- a/lib/auth/cert.h
+++ b/lib/auth/cert.h
@@ -32,6 +32,12 @@
#define MAX_OCSP_RESPONSES 8
+/* We use the structure below to hold a certificate chain
+ * with corresponding public/private key pair. This structure will
+ * also be used when raw public keys are used. The cert_list will
+ * then not hold the cert chain but only a raw public-key. In that case
+ * the list length is always 1.
+ */
typedef struct {
gnutls_pcert_st *cert_list; /* a certificate chain */
unsigned int cert_list_length; /* its length */
@@ -73,7 +79,7 @@ typedef struct gnutls_certificate_credentials_st {
/* X509 specific stuff */
gnutls_x509_trust_list_t tlist;
unsigned flags; /* gnutls_certificate_flags */
- unsigned int verify_flags; /* flags to be used at
+ unsigned int verify_flags; /* flags to be used at
* certificate verification.
*/
unsigned int verify_depth;
@@ -161,4 +167,9 @@ int _gnutls_proc_dhe_signature(gnutls_session_t session, uint8_t * data,
size_t _data_size,
gnutls_datum_t * vparams);
+int _gnutls_gen_rawpk_crt(gnutls_session_t session, gnutls_buffer_st* data);
+int _gnutls_proc_rawpk_crt(gnutls_session_t session,
+ uint8_t * data, size_t data_size);
+
+
#endif
diff --git a/lib/auth/rsa.c b/lib/auth/rsa.c
index 488569d3b7..c2203c7ed3 100644
--- a/lib/auth/rsa.c
+++ b/lib/auth/rsa.c
@@ -117,7 +117,7 @@ _gnutls_get_public_rsa_params(gnutls_session_t session,
}
// Get the negotiated server certificate type
- cert_type = gnutls_certificate_type_get2(session, GNUTLS_CTYPE_SERVER);
+ cert_type = get_certificate_type(session, GNUTLS_CTYPE_SERVER);
ret = _gnutls_get_auth_info_pcert(&peer_cert, cert_type, info);
diff --git a/lib/cert-cred-rawpk.c b/lib/cert-cred-rawpk.c
new file mode 100644
index 0000000000..76cd653204
--- /dev/null
+++ b/lib/cert-cred-rawpk.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2017 - 2018 ARPA2 project
+ *
+ * Author: Tom Vrancken (dev@tomvrancken.nl)
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "gnutls_int.h"
+#include <gnutls/gnutls.h>
+#include "datum.h"
+#include "auth/cert.h"
+#include "x509.h"
+#include "cert-cred.h"
+#include "read-file.h"
+#include <stdint.h>
+
+
+/**
+ * gnutls_certificate_set_rawpk_key_mem:
+ * @cred: is a #gnutls_certificate_credentials_t type.
+ * @spki: contains a raw public key in
+ * PKIX.SubjectPublicKeyInfo format.
+ * @pkey: contains a raw private key.
+ * @format: encoding of the keys. DER or PEM.
+ * @pass: an optional password to unlock the private key pkey.
+ * @key_usage: An ORed sequence of %GNUTLS_KEY_* flags.
+ * @names: is an array of DNS names belonging to the public-key (NULL if none).
+ * @names_length: holds the length of the names list.
+ * @flags: an ORed sequence of #gnutls_pkcs_encrypt_flags_t.
+ * These apply to the private key pkey.
+ *
+ * This function sets a public/private keypair in the
+ * #gnutls_certificate_credentials_t type to be used for authentication
+ * and/or encryption. @spki and @privkey should match otherwise set
+ * signatures cannot be validated. In case of no match this function
+ * returns %GNUTLS_E_CERTIFICATE_KEY_MISMATCH. This function should
+ * be called once for the client because there is currently no mechanism
+ * to determine which raw public-key to select for the peer when there
+ * are multiple present. Multiple raw public keys for the server can be
+ * distinghuished by setting the @names.
+ *
+ * Note here that @spki is a raw public-key as defined
+ * in RFC7250. It means that there is no surrounding certificate that
+ * holds the public key and that there is therefore no direct mechanism
+ * to prove the authenticity of this key. The keypair can be used during
+ * a TLS handshake but its authenticity should be established via a
+ * different mechanism (e.g. TOFU or known fingerprint).
+ *
+ * The supported formats are basic unencrypted key, PKCS8, PKCS12,
+ * and the openssl format and will be autodetected.
+ *
+ * If the raw public-key and the private key are given in PEM encoding
+ * then the strings that hold their values must be null terminated.
+ *
+ * Key usage (as defined by X.509 extension (2.5.29.15)) can be explicitly
+ * set because there is no certificate structure around the key to define
+ * this value. See for more info gnutls_x509_crt_get_key_usage().
+ *
+ * Note that, this function by default returns zero on success and a
+ * negative value on error. Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2
+ * is set using gnutls_certificate_set_flags() it returns an index
+ * (greater or equal to zero). That index can be used in other functions
+ * to refer to the added key-pair.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, in case the
+ * key pair does not match %GNUTLS_E_CERTIFICATE_KEY_MISMATCH is returned,
+ * in other erroneous cases a different negative error code is returned.
+ *
+ * Since: 3.6.6
+ **/
+int gnutls_certificate_set_rawpk_key_mem(gnutls_certificate_credentials_t cred,
+ const gnutls_datum_t* spki,
+ const gnutls_datum_t* pkey,
+ gnutls_x509_crt_fmt_t format,
+ const char* pass,
+ unsigned int key_usage,
+ const char **names,
+ unsigned int names_length,
+ unsigned int flags)
+{
+ int ret;
+ gnutls_privkey_t privkey;
+ gnutls_pcert_st* pcert;
+ gnutls_str_array_t str_names;
+ unsigned int i;
+
+ if (pkey == NULL || spki == NULL) {
+ return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+
+ /* Import our private key. This function does all the necessary
+ * inits, checks and imports. */
+ ret = _gnutls_read_key_mem(cred, pkey->data, pkey->size,
+ format, pass, flags, &privkey);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ /* We now convert our raw public key to a parsed certificate (pcert) structure */
+ pcert = gnutls_calloc(1, sizeof(*pcert));
+ if (pcert == NULL) {
+ gnutls_privkey_deinit(privkey);
+
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+ // Import our raw public key to the pcert structure
+ ret = gnutls_pcert_import_rawpk_raw(pcert, spki,
+ format, key_usage, 0);
+ if (ret < 0) {
+ gnutls_privkey_deinit(privkey);
+
+ return gnutls_assert_val(ret);
+ }
+
+ /* Process the names, if any */
+ _gnutls_str_array_init(&str_names);
+
+ if (names != NULL && names_length > 0) {
+ for (i = 0; i < names_length; i++) {
+ ret =
+ _gnutls_str_array_append_idna(&str_names, names[i],
+ strlen(names[i]));
+ if (ret < 0) {
+ gnutls_privkey_deinit(privkey);
+ _gnutls_str_array_clear(&str_names);
+
+ return gnutls_assert_val(ret);
+ }
+ }
+ }
+
+ /* Now that we have converted the key material to our internal structures
+ * we can now add them to the credentials structure */
+ ret = _gnutls_certificate_credential_append_keypair(cred, privkey, str_names, pcert, 1);
+ // Check for errors
+ if (ret < 0) {
+ gnutls_privkey_deinit(privkey);
+ gnutls_pcert_deinit(pcert);
+ gnutls_free(pcert);
+
+ return gnutls_assert_val(ret);
+ }
+ // Successfully added a certificate
+ cred->ncerts++;
+
+ /* Check whether the key pair matches.
+ * After this point we do not deinitialize anything on failure to avoid
+ * double freeing. We intentionally keep everything as the credentials state
+ * is documented to be in undefined state. */
+ if ((ret = _gnutls_check_key_cert_match(cred)) < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ CRED_RET_SUCCESS(cred);
+}
+
+
+/**
+ * gnutls_certificate_set_rawpk_key_file:
+ * @cred: is a #gnutls_certificate_credentials_t type.
+ * @rawpkfile: contains a raw public key in
+ * PKIX.SubjectPublicKeyInfo format.
+ * @privkeyfile: contains a file path to a private key.
+ * @format: encoding of the keys. DER or PEM.
+ * @pass: an optional password to unlock the private key privkeyfile.
+ * @key_usage: an ORed sequence of %GNUTLS_KEY_* flags.
+ * @names: is an array of DNS names belonging to the public-key (NULL if none).
+ * @names_length: holds the length of the names list.
+ * @privkey_flags: an ORed sequence of #gnutls_pkcs_encrypt_flags_t.
+ * These apply to the private key pkey.
+ * @pkcs11_flags: one of gnutls_pkcs11_obj_flags. These apply to URLs.
+ *
+ * This function sets a public/private keypair read from file in the
+ * #gnutls_certificate_credentials_t type to be used for authentication
+ * and/or encryption. @spki and @privkey should match otherwise set
+ * signatures cannot be validated. In case of no match this function
+ * returns %GNUTLS_E_CERTIFICATE_KEY_MISMATCH. This function should
+ * be called once for the client because there is currently no mechanism
+ * to determine which raw public-key to select for the peer when there
+ * are multiple present. Multiple raw public keys for the server can be
+ * distinghuished by setting the @names.
+ *
+ * Note here that @spki is a raw public-key as defined
+ * in RFC7250. It means that there is no surrounding certificate that
+ * holds the public key and that there is therefore no direct mechanism
+ * to prove the authenticity of this key. The keypair can be used during
+ * a TLS handshake but its authenticity should be established via a
+ * different mechanism (e.g. TOFU or known fingerprint).
+ *
+ * The supported formats are basic unencrypted key, PKCS8, PKCS12,
+ * and the openssl format and will be autodetected.
+ *
+ * If the raw public-key and the private key are given in PEM encoding
+ * then the strings that hold their values must be null terminated.
+ *
+ * Key usage (as defined by X.509 extension (2.5.29.15)) can be explicitly
+ * set because there is no certificate structure around the key to define
+ * this value. See for more info gnutls_x509_crt_get_key_usage().
+ *
+ * Note that, this function by default returns zero on success and a
+ * negative value on error. Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2
+ * is set using gnutls_certificate_set_flags() it returns an index
+ * (greater or equal to zero). That index can be used in other functions
+ * to refer to the added key-pair.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, in case the
+ * key pair does not match %GNUTLS_E_CERTIFICATE_KEY_MISMATCH is returned,
+ * in other erroneous cases a different negative error code is returned.
+ *
+ * Since: 3.6.6
+ */
+int gnutls_certificate_set_rawpk_key_file(gnutls_certificate_credentials_t cred,
+ const char* rawpkfile,
+ const char* privkeyfile,
+ gnutls_x509_crt_fmt_t format,
+ const char *pass,
+ unsigned int key_usage,
+ const char **names,
+ unsigned int names_length,
+ unsigned int privkey_flags,
+ unsigned int pkcs11_flags)
+{
+ int ret;
+ gnutls_privkey_t privkey;
+ gnutls_pubkey_t pubkey;
+ gnutls_pcert_st* pcert;
+ gnutls_datum_t rawpubkey = { NULL, 0 }; // to hold rawpk data from file
+ size_t key_size;
+ gnutls_str_array_t str_names;
+ unsigned int i;
+
+ if (rawpkfile == NULL || privkeyfile == NULL) {
+ return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+
+ /* Import our private key. This function does all the necessary
+ * inits, checks and imports. */
+ ret = _gnutls_read_key_file(cred, privkeyfile, format, pass, privkey_flags, &privkey);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ pcert = gnutls_calloc(1, sizeof(*pcert));
+ if (pcert == NULL) {
+ gnutls_privkey_deinit(privkey);
+
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
+ /* Check whether we are importing our raw public-key from a URL
+ * or from a regular file.
+ */
+ if (gnutls_url_is_supported(rawpkfile)) {
+
+ ret = gnutls_pubkey_init(&pubkey);
+ if (ret < 0) {
+ gnutls_privkey_deinit(privkey);
+
+ return gnutls_assert_val(ret);
+ }
+
+ ret = gnutls_pubkey_import_url(pubkey, rawpkfile, pkcs11_flags);
+ if (ret < 0) {
+ gnutls_privkey_deinit(privkey);
+ gnutls_pubkey_deinit(pubkey);
+
+ return gnutls_assert_val(ret);
+ }
+
+ ret = gnutls_pcert_import_rawpk(pcert, pubkey, 0);
+ if (ret < 0) {
+ gnutls_privkey_deinit(privkey);
+ gnutls_pubkey_deinit(pubkey);
+
+ return gnutls_assert_val(ret);
+ }
+
+ } else {
+ /* Read our raw public-key into memory from file */
+ rawpubkey.data = (void*) read_binary_file(rawpkfile, &key_size);
+ if (rawpubkey.data == NULL) {
+ gnutls_privkey_deinit(privkey);
+
+ return gnutls_assert_val(GNUTLS_E_FILE_ERROR);
+ }
+ rawpubkey.size = key_size; // Implicit type casting
+
+ /* We now convert our raw public key that we've loaded into memory to
+ * a parsed certificate (pcert) structure. Note that rawpubkey will
+ * be copied into pcert. Therefore we can directly cleanup rawpubkey.
+ */
+ ret = gnutls_pcert_import_rawpk_raw(pcert, &rawpubkey,
+ format, key_usage, 0);
+
+ _gnutls_free_datum(&rawpubkey);
+
+ if (ret < 0) {
+ gnutls_privkey_deinit(privkey);
+
+ return gnutls_assert_val(ret);
+ }
+
+ }
+
+ /* Process the names, if any */
+ _gnutls_str_array_init(&str_names);
+
+ if (names != NULL && names_length > 0) {
+ for (i = 0; i < names_length; i++) {
+ ret =
+ _gnutls_str_array_append_idna(&str_names, names[i],
+ strlen(names[i]));
+ if (ret < 0) {
+ gnutls_privkey_deinit(privkey);
+ _gnutls_str_array_clear(&str_names);
+
+ return gnutls_assert_val(ret);
+ }
+ }
+ }
+
+ /* Now that we have converted the key material to our internal structures
+ * we can now add them to the credentials structure */
+ ret = _gnutls_certificate_credential_append_keypair(cred, privkey, str_names, pcert, 1);
+ if (ret < 0) {
+ gnutls_privkey_deinit(privkey);
+ gnutls_pcert_deinit(pcert);
+ gnutls_free(pcert);
+
+ return gnutls_assert_val(ret);
+ }
+ // Successfully added a certificate
+ cred->ncerts++;
+
+ /* Check whether the key pair matches.
+ * After this point we do not deinitialize anything on failure to avoid
+ * double freeing. We intentionally keep everything as the credentials state
+ * is documented to be in undefined state. */
+ if ((ret = _gnutls_check_key_cert_match(cred)) < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ CRED_RET_SUCCESS(cred);
+}
+
diff --git a/lib/cert-cred-x509.c b/lib/cert-cred-x509.c
index 42a6bd5ba8..257f1b989a 100644
--- a/lib/cert-cred-x509.c
+++ b/lib/cert-cred-x509.c
@@ -46,6 +46,7 @@
#include "read-file.h"
#include "system-keys.h"
#include "urls.h"
+#include "cert-cred.h"
#ifdef _WIN32
#include <wincrypt.h>
#endif
@@ -55,42 +56,10 @@
* related objects in a certificate credentials structure.
*/
-static int
-certificate_credential_append_keypair(gnutls_certificate_credentials_t res,
- gnutls_privkey_t key,
- gnutls_str_array_t names,
- gnutls_pcert_st * crt, int nr);
-
-#define CRED_RET_SUCCESS(cred) \
- if (cred->flags & GNUTLS_CERTIFICATE_API_V2) { \
- return cred->ncerts-1; \
- } else { \
- return 0; \
- }
-
-
-static int str_array_append_idna(gnutls_str_array_t * head, const char *name, size_t size)
-{
- int ret;
- gnutls_datum_t ahost;
-
- /* convert the provided hostname to ACE-Labels domain. */
- ret = gnutls_idna_map(name, size, &ahost, 0);
- if (ret < 0) {
- _gnutls_debug_log("unable to convert hostname %s to IDNA format\n", name);
- /* insert the raw name */
- return _gnutls_str_array_append(head, name, size);
- }
-
- ret = _gnutls_str_array_append(head, (char*)ahost.data, ahost.size);
- gnutls_free(ahost.data);
-
- return ret;
-}
/* Returns the name of the certificate of a null name
*/
-static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t * names)
+int _gnutls_get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t * names)
{
size_t max_size;
int i, ret = 0, ret2;
@@ -107,7 +76,7 @@ static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t * names)
have_dns_name = 1;
ret2 =
- str_array_append_idna(names, name,
+ _gnutls_str_array_append_idna(names, name,
max_size);
if (ret2 < 0) {
_gnutls_str_array_clear(names);
@@ -122,7 +91,7 @@ static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t * names)
gnutls_x509_crt_get_dn_by_oid(crt, OID_X520_COMMON_NAME, 0, 0,
name, &max_size);
if (ret >= 0) {
- ret = str_array_append_idna(names, name, max_size);
+ ret = _gnutls_str_array_append_idna(names, name, max_size);
if (ret < 0) {
_gnutls_str_array_clear(names);
return gnutls_assert_val(ret);
@@ -171,7 +140,7 @@ parse_der_cert_mem(gnutls_certificate_credentials_t res,
goto cleanup;
}
- ret = get_x509_name(crt, &names);
+ ret = _gnutls_get_x509_name(crt, &names);
if (ret < 0) {
gnutls_assert();
gnutls_x509_crt_deinit(crt);
@@ -186,7 +155,7 @@ parse_der_cert_mem(gnutls_certificate_credentials_t res,
goto cleanup;
}
- ret = certificate_credential_append_keypair(res, key, names, ccert, 1);
+ ret = _gnutls_certificate_credential_append_keypair(res, key, names, ccert, 1);
if (ret < 0) {
gnutls_assert();
goto cleanup;
@@ -279,7 +248,7 @@ parse_pem_cert_mem(gnutls_certificate_credentials_t res,
while (ptr != NULL && count < DEFAULT_MAX_VERIFY_DEPTH);
ret =
- get_x509_name(unsorted[0], &names);
+ _gnutls_get_x509_name(unsorted[0], &names);
if (ret < 0) {
gnutls_assert();
goto cleanup;
@@ -302,8 +271,7 @@ parse_pem_cert_mem(gnutls_certificate_credentials_t res,
}
ret =
- certificate_credential_append_keypair(res, key, names, pcerts,
- ncerts);
+ _gnutls_certificate_credential_append_keypair(res, key, names, pcerts, ncerts);
if (ret < 0) {
gnutls_assert();
goto cleanup;
@@ -370,8 +338,8 @@ static int tmp_pin_cb(void *userdata, int attempt, const char *token_url,
*
* It returns the private key read in @rkey.
*/
-static int
-read_key_mem(gnutls_certificate_credentials_t res,
+int
+_gnutls_read_key_mem(gnutls_certificate_credentials_t res,
const void *key, int key_size, gnutls_x509_crt_fmt_t type,
const char *pass, unsigned int flags,
gnutls_privkey_t *rkey)
@@ -501,7 +469,7 @@ read_cert_url(gnutls_certificate_credentials_t res, gnutls_privkey_t key, const
goto cleanup;
}
- ret = get_x509_name(crt, &names);
+ ret = _gnutls_get_x509_name(crt, &names);
if (ret < 0) {
gnutls_assert();
goto cleanup;
@@ -543,7 +511,7 @@ read_cert_url(gnutls_certificate_credentials_t res, gnutls_privkey_t key, const
t.data = NULL;
}
- ret = certificate_credential_append_keypair(res, key, names, ccert, count);
+ ret = _gnutls_certificate_credential_append_keypair(res, key, names, ccert, count);
if (ret < 0) {
gnutls_assert();
goto cleanup;
@@ -596,8 +564,8 @@ read_cert_file(gnutls_certificate_credentials_t res,
/* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
* stores it).
*/
-static int
-read_key_file(gnutls_certificate_credentials_t res,
+int
+_gnutls_read_key_file(gnutls_certificate_credentials_t res,
const char *keyfile, gnutls_x509_crt_fmt_t type,
const char *pass, unsigned int flags,
gnutls_privkey_t *rkey)
@@ -629,7 +597,7 @@ read_key_file(gnutls_certificate_credentials_t res,
return GNUTLS_E_FILE_ERROR;
}
- ret = read_key_mem(res, data, size, type, pass, flags, rkey);
+ ret = _gnutls_read_key_mem(res, data, size, type, pass, flags, rkey);
free(data);
return ret;
@@ -716,7 +684,7 @@ gnutls_certificate_set_x509_key_mem2(gnutls_certificate_credentials_t res,
/* this should be first
*/
- if ((ret = read_key_mem(res, key ? key->data : NULL,
+ if ((ret = _gnutls_read_key_mem(res, key ? key->data : NULL,
key ? key->size : 0, type, pass,
flags, &rkey)) < 0)
return ret;
@@ -736,57 +704,6 @@ gnutls_certificate_set_x509_key_mem2(gnutls_certificate_credentials_t res,
CRED_RET_SUCCESS(res);
}
-static int
-certificate_credential_append_keypair(gnutls_certificate_credentials_t res,
- gnutls_privkey_t key,
- gnutls_str_array_t names,
- gnutls_pcert_st * crt, int nr)
-{
- res->sorted_cert_idx = gnutls_realloc_fast(res->sorted_cert_idx,
- (1 + res->ncerts) *
- sizeof(unsigned int));
- if (res->sorted_cert_idx == NULL)
- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-
- res->certs = gnutls_realloc_fast(res->certs,
- (1 + res->ncerts) *
- sizeof(certs_st));
- if (res->certs == NULL)
- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-
- memset(&res->certs[res->ncerts], 0, sizeof(res->certs[0]));
-
- res->certs[res->ncerts].cert_list = crt;
- res->certs[res->ncerts].cert_list_length = nr;
- res->certs[res->ncerts].names = names;
- res->certs[res->ncerts].pkey = key;
-
- /* move RSA-PSS certificates before any RSA key.
- * Note that we cannot assume that any previous pointers
- * to sorted list are ok, due to the realloc in res->certs. */
- if (crt->pubkey->params.algo == GNUTLS_PK_RSA_PSS) {
- unsigned i,ridx;
- unsigned tmp;
-
- for (i=0;i<res->ncerts;i++) {
- ridx = res->sorted_cert_idx[i];
-
- if (res->certs[ridx].cert_list->pubkey->params.algo == GNUTLS_PK_RSA) {
- tmp = ridx;
- res->sorted_cert_idx[i] = res->ncerts;
- res->sorted_cert_idx[res->ncerts] = tmp;
- goto finish;
- }
- }
- }
-
- /* otherwise append it normally on the end */
- res->sorted_cert_idx[res->ncerts] = res->ncerts;
-
- finish:
- return 0;
-
-}
/**
* gnutls_certificate_set_x509_key:
@@ -856,7 +773,7 @@ gnutls_certificate_set_x509_key(gnutls_certificate_credentials_t res,
return GNUTLS_E_MEMORY_ERROR;
}
- ret = get_x509_name(cert_list[0], &names);
+ ret = _gnutls_get_x509_name(cert_list[0], &names);
if (ret < 0) {
gnutls_assert();
goto cleanup;
@@ -871,7 +788,7 @@ gnutls_certificate_set_x509_key(gnutls_certificate_credentials_t res,
}
ret =
- certificate_credential_append_keypair(res, pkey, names, pcerts,
+ _gnutls_certificate_credential_append_keypair(res, pkey, names, pcerts,
cert_list_size);
if (ret < 0) {
gnutls_assert();
@@ -1001,126 +918,6 @@ gnutls_certificate_get_x509_crt(gnutls_certificate_credentials_t res,
}
/**
- * gnutls_certificate_set_key:
- * @res: is a #gnutls_certificate_credentials_t type.
- * @names: is an array of DNS name of the certificate (NULL if none)
- * @names_size: holds the size of the names list
- * @pcert_list: contains a certificate list (path) for the specified private key
- * @pcert_list_size: holds the size of the certificate list
- * @key: is a #gnutls_privkey_t key
- *
- * This function sets a certificate/private key pair in the
- * gnutls_certificate_credentials_t type. This function may be
- * called more than once, in case multiple keys/certificates exist for
- * the server. For clients that want to send more than their own end-
- * entity certificate (e.g., also an intermediate CA cert), the full
- * certificate chain must be provided in @pcert_list.
- *
- * Note that the @key and the elements of @pcert_list will become part of the credentials
- * structure and must not be deallocated. They will be automatically deallocated
- * when the @res structure is deinitialized.
- *
- * If that function fails to load the @res structure is at an undefined state, it must
- * not be reused to load other keys or certificates.
- *
- * Note that, this function by default returns zero on success and a negative value on error.
- * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
- * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
- *
- * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
- *
- * Since: 3.0
- **/
-int
-gnutls_certificate_set_key(gnutls_certificate_credentials_t res,
- const char **names,
- int names_size,
- gnutls_pcert_st * pcert_list,
- int pcert_list_size, gnutls_privkey_t key)
-{
- int ret, i;
- gnutls_str_array_t str_names;
- gnutls_pcert_st *new_pcert_list;
-
- _gnutls_str_array_init(&str_names);
-
- if (names != NULL && names_size > 0) {
- for (i = 0; i < names_size; i++) {
- ret =
- str_array_append_idna(&str_names, names[i],
- strlen(names[i]));
- if (ret < 0) {
- ret = gnutls_assert_val(ret);
- goto cleanup;
- }
- }
- } else if (names == NULL && pcert_list[0].type == GNUTLS_CRT_X509) {
- gnutls_x509_crt_t crt;
-
- ret = gnutls_x509_crt_init(&crt);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
-
- ret = gnutls_x509_crt_import(crt, &pcert_list[0].cert, GNUTLS_X509_FMT_DER);
- if (ret < 0) {
- gnutls_assert();
- gnutls_x509_crt_deinit(crt);
- goto cleanup;
- }
-
- ret = get_x509_name(crt, &str_names);
- gnutls_x509_crt_deinit(crt);
-
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
- }
-
- if (res->pin.cb)
- gnutls_privkey_set_pin_function(key, res->pin.cb,
- res->pin.data);
-
- new_pcert_list = gnutls_malloc(sizeof(gnutls_pcert_st) * pcert_list_size);
- if (new_pcert_list == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
- memcpy(new_pcert_list, pcert_list, sizeof(gnutls_pcert_st) * pcert_list_size);
-
- ret =
- certificate_credential_append_keypair(res, key, str_names,
- new_pcert_list,
- pcert_list_size);
- if (ret < 0) {
- gnutls_assert();
- gnutls_free(new_pcert_list);
- goto cleanup;
- }
-
- res->ncerts++;
-
- /* Unlike gnutls_certificate_set_x509_key, we deinitialize everything
- * local after a failure. That is because the caller is responsible for
- * freeing these values after a failure, and if we keep references we
- * lead to double freeing */
- if ((ret = _gnutls_check_key_cert_match(res)) < 0) {
- gnutls_assert();
- gnutls_free(new_pcert_list);
- res->ncerts--;
- goto cleanup;
- }
-
- CRED_RET_SUCCESS(res);
-
- cleanup:
- _gnutls_str_array_clear(&str_names);
- return ret;
-}
-
-/**
* gnutls_certificate_set_trust_list:
* @res: is a #gnutls_certificate_credentials_t type.
* @tlist: is a #gnutls_x509_trust_list_t type
@@ -1265,7 +1062,7 @@ gnutls_certificate_set_x509_key_file2(gnutls_certificate_credentials_t res,
/* this should be first
*/
- if ((ret = read_key_file(res, keyfile, type, pass, flags, &rkey)) < 0)
+ if ((ret = _gnutls_read_key_file(res, keyfile, type, pass, flags, &rkey)) < 0)
return ret;
if ((ret = read_cert_file(res, rkey, certfile, type)) < 0) {
diff --git a/lib/cert-cred.c b/lib/cert-cred.c
index 2d7009b2e5..f04ded4c04 100644
--- a/lib/cert-cred.c
+++ b/lib/cert-cred.c
@@ -40,7 +40,202 @@
#include <str_array.h>
#include <x509/verify-high.h>
#include "x509/x509_int.h"
+#include "x509/common.h"
#include "dh.h"
+#include "cert-cred.h"
+
+
+/*
+ * Adds a public/private key pair to a certificate credential
+ */
+int
+_gnutls_certificate_credential_append_keypair(gnutls_certificate_credentials_t res,
+ gnutls_privkey_t key,
+ gnutls_str_array_t names,
+ gnutls_pcert_st * crt,
+ int nr)
+{
+ res->sorted_cert_idx = gnutls_realloc_fast(res->sorted_cert_idx,
+ (1 + res->ncerts) *
+ sizeof(unsigned int));
+ if (res->sorted_cert_idx == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ res->certs = gnutls_realloc_fast(res->certs,
+ (1 + res->ncerts) *
+ sizeof(certs_st));
+ if (res->certs == NULL)
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+ memset(&res->certs[res->ncerts], 0, sizeof(res->certs[0]));
+
+ res->certs[res->ncerts].cert_list = crt;
+ res->certs[res->ncerts].cert_list_length = nr;
+ res->certs[res->ncerts].names = names;
+ res->certs[res->ncerts].pkey = key;
+
+ /* move RSA-PSS certificates before any RSA key.
+ * Note that we cannot assume that any previous pointers
+ * to sorted list are ok, due to the realloc in res->certs. */
+ if (crt->pubkey->params.algo == GNUTLS_PK_RSA_PSS) {
+ unsigned i,ridx;
+ unsigned tmp;
+
+ for (i=0;i<res->ncerts;i++) {
+ ridx = res->sorted_cert_idx[i];
+
+ if (res->certs[ridx].cert_list->pubkey->params.algo == GNUTLS_PK_RSA) {
+ tmp = ridx;
+ res->sorted_cert_idx[i] = res->ncerts;
+ res->sorted_cert_idx[res->ncerts] = tmp;
+ goto finish;
+ }
+ }
+ }
+
+ /* otherwise append it normally on the end */
+ res->sorted_cert_idx[res->ncerts] = res->ncerts;
+
+ finish:
+ return 0;
+
+}
+
+
+/**
+ * gnutls_certificate_set_key:
+ * @res: is a #gnutls_certificate_credentials_t type.
+ * @names: is an array of DNS names belonging to the public-key (NULL if none)
+ * @names_size: holds the size of the names list
+ * @pcert_list: contains a certificate list (chain) or raw public-key
+ * @pcert_list_size: holds the size of the certificate list
+ * @key: is a #gnutls_privkey_t key corresponding to the first public-key in pcert_list
+ *
+ * This function sets a public/private key pair in the
+ * gnutls_certificate_credentials_t type. The given public key may be encapsulated
+ * in a certificate or can be given as a raw key. This function may be
+ * called more than once, in case multiple key pairs exist for
+ * the server. For clients that want to send more than their own end-
+ * entity certificate (e.g., also an intermediate CA cert), the full
+ * certificate chain must be provided in @pcert_list.
+ *
+ * Note that the @key will become part of the credentials structure and must
+ * not be deallocated. It will be automatically deallocated when the @res structure
+ * is deinitialized.
+ *
+ * If this function fails, the @res structure is at an undefined state and it must
+ * not be reused to load other keys or certificates.
+ *
+ * Note that, this function by default returns zero on success and a negative value on error.
+ * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
+ * it returns an index (greater or equal to zero). That index can be used for other functions to refer to the added key-pair.
+ *
+ * Since GnuTLS 3.6.6 this function also handles raw public keys.
+ *
+ * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
+ *
+ * Since: 3.0
+ **/
+int
+gnutls_certificate_set_key(gnutls_certificate_credentials_t res,
+ const char **names,
+ int names_size,
+ gnutls_pcert_st * pcert_list,
+ int pcert_list_size,
+ gnutls_privkey_t key)
+{
+ int ret, i;
+ gnutls_str_array_t str_names;
+ gnutls_pcert_st *new_pcert_list;
+
+ /* Sanity checks */
+ // Check for a valid credential struct
+ if (res == NULL) {
+ return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
+ }
+
+ // A complete key pair must be given
+ if (pcert_list == NULL || key == NULL) {
+ return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+
+ /* Process the names, if any */
+ _gnutls_str_array_init(&str_names);
+
+ if (names != NULL && names_size > 0) {
+ for (i = 0; i < names_size; i++) {
+ ret =
+ _gnutls_str_array_append_idna(&str_names, names[i],
+ strlen(names[i]));
+ if (ret < 0) {
+ ret = gnutls_assert_val(ret);
+ goto cleanup;
+ }
+ }
+ } else if (names == NULL && pcert_list[0].type == GNUTLS_CRT_X509) {
+ gnutls_x509_crt_t crt;
+
+ ret = gnutls_x509_crt_init(&crt);
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ ret = gnutls_x509_crt_import(crt, &pcert_list[0].cert, GNUTLS_X509_FMT_DER);
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_x509_crt_deinit(crt);
+ goto cleanup;
+ }
+
+ ret = _gnutls_get_x509_name(crt, &str_names);
+ gnutls_x509_crt_deinit(crt);
+
+ if (ret < 0) {
+ gnutls_assert();
+ goto cleanup;
+ }
+ }
+
+ if (res->pin.cb)
+ gnutls_privkey_set_pin_function(key, res->pin.cb,
+ res->pin.data);
+
+ new_pcert_list = gnutls_malloc(sizeof(gnutls_pcert_st) * pcert_list_size);
+ if (new_pcert_list == NULL) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+ memcpy(new_pcert_list, pcert_list, sizeof(gnutls_pcert_st) * pcert_list_size);
+
+ ret =
+ _gnutls_certificate_credential_append_keypair(res, key, str_names,
+ new_pcert_list,
+ pcert_list_size);
+ if (ret < 0) {
+ gnutls_assert();
+ gnutls_free(new_pcert_list);
+ goto cleanup;
+ }
+
+ res->ncerts++;
+
+ /* Unlike gnutls_certificate_set_x509_key, we deinitialize everything
+ * local after a failure. That is because the caller is responsible for
+ * freeing these values after a failure, and if we keep references we
+ * lead to double freeing */
+ if ((ret = _gnutls_check_key_cert_match(res)) < 0) {
+ gnutls_assert();
+ gnutls_free(new_pcert_list);
+ res->ncerts--;
+ goto cleanup;
+ }
+
+ CRED_RET_SUCCESS(res);
+
+ cleanup:
+ _gnutls_str_array_clear(&str_names);
+ return ret;
+}
/**
* gnutls_certificate_free_keys:
@@ -199,7 +394,7 @@ gnutls_certificate_free_credentials(gnutls_certificate_credentials_t sc)
// Check for valid pointer and otherwise do nothing
if (sc == NULL)
return;
-
+
gnutls_x509_trust_list_deinit(sc->tlist, 1);
gnutls_certificate_free_keys(sc);
memset(sc->pin_tmp, 0, sizeof(sc->pin_tmp));
diff --git a/lib/cert-cred.h b/lib/cert-cred.h
new file mode 100644
index 0000000000..06cba4dd58
--- /dev/null
+++ b/lib/cert-cred.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 Free Software Foundation, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include <gnutls/abstract.h>
+#include "str_array.h"
+
+
+int
+_gnutls_certificate_credential_append_keypair(gnutls_certificate_credentials_t res,
+ gnutls_privkey_t key,
+ gnutls_str_array_t names,
+ gnutls_pcert_st * crt, int nr);
+
+int
+_gnutls_read_key_mem(gnutls_certificate_credentials_t res,
+ const void *key, int key_size, gnutls_x509_crt_fmt_t type,
+ const char *pass, unsigned int flags,
+ gnutls_privkey_t *rkey);
+
+int
+_gnutls_read_key_file(gnutls_certificate_credentials_t res,
+ const char *keyfile, gnutls_x509_crt_fmt_t type,
+ const char *pass, unsigned int flags,
+ gnutls_privkey_t *rkey);
+
+int
+_gnutls_get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t * names);
+
+#define CRED_RET_SUCCESS(cred) \
+ if (cred->flags & GNUTLS_CERTIFICATE_API_V2) { \
+ return cred->ncerts-1; \
+ } else { \
+ return 0; \
+ }
diff --git a/lib/cert-session.c b/lib/cert-session.c
index 2726512f5d..9a25eb57a4 100644
--- a/lib/cert-session.c
+++ b/lib/cert-session.c
@@ -599,6 +599,10 @@ _gnutls_x509_cert_verify_peers(gnutls_session_t session,
* default upper limits regarding the certificate key size and chain
* size are set. To override them use gnutls_certificate_set_verify_limits().
*
+ * Note that when using raw public-keys verification will not work because there is
+ * no corresponding certificate body belonging to the raw key that can be verified. In that
+ * case this function will return %GNUTLS_E_INVALID_REQUEST.
+ *
* Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
* A successful error code means that the @status parameter must be checked to obtain the validation status.
**/
@@ -640,6 +644,10 @@ gnutls_certificate_verify_peers2(gnutls_session_t session,
* default upper limits regarding the certificate key size and chain
* size are set. To override them use gnutls_certificate_set_verify_limits().
*
+ * Note that when using raw public-keys verification will not work because there is
+ * no corresponding certificate body belonging to the raw key that can be verified. In that
+ * case this function will return %GNUTLS_E_INVALID_REQUEST.
+ *
* Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
* A successful error code means that the @status parameter must be checked to obtain the validation status.
*
@@ -695,6 +703,10 @@ gnutls_typed_vdata_st data;
* default upper limits regarding the certificate key size and chain
* size are set. To override them use gnutls_certificate_set_verify_limits().
*
+ * Note that when using raw public-keys verification will not work because there is
+ * no corresponding certificate body belonging to the raw key that can be verified. In that
+ * case this function will return %GNUTLS_E_INVALID_REQUEST.
+ *
* Returns: %GNUTLS_E_SUCCESS (0) when the validation is performed, or a negative error code otherwise.
* A successful error code means that the @status parameter must be checked to obtain the validation status.
*
@@ -719,7 +731,7 @@ gnutls_certificate_verify_peers(gnutls_session_t session,
return GNUTLS_E_NO_CERTIFICATE_FOUND;
- switch (gnutls_certificate_type_get2(session, GNUTLS_CTYPE_PEERS)) {
+ switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
case GNUTLS_CRT_X509:
return _gnutls_x509_cert_verify_peers(session, data, elements,
status);
@@ -820,7 +832,7 @@ time_t gnutls_certificate_expiration_time_peers(gnutls_session_t session)
return (time_t) - 1;
}
- switch (gnutls_certificate_type_get2(session, GNUTLS_CTYPE_PEERS)) {
+ switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
case GNUTLS_CRT_X509:
return
_gnutls_x509_get_raw_crt_expiration_time(&info->
@@ -856,7 +868,7 @@ time_t gnutls_certificate_activation_time_peers(gnutls_session_t session)
return (time_t) - 1;
}
- switch (gnutls_certificate_type_get2(session, GNUTLS_CTYPE_PEERS)) {
+ switch (get_certificate_type(session, GNUTLS_CTYPE_PEERS)) {
case GNUTLS_CRT_X509:
return
_gnutls_x509_get_raw_crt_activation_time(&info->
diff --git a/lib/ext/cert_types.h b/lib/ext/cert_types.h
index c54e0f2bfe..04e024d5db 100644
--- a/lib/ext/cert_types.h
+++ b/lib/ext/cert_types.h
@@ -26,11 +26,13 @@
/* Maps IANA TLS Certificate Types identifiers to internal
* certificate type representation.
*/
-static inline gnutls_certificate_type_t _gnutls_IANA2cert_type(int num)
+static inline gnutls_certificate_type_t IANA2cert_type(int num)
{
switch (num) {
case 0:
return GNUTLS_CRT_X509;
+ case 2:
+ return GNUTLS_CRT_RAWPK;
default:
return GNUTLS_CRT_UNKNOWN;
}
@@ -39,12 +41,43 @@ static inline gnutls_certificate_type_t _gnutls_IANA2cert_type(int num)
/* Maps internal certificate type representation to
* IANA TLS Certificate Types identifiers.
*/
-static inline int _gnutls_cert_type2IANA(gnutls_certificate_type_t cert_type)
+static inline int cert_type2IANA(gnutls_certificate_type_t cert_type)
{
switch (cert_type) {
case GNUTLS_CRT_X509:
return 0;
+ case GNUTLS_CRT_RAWPK:
+ return 2;
default:
return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
}
}
+
+/* Checks whether the given cert type is enabled in the application
+ */
+static inline bool is_cert_type_enabled(gnutls_session_t session, gnutls_certificate_type_t cert_type)
+{
+ switch(cert_type) {
+ case GNUTLS_CRT_X509:
+ // Default cert type, always enabled
+ return true;
+ case GNUTLS_CRT_RAWPK:
+ return session->internals.flags & GNUTLS_ENABLE_RAWPK;
+ default:
+ // When not explicitly supported here disable it
+ return false;
+ }
+}
+
+/* Checks whether alternative cert types (i.e. other than X.509)
+ * are enabled in the application
+ */
+static inline bool are_alternative_cert_types_allowed(gnutls_session_t session)
+{
+ // OR-ed list of defined cert type init flags
+ #define CERT_TYPES_FLAGS GNUTLS_ENABLE_RAWPK
+
+ return session->internals.flags & CERT_TYPES_FLAGS;
+
+ #undef CERT_TYPES_FLAGS
+}
diff --git a/lib/ext/client_cert_type.c b/lib/ext/client_cert_type.c
index 5449eae678..534c407b3a 100644
--- a/lib/ext/client_cert_type.c
+++ b/lib/ext/client_cert_type.c
@@ -33,8 +33,8 @@
#include "hello_ext.h"
#include "hello_ext_lib.h"
#include "errors.h"
-#include <state.h>
-#include <datum.h>
+#include "state.h"
+#include "datum.h"
static int _gnutls_client_cert_type_recv_params(gnutls_session_t session,
@@ -76,10 +76,10 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session,
ssize_t len = data_size;
const uint8_t* pdata = data;
- /* Only activate this extension if cert type negotiation is enabled
- * and we have cert credentials set */
- if (!_gnutls_has_negotiate_ctypes(session) ||
- _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL)
+ /* Only activate this extension if we have cert credentials set
+ * and alternative cert types are allowed */
+ if (!are_alternative_cert_types_allowed(session) ||
+ (_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL))
return 0;
if (!IS_SERVER(session)) { // client mode
@@ -97,7 +97,7 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session,
* receive a cert type that we offered, i.e. one that we support.
* Because the world isn't as beautiful as it may seem, we're going
* to check it nevertheless. */
- cert_type = _gnutls_IANA2cert_type(pdata[0]);
+ cert_type = IANA2cert_type(pdata[0]);
// Check validity of cert type
if (cert_type == GNUTLS_CRT_UNKNOWN) {
@@ -119,7 +119,7 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session,
// Check whether what we got back is actually offered by us
for (i = 0; i < sent_cert_types.size; i++) {
- if (_gnutls_IANA2cert_type(sent_cert_types.data[i]) == cert_type)
+ if (IANA2cert_type(sent_cert_types.data[i]) == cert_type)
found = 1;
}
@@ -160,7 +160,7 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session,
*/
for (i = 0; i < cert_types.size; i++) {
// Convert to internal representation
- cert_type = _gnutls_IANA2cert_type(cert_types.data[i]);
+ cert_type = IANA2cert_type(cert_types.data[i]);
// If we have an invalid cert id then continue to the next
if (cert_type == GNUTLS_CRT_UNKNOWN)
@@ -201,13 +201,13 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session,
uint8_t i = 0, num_cert_types = 0;
priority_st* cert_priorities;
gnutls_datum_t tmp_cert_types; // For type conversion
- uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported cert types
+ uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported cert types. Inv: 0 <= cert type Id < 256
const version_entry_st* vers = get_version(session);
- /* Only activate this extension if cert type negotiation is enabled
- * and we have cert credentials set */
- if (!_gnutls_has_negotiate_ctypes(session) ||
- _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL)
+ /* Only activate this extension if we have cert credentials set
+ * and alternative cert types are allowed */
+ if (!are_alternative_cert_types_allowed(session) ||
+ (_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL))
return 0;
if (!IS_SERVER(session)) { // Client mode
@@ -255,7 +255,13 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session,
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
// Convert to IANA representation
- cert_type = _gnutls_cert_type2IANA(cert_priorities->priorities[i]);
+ ret = cert_type2IANA(cert_priorities->priorities[i]);
+
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ cert_type = ret; // For readability
+
// Add this cert type to our list with supported types
cert_types[num_cert_types] = cert_type;
num_cert_types++;
@@ -282,7 +288,7 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session,
return 0;
} else if (num_cert_types == 1 &&
- _gnutls_IANA2cert_type(cert_types[0]) == DEFAULT_CERT_TYPE) {
+ IANA2cert_type(cert_types[0]) == DEFAULT_CERT_TYPE) {
_gnutls_handshake_log
("EXT[%p]: The only supported client certificate type is (%s) which is the default. "
"We therefore do not send this extension.\n",
@@ -342,9 +348,13 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session,
* when we cannot find a matching client certificate. This is conform
* spec (RFC7250, 4.2 case 2.).
*/
- cert_type =
- _gnutls_cert_type2IANA(session->
- security_parameters.client_ctype);
+ ret = cert_type2IANA(get_certificate_type(
+ session, GNUTLS_CTYPE_CLIENT));
+
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ cert_type = ret; // For readability
ret = gnutls_buffer_append_data(data, &cert_type, 1);
diff --git a/lib/ext/server_cert_type.c b/lib/ext/server_cert_type.c
index a00a0376c9..35c6d751db 100644
--- a/lib/ext/server_cert_type.c
+++ b/lib/ext/server_cert_type.c
@@ -33,8 +33,8 @@
#include "hello_ext.h"
#include "hello_ext_lib.h"
#include "errors.h"
-#include <state.h>
-#include <datum.h>
+#include "state.h"
+#include "datum.h"
static int _gnutls_server_cert_type_recv_params(gnutls_session_t session,
@@ -76,10 +76,10 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session,
ssize_t len = data_size;
const uint8_t* pdata = data;
- /* Only activate this extension if cert type negotiation is enabled
- * and we have cert credentials set */
- if (!_gnutls_has_negotiate_ctypes(session) ||
- _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL)
+ /* Only activate this extension if we have cert credentials set
+ * and alternative cert types are allowed */
+ if (!are_alternative_cert_types_allowed(session) ||
+ (_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL))
return 0;
if (!IS_SERVER(session)) { // client mode
@@ -96,7 +96,7 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session,
* may only receive a cert type that we offered, i.e. one that we
* support. Because the world isn't as beautiful as it may seem,
* we're going to check it nevertheless. */
- cert_type = _gnutls_IANA2cert_type(pdata[0]);
+ cert_type = IANA2cert_type(pdata[0]);
// Check validity of cert type
if (cert_type == GNUTLS_CRT_UNKNOWN) {
@@ -118,7 +118,7 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session,
// Check whether what we got back is actually offered by us
for (i = 0; i < sent_cert_types.size; i++) {
- if (_gnutls_IANA2cert_type(sent_cert_types.data[i]) == cert_type)
+ if (IANA2cert_type(sent_cert_types.data[i]) == cert_type)
found = 1;
}
@@ -159,7 +159,7 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session,
*/
for (i = 0; i < cert_types.size; i++) {
// Convert to internal representation
- cert_type = _gnutls_IANA2cert_type(cert_types.data[i]);
+ cert_type = IANA2cert_type(cert_types.data[i]);
// If we have an invalid cert id then continue to the next
if (cert_type == GNUTLS_CRT_UNKNOWN)
@@ -197,12 +197,12 @@ static int _gnutls_server_cert_type_send_params(gnutls_session_t session,
uint8_t i = 0, num_cert_types = 0;
priority_st* cert_priorities;
gnutls_datum_t tmp_cert_types; // For type conversion
- uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported cert types
+ uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported cert types. Inv: 0 <= cert type Id < 256
- /* Only activate this extension if cert type negotiation is enabled
- * and we have cert credentials set */
- if (!_gnutls_has_negotiate_ctypes(session) ||
- _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL)
+ /* Only activate this extension if we have cert credentials set
+ * and alternative cert types are allowed */
+ if (!are_alternative_cert_types_allowed(session) ||
+ (_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL))
return 0;
if (!IS_SERVER(session)) { // Client mode
@@ -255,7 +255,13 @@ static int _gnutls_server_cert_type_send_params(gnutls_session_t session,
return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
// Convert to IANA representation
- cert_type = _gnutls_cert_type2IANA(cert_priorities->priorities[i]);
+ ret = cert_type2IANA(cert_priorities->priorities[i]);
+
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ cert_type = ret; // For readability
+
// Add this cert type to our list with supported types
cert_types[num_cert_types] = cert_type;
num_cert_types++;
@@ -281,7 +287,7 @@ static int _gnutls_server_cert_type_send_params(gnutls_session_t session,
return 0;
} else if (num_cert_types == 1 &&
- _gnutls_IANA2cert_type(cert_types[0]) == DEFAULT_CERT_TYPE) {
+ IANA2cert_type(cert_types[0]) == DEFAULT_CERT_TYPE) {
_gnutls_handshake_log
("EXT[%p]: The only supported server certificate type is (%s) which is the default. "
"We therefore do not send this extension.\n",
@@ -320,9 +326,13 @@ static int _gnutls_server_cert_type_send_params(gnutls_session_t session,
}
} else { // Server mode
// Retrieve negotiated server certificate type and send it
- cert_type =
- _gnutls_cert_type2IANA(session->security_parameters.
- server_ctype);
+ ret = cert_type2IANA(get_certificate_type(
+ session, GNUTLS_CTYPE_SERVER));
+
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ cert_type = ret; // For readability
ret = gnutls_buffer_append_data(data, &cert_type, 1);
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index cccc3d1a97..8baa8815e7 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -1561,9 +1561,39 @@ inline static size_t max_user_send_size(gnutls_session_t session,
return max;
}
-inline static bool _gnutls_has_negotiate_ctypes(gnutls_session_t session)
+/* Returns the during the handshake negotiated certificate type(s).
+ * See state.c for the full function documentation.
+ *
+ * This function is made static inline for optimization reasons.
+ */
+static inline gnutls_certificate_type_t
+get_certificate_type(gnutls_session_t session,
+ gnutls_ctype_target_t target)
{
- return session->internals.flags & GNUTLS_ENABLE_CERT_TYPE_NEG;
+ switch (target) {
+ case GNUTLS_CTYPE_CLIENT:
+ return session->security_parameters.client_ctype;
+ break;
+ case GNUTLS_CTYPE_SERVER:
+ return session->security_parameters.server_ctype;
+ break;
+ case GNUTLS_CTYPE_OURS:
+ if (IS_SERVER(session)) {
+ return session->security_parameters.server_ctype;
+ } else {
+ return session->security_parameters.client_ctype;
+ }
+ break;
+ case GNUTLS_CTYPE_PEERS:
+ if (IS_SERVER(session)) {
+ return session->security_parameters.client_ctype;
+ } else {
+ return session->security_parameters.server_ctype;
+ }
+ break;
+ default: // Illegal parameter passed
+ return GNUTLS_CRT_UNKNOWN;
+ }
}
/* Macros to aide constant time/mem checks */
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index fcff0a562f..223fb2ed1f 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -693,6 +693,14 @@ int gnutls_pcert_export_openpgp(gnutls_pcert_st * pcert,
void gnutls_pcert_deinit(gnutls_pcert_st * pcert);
+int gnutls_pcert_import_rawpk(gnutls_pcert_st* pcert,
+ gnutls_pubkey_t key, unsigned int flags);
+
+int gnutls_pcert_import_rawpk_raw(gnutls_pcert_st* pcert,
+ const gnutls_datum_t* rawpubkey,
+ gnutls_x509_crt_fmt_t format,
+ unsigned int key_usage, unsigned int flags);
+
/* For certificate credentials */
/* This is the same as gnutls_certificate_retrieve_function()
* but retrieves a gnutls_pcert_st which requires much less processing
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 73141a3a3b..1c3455c0cf 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -421,7 +421,6 @@ typedef enum {
* applications which hide the length of transferred data via the TLS1.3 padding mechanism and
* are already taking steps to hide the data processing time. This comes at a performance
* penalty.
- * @GNUTLS_ENABLE_CERT_TYPE_NEG: Enable certificate type negotiation extensions (RFC7250).
* @GNUTLS_AUTO_REAUTH: Enable transparent re-authentication in client side when the server
* requests to. That is, reauthentication is handled within gnutls_record_recv(), and
* the %GNUTLS_E_REHANDSHAKE or %GNUTLS_E_REAUTH_REQUEST are not returned. This must be
@@ -430,6 +429,10 @@ typedef enum {
* since gnutls_record_recv() could be interrupted when sending when this flag is enabled.
* Note this flag may not be used if you are using the same session for sending and receiving
* in different threads.
+ * @GNUTLS_ENABLE_EARLY_DATA: Under TLS1.3 allow the server to receive early data sent as part of the initial ClientHello (0-RTT).
+ * This is not enabled by default as early data has weaker security properties than other data. Since 3.6.5.
+ *
+ * @GNUTLS_ENABLE_RAWPK: Allows raw public-keys to be negotiated during the handshake. Since 3.6.6.
*
* Enumeration of different flags for gnutls_init() function. All the flags
* can be combined except @GNUTLS_SERVER and @GNUTLS_CLIENT which are mutually
@@ -458,7 +461,7 @@ typedef enum {
GNUTLS_NO_AUTO_REKEY = (1<<15),
GNUTLS_SAFE_PADDING_CHECK = (1<<16),
GNUTLS_ENABLE_EARLY_START = (1<<17),
- GNUTLS_ENABLE_CERT_TYPE_NEG = (1<<18),
+ GNUTLS_ENABLE_RAWPK = (1<<18),
GNUTLS_AUTO_REAUTH = (1<<19),
GNUTLS_ENABLE_EARLY_DATA = (1<<20)
} gnutls_init_flags_t;
@@ -476,6 +479,8 @@ typedef enum {
#define GNUTLS_ENABLE_FALSE_START (1<<8)
#define GNUTLS_FORCE_CLIENT_CERT (1<<9)
#define GNUTLS_NO_TICKETS (1<<10)
+#define GNUTLS_ENABLE_CERT_TYPE_NEG 0
+ // Here for compatibility reasons
/**
* gnutls_alert_level_t:
@@ -630,7 +635,7 @@ const char
* @GNUTLS_CERT_SIGNER_NOT_FOUND: The certificate's issuer is not known.
* This is the case if the issuer is not included in the trusted certificate list.
* @GNUTLS_CERT_SIGNER_NOT_CA: The certificate's signer was not a CA. This
- * may happen if this was a version 1 certificate, which is common with
+ * may happen if this was a version 1 certificate, which is common with
* some CAs, or a version 3 certificate without the basic constrains extension.
* @GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE: The certificate's signer constraints were
* violated.
@@ -1405,7 +1410,7 @@ ssize_t gnutls_record_recv(gnutls_session_t session, void *data,
typedef struct mbuffer_st *gnutls_packet_t;
ssize_t
-gnutls_record_recv_packet(gnutls_session_t session,
+gnutls_record_recv_packet(gnutls_session_t session,
gnutls_packet_t *packet);
void gnutls_packet_get(gnutls_packet_t packet, gnutls_datum_t *data, unsigned char *sequence);
@@ -1685,7 +1690,7 @@ const char *
gnutls_protocol_get_name(gnutls_protocol_t version) __GNUTLS_CONST__;
-/* get/set session
+/* get/set session
*/
int gnutls_session_set_data(gnutls_session_t session,
const void *session_data,
@@ -1776,7 +1781,7 @@ int gnutls_session_channel_binding(gnutls_session_t session,
gnutls_channel_binding_t cbtype,
gnutls_datum_t * cb);
-/* checks if this session is a resumed one
+/* checks if this session is a resumed one
*/
int gnutls_session_is_resumed(gnutls_session_t session);
int gnutls_session_resumption_requested(gnutls_session_t session);
@@ -2130,6 +2135,29 @@ gnutls_ocsp_status_request_get2(gnutls_session_t session,
unsigned idx,
gnutls_datum_t * response);
+/* RAW public key functions (RFC7250) */
+int gnutls_certificate_set_rawpk_key_mem(gnutls_certificate_credentials_t cred,
+ const gnutls_datum_t* spki,
+ const gnutls_datum_t* pkey,
+ gnutls_x509_crt_fmt_t format,
+ const char* pass,
+ unsigned int key_usage,
+ const char **names,
+ unsigned int names_length,
+ unsigned int flags);
+
+int gnutls_certificate_set_rawpk_key_file(gnutls_certificate_credentials_t cred,
+ const char* rawpkfile,
+ const char* privkeyfile,
+ gnutls_x509_crt_fmt_t format,
+ const char *pass,
+ unsigned int key_usage,
+ const char **names,
+ unsigned int names_length,
+ unsigned int privkey_flags,
+ unsigned int pkcs11_flags);
+
+
/* global state functions
*/
int gnutls_global_init(void);
@@ -2272,7 +2300,7 @@ void gnutls_transport_set_errno_function(gnutls_session_t session,
void gnutls_transport_set_errno(gnutls_session_t session, int err);
-/* session specific
+/* session specific
*/
void gnutls_session_set_ptr(gnutls_session_t session, void *ptr);
void *gnutls_session_get_ptr(gnutls_session_t session);
@@ -2305,7 +2333,7 @@ int gnutls_random_art(gnutls_random_art_t type,
int gnutls_idna_map(const char * input, unsigned ilen, gnutls_datum_t *out, unsigned flags);
int gnutls_idna_reverse_map(const char *input, unsigned ilen, gnutls_datum_t *out, unsigned flags);
-/* SRP
+/* SRP
*/
typedef struct gnutls_srp_server_credentials_st
@@ -2974,13 +3002,13 @@ typedef int (*gnutls_supp_recv_func) (gnutls_session_t session,
typedef int (*gnutls_supp_send_func) (gnutls_session_t session,
gnutls_buffer_t buf);
-int gnutls_supplemental_register(const char *name,
- gnutls_supplemental_data_format_type_t type,
+int gnutls_supplemental_register(const char *name,
+ gnutls_supplemental_data_format_type_t type,
gnutls_supp_recv_func supp_recv_func,
gnutls_supp_send_func supp_send_func);
int gnutls_session_supplemental_register(gnutls_session_t session, const char *name,
- gnutls_supplemental_data_format_type_t type,
+ gnutls_supplemental_data_format_type_t type,
gnutls_supp_recv_func supp_recv_func,
gnutls_supp_send_func supp_send_func,
unsigned int flags);
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index bfb447ccfd..197644ea43 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1264,6 +1264,15 @@ GNUTLS_3_6_5
gnutls_privkey_decrypt_data2;
} GNUTLS_3_6_4;
+GNUTLS_3_6_6
+{
+ global:
+ gnutls_certificate_set_rawpk_key_mem;
+ gnutls_certificate_set_rawpk_key_file;
+ gnutls_pcert_import_rawpk;
+ gnutls_pcert_import_rawpk_raw;
+} GNUTLS_3_6_5;
+
GNUTLS_FIPS140_3_4 {
global:
gnutls_cipher_self_test;
diff --git a/lib/pcert.c b/lib/pcert.c
index b800e91fc4..816a748b05 100644
--- a/lib/pcert.c
+++ b/lib/pcert.c
@@ -27,6 +27,7 @@
#include <x509.h>
#include "x509/x509_int.h"
#include <gnutls/x509.h>
+#include "x509_b64.h"
/**
* gnutls_pcert_import_x509:
@@ -215,7 +216,7 @@ gnutls_pcert_list_import_x509_raw(gnutls_pcert_st *pcert_list,
cleanup:
for (i = 0; i < *pcert_list_size; i++)
gnutls_x509_crt_deinit(crt[i]);
-
+
cleanup_crt:
gnutls_free(crt);
return ret;
@@ -356,6 +357,133 @@ int gnutls_pcert_import_x509_raw(gnutls_pcert_st * pcert,
}
/**
+ * gnutls_pcert_import_rawpk:
+ * @pcert: The pcert structure to import the data into.
+ * @pubkey: The raw public-key in #gnutls_pubkey_t format to be imported
+ * @flags: zero for now
+ *
+ * This convenience function will import (i.e. convert) the given raw
+ * public key @pubkey into a #gnutls_pcert_st structure. The structure
+ * must be deinitialized afterwards using gnutls_pcert_deinit(). The
+ * given @pubkey must not be deinitialized because it will be associated
+ * with the given @pcert structure and will be deinitialized with it.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ *
+ * Since: 3.6.6
+ **/
+int gnutls_pcert_import_rawpk(gnutls_pcert_st* pcert,
+ gnutls_pubkey_t pubkey, unsigned int flags)
+{
+ int ret;
+
+ if (pubkey == NULL) {
+ return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+
+ memset(pcert, 0, sizeof(*pcert));
+
+ /* A pcert struct holds a raw copy of the certificate data.
+ * Therefore we convert our gnutls_pubkey_t to its raw DER
+ * representation and copy it into our pcert. It is this raw data
+ * that will be transfered to the peer via a Certificate msg.
+ * According to the spec (RFC7250) a DER representation must be used.
+ */
+ ret = gnutls_pubkey_export2(pubkey, GNUTLS_X509_FMT_DER, &pcert->cert);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ pcert->pubkey = pubkey;
+
+ pcert->type = GNUTLS_CRT_RAWPK;
+
+ return GNUTLS_E_SUCCESS;
+}
+
+/**
+ * gnutls_pcert_import_rawpk_raw:
+ * @pcert: The pcert structure to import the data into.
+ * @rawpubkey: The raw public-key in #gnutls_datum_t format to be imported.
+ * @format: The format of the raw public-key. DER or PEM.
+ * @key_usage: An ORed sequence of %GNUTLS_KEY_* flags.
+ * @flags: zero for now
+ *
+ * This convenience function will import (i.e. convert) the given raw
+ * public key @rawpubkey into a #gnutls_pcert_st structure. The structure
+ * must be deinitialized afterwards using gnutls_pcert_deinit().
+ * Note that the caller is responsible for freeing @rawpubkey. All necessary
+ * values will be copied into @pcert.
+ *
+ * Key usage (as defined by X.509 extension (2.5.29.15)) can be explicitly
+ * set because there is no certificate structure around the key to define
+ * this value. See for more info gnutls_x509_crt_get_key_usage().
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ *
+ * Since: 3.6.6
+ **/
+int gnutls_pcert_import_rawpk_raw(gnutls_pcert_st* pcert,
+ const gnutls_datum_t* rawpubkey,
+ gnutls_x509_crt_fmt_t format,
+ unsigned int key_usage, unsigned int flags)
+{
+ int ret;
+
+ if (rawpubkey == NULL) {
+ return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+
+ memset(pcert, 0, sizeof(*pcert));
+
+ ret = gnutls_pubkey_init(&pcert->pubkey);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ // Convert our raw public-key to a gnutls_pubkey_t structure
+ ret = gnutls_pubkey_import(pcert->pubkey, rawpubkey, format);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
+
+ pcert->pubkey->key_usage = key_usage;
+
+ /* A pcert struct holds a raw copy of the certificate data.
+ * It is this raw data that will be transfered to the peer via a
+ * Certificate message. According to the spec (RFC7250) a DER
+ * representation must be used. Therefore we check the format and
+ * convert if necessary.
+ */
+ if (format == GNUTLS_X509_FMT_PEM) {
+ ret = _gnutls_fbase64_decode(PEM_PK,
+ rawpubkey->data, rawpubkey->size,
+ &pcert->cert);
+
+ if (ret < 0) {
+ gnutls_pubkey_deinit(pcert->pubkey);
+
+ return gnutls_assert_val(ret);
+ }
+ } else {
+ // Directly copy the raw DER data to our pcert
+ ret = _gnutls_set_datum(&pcert->cert, rawpubkey->data, rawpubkey->size);
+
+ if (ret < 0) {
+ gnutls_pubkey_deinit(pcert->pubkey);
+
+ return gnutls_assert_val(ret);
+ }
+ }
+
+ pcert->type = GNUTLS_CRT_RAWPK;
+
+ return GNUTLS_E_SUCCESS;
+}
+
+/**
* gnutls_pcert_export_x509:
* @pcert: The pcert structure.
* @crt: An initialized #gnutls_x509_crt_t.
@@ -420,15 +548,17 @@ _gnutls_get_auth_info_pcert(gnutls_pcert_st * pcert,
cert_auth_info_t info)
{
switch (type) {
- case GNUTLS_CRT_X509:
- return gnutls_pcert_import_x509_raw(pcert,
- &info->
- raw_certificate_list
- [0],
- GNUTLS_X509_FMT_DER,
- 0);
- default:
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
+ case GNUTLS_CRT_X509:
+ return gnutls_pcert_import_x509_raw(pcert,
+ &info->raw_certificate_list[0],
+ GNUTLS_X509_FMT_DER,
+ 0);
+ case GNUTLS_CRT_RAWPK:
+ return gnutls_pcert_import_rawpk_raw(pcert,
+ &info->raw_certificate_list[0],
+ GNUTLS_X509_FMT_DER,
+ 0, 0);
+ default:
+ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
}
}
diff --git a/lib/pkcs11x.c b/lib/pkcs11x.c
index fc428e17a4..c11f12cb8d 100644
--- a/lib/pkcs11x.c
+++ b/lib/pkcs11x.c
@@ -277,7 +277,7 @@ gnutls_pkcs11_obj_get_exts(gnutls_pkcs11_obj_t obj,
spki.data = obj->raw.data;
spki.size = obj->raw.size;
} else {
- ret = x509_raw_crt_to_raw_pubkey(&obj->raw, &spki);
+ ret = _gnutls_x509_raw_crt_to_raw_pubkey(&obj->raw, &spki);
if (ret < 0)
return gnutls_assert_val(ret);
deinit_spki = 1;
diff --git a/lib/session.c b/lib/session.c
index a7ac943153..a5c9c93d53 100644
--- a/lib/session.c
+++ b/lib/session.c
@@ -27,6 +27,7 @@
#include <datum.h>
#include "buffers.h"
#include "state.h"
+#include "ext/cert_types.h"
/**
* gnutls_session_get_data:
@@ -423,11 +424,10 @@ char *gnutls_session_get_desc(gnutls_session_t session)
}
}
- // Check whether we have negotiated certificate types
- if (_gnutls_has_negotiate_ctypes(session)) {
+ if (are_alternative_cert_types_allowed(session)) {
// Get certificate types
- ctype_client = gnutls_certificate_type_get2(session, GNUTLS_CTYPE_CLIENT);
- ctype_server = gnutls_certificate_type_get2(session, GNUTLS_CTYPE_SERVER);
+ ctype_client = get_certificate_type(session, GNUTLS_CTYPE_CLIENT);
+ ctype_server = get_certificate_type(session, GNUTLS_CTYPE_SERVER);
if (ctype_client == ctype_server) {
// print proto version, client/server cert type
@@ -442,9 +442,8 @@ char *gnutls_session_get_desc(gnutls_session_t session)
gnutls_certificate_type_get_name(ctype_server));
}
} else { // Assumed default certificate type (X.509)
- snprintf(proto_name, sizeof(proto_name), "%s",
- gnutls_protocol_get_name(get_num_version
- (session)));
+ snprintf(proto_name, sizeof(proto_name), "%s",
+ gnutls_protocol_get_name(get_num_version(session)));
}
desc = gnutls_malloc(DESC_SIZE);
diff --git a/lib/state.c b/lib/state.c
index 392183c95f..540a83c7b8 100644
--- a/lib/state.c
+++ b/lib/state.c
@@ -52,6 +52,7 @@
#include <gnutls/dtls.h>
#include "dtls.h"
#include "tls13/session_ticket.h"
+#include "ext/cert_types.h"
/* to be used by supplemental data support to disable TLS1.3
* when supplemental data have been globally registered */
@@ -140,30 +141,9 @@ gnutls_certificate_type_t
gnutls_certificate_type_get2(gnutls_session_t session,
gnutls_ctype_target_t target)
{
- switch (target) {
- case GNUTLS_CTYPE_CLIENT:
- return session->security_parameters.client_ctype;
- break;
- case GNUTLS_CTYPE_SERVER:
- return session->security_parameters.server_ctype;
- break;
- case GNUTLS_CTYPE_OURS:
- if (IS_SERVER(session)) {
- return session->security_parameters.server_ctype;
- } else {
- return session->security_parameters.client_ctype;
- }
- break;
- case GNUTLS_CTYPE_PEERS:
- if (IS_SERVER(session)) {
- return session->security_parameters.client_ctype;
- } else {
- return session->security_parameters.server_ctype;
- }
- break;
- default: // Illegal parameter passed
- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- }
+ /* We want to inline this function so therefore
+ * we've defined it in gnutls_int.h */
+ return get_certificate_type(session, target);
}
/**
@@ -309,6 +289,10 @@ _gnutls_session_cert_type_supported(gnutls_session_t session,
unsigned i;
priority_st* ctype_priorities;
+ // Check whether this cert type is enabled by the application
+ if (!is_cert_type_enabled(session, cert_type))
+ return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
+
// Perform a credentials check if requested
if (check_credentials) {
if (!_gnutls_has_cert_credentials(session, cert_type))
@@ -336,14 +320,14 @@ _gnutls_session_cert_type_supported(gnutls_session_t session,
// No explicit priorities set, and default ctype is asked
if (ctype_priorities->num_priorities == 0
&& cert_type == DEFAULT_CERT_TYPE)
- return 0; // ok
+ return 0;
/* Now lets find out whether our cert type is in our priority
* list, i.e. set of allowed cert types.
*/
for (i = 0; i < ctype_priorities->num_priorities; i++) {
if (ctype_priorities->priorities[i] == cert_type)
- return 0; /* ok */
+ return 0;
}
return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
diff --git a/lib/str_array.h b/lib/str_array.h
index ef68783905..abec702488 100644
--- a/lib/str_array.h
+++ b/lib/str_array.h
@@ -112,4 +112,24 @@ inline static int _gnutls_str_array_append(gnutls_str_array_t * head,
return 0;
}
+inline static int _gnutls_str_array_append_idna(gnutls_str_array_t * head,
+ const char *name, size_t size)
+{
+ int ret;
+ gnutls_datum_t ahost;
+
+ /* convert the provided hostname to ACE-Labels domain. */
+ ret = gnutls_idna_map(name, size, &ahost, 0);
+ if (ret < 0) {
+ _gnutls_debug_log("unable to convert hostname %s to IDNA format\n", name);
+ /* insert the raw name */
+ return _gnutls_str_array_append(head, name, size);
+ }
+
+ ret = _gnutls_str_array_append(head, (char*)ahost.data, ahost.size);
+ gnutls_free(ahost.data);
+
+ return ret;
+}
+
#endif
diff --git a/lib/tls13/certificate_verify.c b/lib/tls13/certificate_verify.c
index 01966b14d1..26c93d2c1d 100644
--- a/lib/tls13/certificate_verify.c
+++ b/lib/tls13/certificate_verify.c
@@ -113,7 +113,7 @@ int _gnutls13_recv_certificate_verify(gnutls_session_t session)
/* We verify the certificate of the peer. Therefore we need to
* retrieve the negotiated certificate type for the peer. */
- cert_type = gnutls_certificate_type_get2(session, GNUTLS_CTYPE_PEERS);
+ cert_type = get_certificate_type(session, GNUTLS_CTYPE_PEERS);
/* Verify the signature */
ret = _gnutls_get_auth_info_pcert(&peer_cert, cert_type, info);
diff --git a/lib/verify-tofu.c b/lib/verify-tofu.c
index 310778629b..66a583ded7 100644
--- a/lib/verify-tofu.c
+++ b/lib/verify-tofu.c
@@ -77,11 +77,11 @@ struct gnutls_tdb_int default_tdb = {
* @cert: The raw (der) data of the certificate
* @flags: should be 0.
*
- * This function will try to verify the provided (raw or DER-encoded) certificate
- * using a list of stored public keys. The @service field if non-NULL should
- * be a port number.
+ * This function will try to verify a raw public-key or a public-key provided via
+ * a raw (DER-encoded) certificate using a list of stored public keys.
+ * The @service field if non-NULL should be a port number.
*
- * The @retrieve variable if non-null specifies a custom backend for
+ * The @db_name variable if non-null specifies a custom backend for
* the retrieval of entries. If it is NULL then the
* default file backend will be used. In POSIX-like systems the
* file backend uses the $HOME/.gnutls/known_hosts file.
@@ -93,10 +93,12 @@ struct gnutls_tdb_int default_tdb = {
* the given key is found, and 0 if it was found. The storage
* function should return 0 on success.
*
+ * As of GnuTLS 3.6.6 this function also verifies raw public keys.
+ *
* Returns: If no associated public key is found
* then %GNUTLS_E_NO_CERTIFICATE_FOUND will be returned. If a key
* is found but does not match %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
- * is returned. On success, %GNUTLS_E_SUCCESS (0) is returned,
+ * is returned. On success, %GNUTLS_E_SUCCESS (0) is returned,
* or a negative error value on other errors.
*
* Since: 3.0.13
@@ -110,14 +112,11 @@ gnutls_verify_stored_pubkey(const char *db_name,
const gnutls_datum_t * cert,
unsigned int flags)
{
- gnutls_datum_t pubkey = { NULL, 0 };
+ gnutls_datum_t pubkey = { NULL, 0 }; // Holds the pubkey in subjectPublicKeyInfo format (DER encoded)
int ret;
char local_file[MAX_FILENAME];
+ bool need_free;
- if (cert_type != GNUTLS_CRT_X509)
- return
- gnutls_assert_val
- (GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
if (db_name == NULL && tdb == NULL) {
ret = find_config_file(local_file, sizeof(local_file));
@@ -129,18 +128,38 @@ gnutls_verify_stored_pubkey(const char *db_name,
if (tdb == NULL)
tdb = &default_tdb;
- ret = x509_raw_crt_to_raw_pubkey(cert, &pubkey);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
+ /* Import the public key depending on the provided certificate type */
+ switch (cert_type) {
+ case GNUTLS_CRT_X509:
+ /* Extract the pubkey from the cert. This function does a malloc
+ * deep down the call chain. We are responsible for freeing. */
+ ret = _gnutls_x509_raw_crt_to_raw_pubkey(cert, &pubkey);
+
+ if (ret < 0) {
+ _gnutls_free_datum(&pubkey);
+ return gnutls_assert_val(ret);
+ }
+
+ need_free = true;
+ break;
+ case GNUTLS_CRT_RAWPK:
+ pubkey.data = cert->data;
+ pubkey.size = cert->size;
+ need_free = false;
+ break;
+ default:
+ return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
}
+ // Verify our pubkey against the database
ret = tdb->verify(db_name, host, service, &pubkey);
if (ret < 0 && ret != GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
ret = gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);
- cleanup:
- gnutls_free(pubkey.data);
+ if (need_free) {
+ _gnutls_free_datum(&pubkey);
+ }
+
return ret;
}
@@ -203,7 +222,7 @@ static int parse_commitment_line(char *line,
/* hash and hex encode */
ret =
- _gnutls_hash_fast((gnutls_digest_algorithm_t)hash_algo->id,
+ _gnutls_hash_fast((gnutls_digest_algorithm_t)hash_algo->id,
skey->data, skey->size, phash);
if (ret < 0)
return gnutls_assert_val(ret);
@@ -301,7 +320,7 @@ static int parse_line(char *line,
return 0;
}
-/* Returns the base64 key if found
+/* Returns the base64 key if found
*/
static int verify_pubkey(const char *file,
const char *host, const char *service,
@@ -460,11 +479,11 @@ int store_commitment(const char *db_name, const char *host,
* @expiration: The expiration time (use 0 to disable expiration)
* @flags: should be 0.
*
- * This function will store the provided (raw or DER-encoded) certificate to
- * the list of stored public keys. The key will be considered valid until
- * the provided expiration time.
+ * This function will store a raw public-key or a public-key provided via
+ * a raw (DER-encoded) certificate to the list of stored public keys. The key
+ * will be considered valid until the provided expiration time.
*
- * The @store variable if non-null specifies a custom backend for
+ * The @tdb variable if non-null specifies a custom backend for
* the storage of entries. If it is NULL then the
* default file backend will be used.
*
@@ -475,6 +494,8 @@ int store_commitment(const char *db_name, const char *host,
* time in seconds since the epoch (0 for no expiration), and a base64
* encoding of the raw (DER) public key information (SPKI) of the peer.
*
+ * As of GnuTLS 3.6.6 this function also accepts raw public keys.
+ *
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
* negative error value.
*
@@ -489,14 +510,11 @@ gnutls_store_pubkey(const char *db_name,
const gnutls_datum_t * cert,
time_t expiration, unsigned int flags)
{
- gnutls_datum_t pubkey = { NULL, 0 };
+ gnutls_datum_t pubkey = { NULL, 0 }; // Holds the pubkey in subjectPublicKeyInfo format (DER encoded)
int ret;
char local_file[MAX_FILENAME];
+ bool need_free;
- if (cert_type != GNUTLS_CRT_X509)
- return
- gnutls_assert_val
- (GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
if (db_name == NULL && tdb == NULL) {
ret =
@@ -517,22 +535,38 @@ gnutls_store_pubkey(const char *db_name,
if (tdb == NULL)
tdb = &default_tdb;
- ret = x509_raw_crt_to_raw_pubkey(cert, &pubkey);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
+ /* Import the public key depending on the provided certificate type */
+ switch (cert_type) {
+ case GNUTLS_CRT_X509:
+ /* Extract the pubkey from the cert. This function does a malloc
+ * deep down the call chain. We are responsible for freeing. */
+ ret = _gnutls_x509_raw_crt_to_raw_pubkey(cert, &pubkey);
+
+ if (ret < 0) {
+ _gnutls_free_datum(&pubkey);
+ return gnutls_assert_val(ret);
+ }
+
+ need_free = true;
+ break;
+ case GNUTLS_CRT_RAWPK:
+ pubkey.data = cert->data;
+ pubkey.size = cert->size;
+ need_free = false;
+ break;
+ default:
+ return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
}
_gnutls_debug_log("Configuration file: %s\n", db_name);
tdb->store(db_name, host, service, expiration, &pubkey);
- ret = 0;
-
- cleanup:
- gnutls_free(pubkey.data);
+ if (need_free) {
+ _gnutls_free_datum(&pubkey);
+ }
- return ret;
+ return GNUTLS_E_SUCCESS;
}
/**
@@ -546,11 +580,11 @@ gnutls_store_pubkey(const char *db_name,
* @expiration: The expiration time (use 0 to disable expiration)
* @flags: should be 0 or %GNUTLS_SCOMMIT_FLAG_ALLOW_BROKEN.
*
- * This function will store the provided hash commitment to
+ * This function will store the provided hash commitment to
* the list of stored public keys. The key with the given
* hash will be considered valid until the provided expiration time.
*
- * The @store variable if non-null specifies a custom backend for
+ * The @tdb variable if non-null specifies a custom backend for
* the storage of entries. If it is NULL then the
* default file backend will be used.
*
@@ -604,12 +638,10 @@ gnutls_store_commitment(const char *db_name,
_gnutls_debug_log("Configuration file: %s\n", db_name);
- tdb->cstore(db_name, host, service, expiration,
+ tdb->cstore(db_name, host, service, expiration,
(gnutls_digest_algorithm_t)me->id, hash);
- ret = 0;
-
- return ret;
+ return 0;
}
#define CONFIG_FILE "known_hosts"
diff --git a/lib/x509.h b/lib/x509.h
index 859824056a..67eb957d78 100644
--- a/lib/x509.h
+++ b/lib/x509.h
@@ -21,7 +21,7 @@
*/
#include <libtasn1.h>
-#include <gnutls/abstract.h>
+
int _gnutls_x509_cert_verify_peers(gnutls_session_t session,
gnutls_typed_vdata_st * data,
@@ -35,6 +35,7 @@ int _gnutls_x509_cert_verify_peers(gnutls_session_t session,
#define PEM_CRL_SEP "-----BEGIN X509 CRL"
+
int _gnutls_x509_raw_privkey_to_gkey(gnutls_privkey_t * privkey,
const gnutls_datum_t * raw_key,
gnutls_x509_crt_fmt_t type);
diff --git a/lib/x509/common.c b/lib/x509/common.c
index 060c2aede1..9ce4275229 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -1653,7 +1653,7 @@ int x509_crt_to_raw_pubkey(gnutls_x509_crt_t crt,
}
/* Converts an X.509 certificate to subjectPublicKeyInfo */
-int x509_raw_crt_to_raw_pubkey(const gnutls_datum_t * cert,
+int _gnutls_x509_raw_crt_to_raw_pubkey(const gnutls_datum_t * cert,
gnutls_datum_t * rpubkey)
{
gnutls_x509_crt_t crt = NULL;
diff --git a/lib/x509/common.h b/lib/x509/common.h
index 2ff979380f..878da42045 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -260,7 +260,7 @@ int _gnutls_copy_string(gnutls_datum_t* str, uint8_t *out, size_t *out_size);
int _gnutls_copy_data(gnutls_datum_t* str, uint8_t *out, size_t *out_size);
int _gnutls_x509_decode_ext(const gnutls_datum_t *der, gnutls_x509_ext_st *out);
-int x509_raw_crt_to_raw_pubkey(const gnutls_datum_t * cert,
+int _gnutls_x509_raw_crt_to_raw_pubkey(const gnutls_datum_t * cert,
gnutls_datum_t * rpubkey);
int x509_crt_to_raw_pubkey(gnutls_x509_crt_t crt,
diff --git a/m4/hooks.m4 b/m4/hooks.m4
index 86b4b2a0e5..2762da6d55 100644
--- a/m4/hooks.m4
+++ b/m4/hooks.m4
@@ -71,13 +71,13 @@ AC_DEFUN([LIBGNUTLS_HOOKS],
NETTLE_MINIMUM=3.4.1
PKG_CHECK_MODULES(NETTLE, [nettle >= $NETTLE_MINIMUM], [cryptolib="nettle"], [
AC_MSG_ERROR([[
- ***
+ ***
*** Libnettle $NETTLE_MINIMUM was not found.
]])
])
PKG_CHECK_MODULES(HOGWEED, [hogweed >= $NETTLE_MINIMUM ], [], [
AC_MSG_ERROR([[
- ***
+ ***
*** Libhogweed (nettle's companion library) $NETTLE_MINIMUM was not found. Note that you must compile nettle with gmp support.
]])
])
@@ -116,7 +116,7 @@ LIBTASN1_MINIMUM=4.9
PKG_CHECK_MODULES(LIBTASN1, [libtasn1 >= $LIBTASN1_MINIMUM], [], [included_libtasn1=yes])
if test "$included_libtasn1" = yes; then
AC_MSG_ERROR([[
- ***
+ ***
*** Libtasn1 $LIBTASN1_MINIMUM was not found. To use the included one, use --with-included-libtasn1
]])
fi
@@ -132,7 +132,7 @@ LIBTASN1_MINIMUM=4.9
AC_MSG_CHECKING([whether C99 macros are supported])
AC_TRY_COMPILE(,
[
- #define test_mac(...)
+ #define test_mac(...)
int z,y,x;
test_mac(x,y,z);
return 0;
@@ -246,7 +246,7 @@ LIBTASN1_MINIMUM=4.9
AC_MSG_RESULT(yes)
fi
AM_CONDITIONAL(ENABLE_SRP, test "$ac_enable_srp" != "no")
-
+
ac_enable_psk=yes
AC_MSG_CHECKING([whether to disable PSK authentication support])
AC_ARG_ENABLE(psk-authentication,
@@ -261,7 +261,7 @@ LIBTASN1_MINIMUM=4.9
AC_MSG_RESULT(yes)
fi
AM_CONDITIONAL(ENABLE_PSK, test "$ac_enable_psk" != "no")
-
+
ac_enable_anon=yes
AC_MSG_CHECKING([whether to disable anonymous authentication support])
AC_ARG_ENABLE(anon-authentication,
diff --git a/src/tests.c b/src/tests.c
index ffa772553a..682ce41504 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -117,6 +117,7 @@ char prio_str[512] = "";
#define BLOCK_CIPHERS "+3DES-CBC:+AES-128-CBC:+CAMELLIA-128-CBC:+AES-256-CBC:+CAMELLIA-256-CBC"
#define ALL_COMP "+COMP-NULL"
#define ALL_MACS "+MAC-ALL:+MD5:+SHA1"
+#define ALL_CERTTYPES "+CTYPE-X509:+CTYPE-RAWPK"
#define ALL_KX "+RSA:+DHE-RSA:+DHE-DSS:+ANON-DH:+ECDHE-RSA:+ECDHE-ECDSA:+ANON-ECDH"
#define INIT_STR "NONE:"
char rest[128] = "%UNSAFE_RENEGOTIATION:+SIGN-ALL:+GROUP-ALL";
diff --git a/symbols.last b/symbols.last
index 7b547b7117..e5f0e01c69 100644
--- a/symbols.last
+++ b/symbols.last
@@ -4,6 +4,7 @@ GNUTLS_3_6_2@GNUTLS_3_6_2
GNUTLS_3_6_3@GNUTLS_3_6_3
GNUTLS_3_6_4@GNUTLS_3_6_4
GNUTLS_3_6_5@GNUTLS_3_6_5
+GNUTLS_3_6_6@GNUTLS_3_6_6
_gnutls_global_init_skip@GNUTLS_3_4
gnutls_aead_cipher_decrypt@GNUTLS_3_4
gnutls_aead_cipher_deinit@GNUTLS_3_4
@@ -80,6 +81,8 @@ gnutls_certificate_set_openpgp_keyring_file@GNUTLS_3_4
gnutls_certificate_set_openpgp_keyring_mem@GNUTLS_3_4
gnutls_certificate_set_params_function@GNUTLS_3_4
gnutls_certificate_set_pin_function@GNUTLS_3_4
+gnutls_certificate_set_rawpk_key_file@GNUTLS_3_6_6
+gnutls_certificate_set_rawpk_key_mem@GNUTLS_3_6_6
gnutls_certificate_set_retrieve_function2@GNUTLS_3_4
gnutls_certificate_set_retrieve_function3@GNUTLS_3_6_3
gnutls_certificate_set_retrieve_function@GNUTLS_3_4
@@ -415,6 +418,8 @@ gnutls_pcert_export_openpgp@GNUTLS_3_4
gnutls_pcert_export_x509@GNUTLS_3_4
gnutls_pcert_import_openpgp@GNUTLS_3_4
gnutls_pcert_import_openpgp_raw@GNUTLS_3_4
+gnutls_pcert_import_rawpk@GNUTLS_3_6_6
+gnutls_pcert_import_rawpk_raw@GNUTLS_3_6_6
gnutls_pcert_import_x509@GNUTLS_3_4
gnutls_pcert_import_x509_list@GNUTLS_3_4
gnutls_pcert_import_x509_raw@GNUTLS_3_4
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 45192203e1..7bc98df743 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -37,6 +37,7 @@ EXTRA_DIST = suppressions.valgrind eagain-common.h cert-common.h test-chains.h \
certs/cert-rsa-2432.pem certs/ecc384.pem certs/ecc.pem hex.h \
certs/ca-ecc.pem certs/cert-ecc384.pem certs/cert-ecc.pem certs/ecc256.pem \
certs/ecc521.pem certs/rsa-2432.pem x509cert-dir/ca.pem psk.passwd \
+ certs/rawpk_priv.pem certs/rawpk_pub.pem \
certs/ed25519.pem certs/cert-ed25519.pem \
system.prio pkcs11/softhsm.h pkcs11/pkcs11-pubkey-import.c gnutls-asan.supp \
rsa-md5-collision/README safe-renegotiation/README starttls-smtp.txt starttls-ftp.txt \
@@ -207,7 +208,7 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei
dss-sig-val sign-pk-api tls-session-ext-override record-pad \
tls13-server-kx-neg gnutls_ext_raw_parse_dtls key-export-pkcs8 \
null_retrieve_function tls-record-size-limit tls-crt_type-neg \
- resume-with-stek-expiration resume-with-previous-stek
+ resume-with-stek-expiration resume-with-previous-stek rawpk-api
if HAVE_SECCOMP_TESTS
ctests += dtls-with-seccomp tls-with-seccomp dtls-client-with-seccomp tls-client-with-seccomp
diff --git a/tests/cert-common.h b/tests/cert-common.h
index dcae0104e5..80cdffd776 100644
--- a/tests/cert-common.h
+++ b/tests/cert-common.h
@@ -1783,3 +1783,131 @@ const gnutls_datum_t server_ca3_pkcs12 = { (unsigned char*)server_ca3_pkcs12_pem
sizeof(server_ca3_pkcs12_pem)-1
};
+/* Raw public-key key material for testing */
+static char rawpk_public_key_pem1[] =
+ "-----BEGIN PUBLIC KEY-----\n"
+ "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAyAeBq7Ti7oVExeVT1PqH\n"
+ "GBXzC+johdeVnZgZRLhDTIaIGODV5F5JhE4NNb1O/DYLlAy5IIO8tfAE2KIxlarN\n"
+ "H/+AcfV6ZJQSG4SSmhoIGzfdcdjuBmFfdfhO+z/cgqiewh53/fFCQlaJweHhpmim\n"
+ "/LVL/M/1Rd6Urskv/5jXGG4FVUNfhXKQag0uzWsqcztCPX7Lrqr2BSOmkA1nWzdo\n"
+ "h5oBuxdooaH9/kwphqJAp03LwtaSStX/yz6Mh+ZqEbBuM4mWw/xKzbEbs7zA+d8s\n"
+ "ryHXkC8nsdA+h+IRd8bPa/KuWQNfjxXKNPzgmsZddHmHtYtWvAcoIMvtyO23Y2Nh\n"
+ "N4V0/7fwFLbZtfUBg4pqUl2ktkdwsNguTT1qzJCsYhsHXaqqvHy+5HR2D0w07y2X\n"
+ "1qCVmfHzBZCM5OhxoeoauE+xu+5nvYrgsgPE0y5Nty0y2MrApg3digaiKUXrI+mE\n"
+ "VKn9vsQeaVvw9D6PgNQM99HkbGhRMGPOzcHjS/ZeLd1zAgMBAAE=\n"
+ "-----END PUBLIC KEY-----";
+
+const gnutls_datum_t rawpk_public_key1 = {
+ (unsigned char*)rawpk_public_key_pem1,
+ sizeof(rawpk_public_key_pem1) - 1
+};
+
+static char rawpk_private_key_pem1[] =
+ "-----BEGIN RSA PRIVATE KEY-----\n"
+ "MIIG4wIBAAKCAYEAyAeBq7Ti7oVExeVT1PqHGBXzC+johdeVnZgZRLhDTIaIGODV\n"
+ "5F5JhE4NNb1O/DYLlAy5IIO8tfAE2KIxlarNH/+AcfV6ZJQSG4SSmhoIGzfdcdju\n"
+ "BmFfdfhO+z/cgqiewh53/fFCQlaJweHhpmim/LVL/M/1Rd6Urskv/5jXGG4FVUNf\n"
+ "hXKQag0uzWsqcztCPX7Lrqr2BSOmkA1nWzdoh5oBuxdooaH9/kwphqJAp03LwtaS\n"
+ "StX/yz6Mh+ZqEbBuM4mWw/xKzbEbs7zA+d8sryHXkC8nsdA+h+IRd8bPa/KuWQNf\n"
+ "jxXKNPzgmsZddHmHtYtWvAcoIMvtyO23Y2NhN4V0/7fwFLbZtfUBg4pqUl2ktkdw\n"
+ "sNguTT1qzJCsYhsHXaqqvHy+5HR2D0w07y2X1qCVmfHzBZCM5OhxoeoauE+xu+5n\n"
+ "vYrgsgPE0y5Nty0y2MrApg3digaiKUXrI+mEVKn9vsQeaVvw9D6PgNQM99HkbGhR\n"
+ "MGPOzcHjS/ZeLd1zAgMBAAECggGBALHiAw3Yscqd11gJpbCMDqF7u4VG3alQ26un\n"
+ "PClhl++w380H/Q62TriK1LKKpHgj8834NpXUsXg2d4jTTDcmCn6/L9GoFOzmxOeV\n"
+ "0O2b4sOZvaNl397qrwLxDAPhec7z9yL4B4tcBqmJ3b3+izX6cS3gaC/uG9fDpgN9\n"
+ "xOKPYBFInhOB86twAz9cc9eXysto0nJvlODDBj/xwUjvso9qydl1Or7PhWvf7Ek+\n"
+ "H9ur5MUjqOWe/b/xaSWsfTrJzF/ovbRnGbXLIpozIx609TZS4wYSqU5FUjkL0zTB\n"
+ "bTdb3jgFm/5SHnnThD67zbZavCxiN9wiTs3zeGlxYf8hMeaTkOYiAOR4/1bOTe2J\n"
+ "ttRA1EcY+i6H0+JOtLkqwj5ka0m3lrH2KD3E/mHs1yfERQx7VVjw9IpeAKmi5lzQ\n"
+ "v1lhIXiv75Mb0NMsCknGYPLHCyOY5aA2dhR8Wnr67gOYu3ssexLzMKczk5OTzl5c\n"
+ "PRHJRXDpJqgOYWujF99uCYhnxonO4QKBwQDUQB0s4shWTyOylq7j4rCSbHf2zHDf\n"
+ "HBYC75wyjQECNQXNk6hp5jJz2BC0XvnO7PYSRXaVauMc/S3V7V7GMsry3uugfwLy\n"
+ "XNnyRVY4voe5SNt/WAArybNsPNPEIPzgkZmeWvcpoY8ESufPfVW54BvGHt3YjPjI\n"
+ "gYmFUkpPRUWXfji91NpTlIrsP6jtBTYXGV4kVm+TawP06a6FdCjJQaI7Nm2dwUiX\n"
+ "Cmf4oFSo8mGxi0wimX+BiLJep2bYnUF2gqMCgcEA8UKESDX3jBpyz59vpSjmfpw1\n"
+ "AnlEfR6s83W92m0HfEYLulfxq9xA2zaQjy4GbaKVRfLrO2Pj3bZWs89RGXTQVGgq\n"
+ "ztCLIRsL+M1SQ883e8yx4jwFaqIM+pPpvAjOOOTdpgY33h7w20tgrbzVKeOl1ghC\n"
+ "IZ+K8C/tIGZXI5/TYppl7csIOoYRtzuRpyDE0tmwy658RfyxzEtfLxJoaLiFXOE0\n"
+ "zFFrEvT/jto4jN+cwsdnHhxrY9+bVNUNyb9ZH7bxAoHARvcIyjEo+nKLZPKsltT8\n"
+ "ZHiPw5ynQHGLin/CocQzSiGgRxPPg1jMFZ9wNl5q95ySyZkgBOUv+klMQfKTdYEW\n"
+ "Cg4uigLtYUtaM36rTV2m03RgrzslE37k1pOf2juNUShdTGztpqW1w6Gnz+AAAZ3E\n"
+ "q4E2e2jm5WMqL8FLxyVKF1TEc/Pu63MG3+aI/HZ5l0+MAmpD8+4b7I8VItmrqV6g\n"
+ "d1vDWrN9KcL48E/q/nHL6CjC0+6uiwjBWpRt9o7djFoxAoHAJzK/e1wJVGIXtVQa\n"
+ "N6Nlj7yhgD1ju1B4mTXQGuUMCkz3KtePFHU8tGExK5I2ySlZR3wobAXWx/cQLzbH\n"
+ "3nL0RkKGcgPAFyjl0Q7LBulsAllHrZJC7whVQ4E0wLBNkUDeIlNwUE6Go5qjopbD\n"
+ "q4KpNxUwaXYahNvEkzcNgWQ+XA7p8LDELX4K8tJi39ybHgbwiqdW2ags2xyD4ooD\n"
+ "HMCeKnEMuwWfd/0GaJdcCMdsGNl9D49eg2OZQTc8fkLwoA6BAoHATQdk3VZwGGn/\n"
+ "93p9vu189alkshTmir+SOo/ufH5U+j7t8cPeT7psuYAPZWS+Z6KEzvHxj54pAvcp\n"
+ "mlAngD3+AfHDn/VAtYv5HVcpZ+K2K0X4v8N5HGIubgaebs2oVNz+RAWnd8K2drDG\n"
+ "NcJV3C+zLziTCwvpGCIy3T/lHjKe+YczjGfhg2e6PgfwhTqPAjuhUZ8wScYo7l7V\n"
+ "zAhlSL0665IXJ32zX+3LyQFDbkB6pbKy5TU+rX3DmDyj3MSbc3kR\n"
+ "-----END RSA PRIVATE KEY-----\n";
+
+const gnutls_datum_t rawpk_private_key1 = {
+ (unsigned char*)rawpk_private_key_pem1,
+ sizeof(rawpk_private_key_pem1) - 1
+};
+
+const char rawpk_public_key_pem2[] =
+ "-----BEGIN PUBLIC KEY-----\n"
+ "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA0tQAiQ13zWGZMV9YxFo2\n"
+ "H15yERrkr8KD7z6QheVeatc2+5X0m5/+/o95nmnt6Mlwa27U78QwkHBccOaNkSi7\n"
+ "HGMopaxatEsF/S30MDmhqOi9R2VtMwDaa2zWH/s2wPHn8efn2/zG0jeXCzNsXFs4\n"
+ "zNApaZmTJCHaDRUE12adwP5i6GvUb978f27Cm0gnkSWBH9OdVnMunQkm/L16NI3E\n"
+ "lvcDEEJbqhX2eswHenbhw//LiR1EKRtHEjWywAq5AeHeYNH+2zjff59SGD6Bn+W2\n"
+ "vPKBhSWCyFDPGRfcYeCX2LFM7+Xx0j+GLzBnkjBhEgdsdLJ7Bt8aDToUJScLxeeP\n"
+ "oOmL9e0bec20debwF0G/7QMlwRgDjV3sd3u+5RxRCeOh8Xqfbs/tij7tnU93orhc\n"
+ "MzGjcn5XZ6WicyimuTruNznhKhNp6vmizCpwQAroimaZGV7F/8nvHInTZfpNH/+b\n"
+ "++gYbddkH+MouxOXcAEUku6vN0JzDgA4qj4Tw7dffXSDAgMBAAE=\n"
+ "-----END PUBLIC KEY-----\n";
+
+const gnutls_datum_t rawpk_public_key2 = {
+ (unsigned char*)rawpk_public_key_pem2,
+ sizeof(rawpk_public_key_pem2) - 1
+};
+
+const char rawpk_private_key_pem2[] =
+ "-----BEGIN RSA PRIVATE KEY-----\n"
+ "MIIG4wIBAAKCAYEA0tQAiQ13zWGZMV9YxFo2H15yERrkr8KD7z6QheVeatc2+5X0\n"
+ "m5/+/o95nmnt6Mlwa27U78QwkHBccOaNkSi7HGMopaxatEsF/S30MDmhqOi9R2Vt\n"
+ "MwDaa2zWH/s2wPHn8efn2/zG0jeXCzNsXFs4zNApaZmTJCHaDRUE12adwP5i6GvU\n"
+ "b978f27Cm0gnkSWBH9OdVnMunQkm/L16NI3ElvcDEEJbqhX2eswHenbhw//LiR1E\n"
+ "KRtHEjWywAq5AeHeYNH+2zjff59SGD6Bn+W2vPKBhSWCyFDPGRfcYeCX2LFM7+Xx\n"
+ "0j+GLzBnkjBhEgdsdLJ7Bt8aDToUJScLxeePoOmL9e0bec20debwF0G/7QMlwRgD\n"
+ "jV3sd3u+5RxRCeOh8Xqfbs/tij7tnU93orhcMzGjcn5XZ6WicyimuTruNznhKhNp\n"
+ "6vmizCpwQAroimaZGV7F/8nvHInTZfpNH/+b++gYbddkH+MouxOXcAEUku6vN0Jz\n"
+ "DgA4qj4Tw7dffXSDAgMBAAECggGAVD3oFNtv0n48I1FQ++x8Ed7AP3t6g4x7AX8D\n"
+ "aq0zJAfo7XCG9CRjVL5pv1XefZT4OcVoioHfUefD2E0XpjgbRAWPOVv8Rmxv8TGK\n"
+ "kDaHFSIid8PcdXPS0vgDO3Y686/1mWCr8eg4XclerlgW5XSB5r0KvyphdB+erHmI\n"
+ "nLVhNbuwM+TaVvVH+Xd9hWS4grP0u43oIaIWryL4FCd2DEfVlOkQrU+GpxjtizW5\n"
+ "i0KzhYjRgHFUSgSfSnRwf3IJaOoiIpOma2p7R4dVoQkVGS6bStqPcqSUGVxH2CLu\n"
+ "TC7B0xZZs2xq6pLVWYXh/J79Ziw76+7qeMwFatzsUPtB6smQvR7016BThY6Cj+ui\n"
+ "KgTCZGpbb30MCn9/px8P2jXagA9fnPzf31WkdbsnjrYPNe6kkP5snJtz6k3cYex2\n"
+ "P8WulCS23qjCdVoUcoSDzPiaFtnPR/HcZDpTYuxKuUMoQrqsmRHeF/QRvbXkKFQC\n"
+ "Kudpfna5CAIT5IaIWwXQp0NfpnNBAoHBAPcnqz2uZaVZO7LiZEMc3cDfiPTp2vhf\n"
+ "VRYNyvTZIYgAox8k49waEQq6MyD5N2oWyRjWsQ0ta/BqJgMLoG42oyDntp/HGhZC\n"
+ "SxLQEu4ursFsCE32I4nyt7DD5erzX+H6folRq2BelL6ISwdr1g1wJZ3cCrwGbG/P\n"
+ "7MUYtSo026K9iXCqv9t7Q3TYe7yECVrxqbOu++C2df8IodehUm5wQZTsysBDfCHZ\n"
+ "PT9m4Qfaryq/u4N5w8nCt/Ep3JkjqyJL4wKBwQDaX4WbwL6ipyt6k4NZ6dEe0aLT\n"
+ "yKowO0rAWckr6WbA6kFBV2JWPswdV7gCqSOaae+UVc6cpw07jc39vsFNFGDL6OfC\n"
+ "HvmjQ2HQ/Mf4RjNTSt1rYpiB7DTqtLCys454OHFxo0UinXUc20+timroLEJbZJ23\n"
+ "upgAvico9zgCyjiwHoEVCpwZerLcLJk44mSGANiBLMo6YfyWj+PfLOeXu5rs4vhC\n"
+ "K0JBPdIzXHKwv996qFpy8xBatfO/+CH2NR/D1uECgcB8mATdbWNUfa14umQs6Qpp\n"
+ "Rsb2IEYA2547Jezgje03cIrLEn/D32gj7kYEI15qHt51pRVQPUuiwQA0nNHdfbGy\n"
+ "ztzjoy1ldzn9W+OPKv1yCJIPKzwzOKadd8QaM2Jsuyi69O7eABAgFPkt3pDj6Vst\n"
+ "P1Yx/1L+8uS7X39ErazjV4VHxOw/Kt6Qsul92VoV/Km+KUJUv+awEJv15h92CSUm\n"
+ "fFChp+OV9LvJkIV0vit783gGCYZH2d98tcu9b5vACF0CgcAZM0rM5ZpaVOZcl+dh\n"
+ "me0LHHAo9pBFTqJavkHL8nxsKNxs+POdNlQB0tymWfSE3lLKkHhudYy+Yafy72+J\n"
+ "QJ/HCFKugTqXz6/bGUDOcvN7WjlhKhilbafRqhZ2GOiJESJuVcQlsXwRX3G7eizK\n"
+ "LElgGKVmzX67HzaPsK/jCokuMeb9kaLgAdvgMrlf6ihlmnVhutR/lk065tIKMDlt\n"
+ "tjWzvqGdqTZVJxg52yJVKV9V3VXKzCgH/9VoQu9QZWMMC6ECgcEAu2lYMEfbrTYS\n"
+ "u2ukovL69EnxUfQ76f8/cs3gVsOWRxPN6MFe8pR7lC03orHckGdwVF0uUSbek4F7\n"
+ "vmZxewPQvVWntGfyL3uhln+xyJbfd/a4YThTDzXIy++jdrKGCVPc9Z+XPWJyc5qM\n"
+ "fA7FxB9uBfVyHKa3LIsuvyFtSKF38pEVMrL4kTnB++Eg536AOZbYB351dMi0qXzN\n"
+ "Ljyi36ud0J5l00OZAanLPw7dklZOTYNguCDRhi6k7qpayV7ywLSB\n"
+ "-----END RSA PRIVATE KEY-----\n";
+
+const gnutls_datum_t rawpk_private_key2 = {
+ (unsigned char*)rawpk_private_key_pem2,
+ sizeof(rawpk_private_key_pem2) - 1
+};
diff --git a/tests/certs/rawpk_priv.pem b/tests/certs/rawpk_priv.pem
new file mode 100644
index 0000000000..4329cb0870
--- /dev/null
+++ b/tests/certs/rawpk_priv.pem
@@ -0,0 +1,39 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIG4wIBAAKCAYEAyAeBq7Ti7oVExeVT1PqHGBXzC+johdeVnZgZRLhDTIaIGODV
+5F5JhE4NNb1O/DYLlAy5IIO8tfAE2KIxlarNH/+AcfV6ZJQSG4SSmhoIGzfdcdju
+BmFfdfhO+z/cgqiewh53/fFCQlaJweHhpmim/LVL/M/1Rd6Urskv/5jXGG4FVUNf
+hXKQag0uzWsqcztCPX7Lrqr2BSOmkA1nWzdoh5oBuxdooaH9/kwphqJAp03LwtaS
+StX/yz6Mh+ZqEbBuM4mWw/xKzbEbs7zA+d8sryHXkC8nsdA+h+IRd8bPa/KuWQNf
+jxXKNPzgmsZddHmHtYtWvAcoIMvtyO23Y2NhN4V0/7fwFLbZtfUBg4pqUl2ktkdw
+sNguTT1qzJCsYhsHXaqqvHy+5HR2D0w07y2X1qCVmfHzBZCM5OhxoeoauE+xu+5n
+vYrgsgPE0y5Nty0y2MrApg3digaiKUXrI+mEVKn9vsQeaVvw9D6PgNQM99HkbGhR
+MGPOzcHjS/ZeLd1zAgMBAAECggGBALHiAw3Yscqd11gJpbCMDqF7u4VG3alQ26un
+PClhl++w380H/Q62TriK1LKKpHgj8834NpXUsXg2d4jTTDcmCn6/L9GoFOzmxOeV
+0O2b4sOZvaNl397qrwLxDAPhec7z9yL4B4tcBqmJ3b3+izX6cS3gaC/uG9fDpgN9
+xOKPYBFInhOB86twAz9cc9eXysto0nJvlODDBj/xwUjvso9qydl1Or7PhWvf7Ek+
+H9ur5MUjqOWe/b/xaSWsfTrJzF/ovbRnGbXLIpozIx609TZS4wYSqU5FUjkL0zTB
+bTdb3jgFm/5SHnnThD67zbZavCxiN9wiTs3zeGlxYf8hMeaTkOYiAOR4/1bOTe2J
+ttRA1EcY+i6H0+JOtLkqwj5ka0m3lrH2KD3E/mHs1yfERQx7VVjw9IpeAKmi5lzQ
+v1lhIXiv75Mb0NMsCknGYPLHCyOY5aA2dhR8Wnr67gOYu3ssexLzMKczk5OTzl5c
+PRHJRXDpJqgOYWujF99uCYhnxonO4QKBwQDUQB0s4shWTyOylq7j4rCSbHf2zHDf
+HBYC75wyjQECNQXNk6hp5jJz2BC0XvnO7PYSRXaVauMc/S3V7V7GMsry3uugfwLy
+XNnyRVY4voe5SNt/WAArybNsPNPEIPzgkZmeWvcpoY8ESufPfVW54BvGHt3YjPjI
+gYmFUkpPRUWXfji91NpTlIrsP6jtBTYXGV4kVm+TawP06a6FdCjJQaI7Nm2dwUiX
+Cmf4oFSo8mGxi0wimX+BiLJep2bYnUF2gqMCgcEA8UKESDX3jBpyz59vpSjmfpw1
+AnlEfR6s83W92m0HfEYLulfxq9xA2zaQjy4GbaKVRfLrO2Pj3bZWs89RGXTQVGgq
+ztCLIRsL+M1SQ883e8yx4jwFaqIM+pPpvAjOOOTdpgY33h7w20tgrbzVKeOl1ghC
+IZ+K8C/tIGZXI5/TYppl7csIOoYRtzuRpyDE0tmwy658RfyxzEtfLxJoaLiFXOE0
+zFFrEvT/jto4jN+cwsdnHhxrY9+bVNUNyb9ZH7bxAoHARvcIyjEo+nKLZPKsltT8
+ZHiPw5ynQHGLin/CocQzSiGgRxPPg1jMFZ9wNl5q95ySyZkgBOUv+klMQfKTdYEW
+Cg4uigLtYUtaM36rTV2m03RgrzslE37k1pOf2juNUShdTGztpqW1w6Gnz+AAAZ3E
+q4E2e2jm5WMqL8FLxyVKF1TEc/Pu63MG3+aI/HZ5l0+MAmpD8+4b7I8VItmrqV6g
+d1vDWrN9KcL48E/q/nHL6CjC0+6uiwjBWpRt9o7djFoxAoHAJzK/e1wJVGIXtVQa
+N6Nlj7yhgD1ju1B4mTXQGuUMCkz3KtePFHU8tGExK5I2ySlZR3wobAXWx/cQLzbH
+3nL0RkKGcgPAFyjl0Q7LBulsAllHrZJC7whVQ4E0wLBNkUDeIlNwUE6Go5qjopbD
+q4KpNxUwaXYahNvEkzcNgWQ+XA7p8LDELX4K8tJi39ybHgbwiqdW2ags2xyD4ooD
+HMCeKnEMuwWfd/0GaJdcCMdsGNl9D49eg2OZQTc8fkLwoA6BAoHATQdk3VZwGGn/
+93p9vu189alkshTmir+SOo/ufH5U+j7t8cPeT7psuYAPZWS+Z6KEzvHxj54pAvcp
+mlAngD3+AfHDn/VAtYv5HVcpZ+K2K0X4v8N5HGIubgaebs2oVNz+RAWnd8K2drDG
+NcJV3C+zLziTCwvpGCIy3T/lHjKe+YczjGfhg2e6PgfwhTqPAjuhUZ8wScYo7l7V
+zAhlSL0665IXJ32zX+3LyQFDbkB6pbKy5TU+rX3DmDyj3MSbc3kR
+-----END RSA PRIVATE KEY-----
diff --git a/tests/certs/rawpk_pub.pem b/tests/certs/rawpk_pub.pem
new file mode 100644
index 0000000000..fad8af8e0f
--- /dev/null
+++ b/tests/certs/rawpk_pub.pem
@@ -0,0 +1,11 @@
+-----BEGIN PUBLIC KEY-----
+MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAyAeBq7Ti7oVExeVT1PqH
+GBXzC+johdeVnZgZRLhDTIaIGODV5F5JhE4NNb1O/DYLlAy5IIO8tfAE2KIxlarN
+H/+AcfV6ZJQSG4SSmhoIGzfdcdjuBmFfdfhO+z/cgqiewh53/fFCQlaJweHhpmim
+/LVL/M/1Rd6Urskv/5jXGG4FVUNfhXKQag0uzWsqcztCPX7Lrqr2BSOmkA1nWzdo
+h5oBuxdooaH9/kwphqJAp03LwtaSStX/yz6Mh+ZqEbBuM4mWw/xKzbEbs7zA+d8s
+ryHXkC8nsdA+h+IRd8bPa/KuWQNfjxXKNPzgmsZddHmHtYtWvAcoIMvtyO23Y2Nh
+N4V0/7fwFLbZtfUBg4pqUl2ktkdwsNguTT1qzJCsYhsHXaqqvHy+5HR2D0w07y2X
+1qCVmfHzBZCM5OhxoeoauE+xu+5nvYrgsgPE0y5Nty0y2MrApg3digaiKUXrI+mE
+VKn9vsQeaVvw9D6PgNQM99HkbGhRMGPOzcHjS/ZeLd1zAgMBAAE=
+-----END PUBLIC KEY-----
diff --git a/tests/common-cert-key-exchange.c b/tests/common-cert-key-exchange.c
index 9d8fbb217b..468475f846 100644
--- a/tests/common-cert-key-exchange.c
+++ b/tests/common-cert-key-exchange.c
@@ -145,12 +145,14 @@ void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algori
const gnutls_datum_t *client_cert,
const gnutls_datum_t *client_key,
unsigned cert_flags,
- unsigned exp_group)
+ unsigned exp_group,
+ gnutls_certificate_type_t server_ctype,
+ gnutls_certificate_type_t client_ctype)
{
int ret;
char buffer[256];
/* Server stuff. */
- gnutls_certificate_credentials_t serverx509cred;
+ gnutls_certificate_credentials_t server_cred;
gnutls_anon_server_credentials_t s_anoncred;
gnutls_dh_params_t dh_params;
const gnutls_datum_t p3 =
@@ -158,7 +160,7 @@ void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algori
gnutls_session_t server;
int sret = GNUTLS_E_AGAIN;
/* Client stuff. */
- gnutls_certificate_credentials_t clientx509cred;
+ gnutls_certificate_credentials_t client_cred;
gnutls_anon_client_credentials_t c_anoncred;
gnutls_session_t client;
int cret = GNUTLS_E_AGAIN, version;
@@ -172,23 +174,36 @@ void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algori
reset_buffers();
/* Init server */
gnutls_anon_allocate_server_credentials(&s_anoncred);
- gnutls_certificate_allocate_credentials(&serverx509cred);
+ gnutls_certificate_allocate_credentials(&server_cred);
+
+ // Set server crt creds based on ctype
+ switch (server_ctype) {
+ case GNUTLS_CRT_X509:
+ ret = gnutls_certificate_set_x509_key_mem(server_cred,
+ serv_cert, serv_key,
+ GNUTLS_X509_FMT_PEM);
+ break;
+ case GNUTLS_CRT_RAWPK:
+ ret = gnutls_certificate_set_rawpk_key_mem(server_cred,
+ serv_cert, serv_key, GNUTLS_X509_FMT_PEM, NULL, 0,
+ NULL, 0, 0);
+ break;
+ default:
+ ret = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
+ }
- ret = gnutls_certificate_set_x509_key_mem(serverx509cred,
- serv_cert, serv_key,
- GNUTLS_X509_FMT_PEM);
if (ret < 0) {
fail("Could not set key/cert: %s\n", gnutls_strerror(ret));
}
gnutls_dh_params_init(&dh_params);
gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM);
- gnutls_certificate_set_dh_params(serverx509cred, dh_params);
+ gnutls_certificate_set_dh_params(server_cred, dh_params);
gnutls_anon_set_server_dh_params(s_anoncred, dh_params);
- gnutls_init(&server, GNUTLS_SERVER);
+ gnutls_init(&server, GNUTLS_SERVER | GNUTLS_ENABLE_RAWPK);
gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
- serverx509cred);
+ server_cred);
gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred);
@@ -196,33 +211,45 @@ void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algori
assert(gnutls_priority_set_direct(server, server_priority, NULL) >= 0);
else
assert(gnutls_priority_set_direct(server,
- "NORMAL:+VERS-SSL3.0:+ANON-ECDH:+ANON-DH:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519:+SIGN-EDDSA-ED25519",
+ "NORMAL:+VERS-SSL3.0:+ANON-ECDH:+ANON-DH:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519:+SIGN-EDDSA-ED25519:+CTYPE-ALL",
NULL)>=0);
gnutls_transport_set_push_function(server, server_push);
gnutls_transport_set_pull_function(server, server_pull);
gnutls_transport_set_ptr(server, server);
/* Init client */
-
- ret = gnutls_certificate_allocate_credentials(&clientx509cred);
+ ret = gnutls_certificate_allocate_credentials(&client_cred);
if (ret < 0)
exit(1);
if (cert_flags == USE_CERT) {
- gnutls_certificate_set_x509_key_mem(clientx509cred,
- client_cert, client_key,
- GNUTLS_X509_FMT_PEM);
+ // Set client crt creds based on ctype
+ switch (client_ctype) {
+ case GNUTLS_CRT_X509:
+ gnutls_certificate_set_x509_key_mem(client_cred,
+ client_cert, client_key,
+ GNUTLS_X509_FMT_PEM);
+ break;
+ case GNUTLS_CRT_RAWPK:
+ gnutls_certificate_set_rawpk_key_mem(client_cred,
+ client_cert, client_key, GNUTLS_X509_FMT_PEM, NULL, 0,
+ NULL, 0, 0);
+ break;
+ default:
+ fail("Illegal client certificate type given\n");
+ }
+
gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE);
} else if (cert_flags == ASK_CERT) {
gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);
}
#if 0
- ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
+ ret = gnutls_certificate_set_x509_trust_mem(client_cred, &ca_cert, GNUTLS_X509_FMT_PEM);
if (ret < 0)
exit(1);
#endif
- ret = gnutls_init(&client, GNUTLS_CLIENT);
+ ret = gnutls_init(&client, GNUTLS_CLIENT | GNUTLS_ENABLE_RAWPK);
if (ret < 0)
exit(1);
@@ -230,7 +257,7 @@ void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algori
gnutls_anon_allocate_client_credentials(&c_anoncred);
gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred);
ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
- clientx509cred);
+ client_cred);
if (ret < 0)
exit(1);
@@ -315,8 +342,8 @@ void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algori
gnutls_deinit(client);
gnutls_deinit(server);
- gnutls_certificate_free_credentials(serverx509cred);
- gnutls_certificate_free_credentials(clientx509cred);
+ gnutls_certificate_free_credentials(server_cred);
+ gnutls_certificate_free_credentials(client_cred);
gnutls_anon_free_server_credentials(s_anoncred);
gnutls_anon_free_client_credentials(c_anoncred);
gnutls_dh_params_deinit(dh_params);
@@ -423,7 +450,7 @@ void dtls_try_with_key_mtu(const char *name, const char *client_prio, gnutls_kx_
gnutls_transport_set_push_function(client, client_push);
gnutls_transport_set_pull_function(client, client_pull);
gnutls_transport_set_pull_timeout_function(client, client_pull_timeout_func);
-
+
gnutls_transport_set_ptr(client, client);
if (smtu)
gnutls_dtls_set_mtu (client, smtu);
diff --git a/tests/common-cert-key-exchange.h b/tests/common-cert-key-exchange.h
index b52c95ea72..8fb5ab754e 100644
--- a/tests/common-cert-key-exchange.h
+++ b/tests/common-cert-key-exchange.h
@@ -31,17 +31,26 @@
extern const char *server_priority;
-#define try(name, client_prio, client_kx, server_sign_algo, client_sign_algo) \
+#define try_x509(name, client_prio, client_kx, server_sign_algo, client_sign_algo) \
try_with_key(name, client_prio, client_kx, server_sign_algo, client_sign_algo, \
- &server_ca3_localhost_cert, &server_ca3_key, NULL, NULL, 0)
+ &server_ca3_localhost_cert, &server_ca3_key, NULL, NULL, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN)
+
+#define try_rawpk(name, client_prio, client_kx, server_sign_algo, client_sign_algo) \
+ try_with_key(name, client_prio, client_kx, server_sign_algo, client_sign_algo, \
+ &rawpk_public_key1, &rawpk_private_key1, NULL, NULL, 0, GNUTLS_CRT_RAWPK, GNUTLS_CRT_UNKNOWN)
-#define try_ks(name, client_prio, client_kx, group) \
+#define try_x509_ks(name, client_prio, client_kx, group) \
try_with_key_ks(name, client_prio, client_kx, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN, \
- &server_ca3_localhost_cert, &server_ca3_key, NULL, NULL, 0, group)
+ &server_ca3_localhost_cert, &server_ca3_key, NULL, NULL, 0, group, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN)
-#define try_cli(name, client_prio, client_kx, server_sign_algo, client_sign_algo, client_cert) \
+#define try_x509_cli(name, client_prio, client_kx, server_sign_algo, client_sign_algo, client_cert) \
try_with_key(name, client_prio, client_kx, server_sign_algo, client_sign_algo, \
- &server_ca3_localhost_cert, &server_ca3_key, &cli_ca3_cert, &cli_ca3_key, client_cert)
+ &server_ca3_localhost_cert, &server_ca3_key, &cli_ca3_cert, &cli_ca3_key, client_cert, GNUTLS_CRT_X509, GNUTLS_CRT_X509)
+
+#define try_rawpk_cli(name, client_prio, client_kx, server_sign_algo, client_sign_algo, client_cert) \
+ try_with_key(name, client_prio, client_kx, server_sign_algo, client_sign_algo, \
+ &rawpk_public_key1, &rawpk_private_key1, &rawpk_public_key2, &rawpk_private_key2, client_cert, GNUTLS_CRT_RAWPK, GNUTLS_CRT_RAWPK)
+
void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algorithm_t client_kx,
gnutls_sign_algorithm_t server_sign_algo,
@@ -51,7 +60,9 @@ void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algori
const gnutls_datum_t *cli_cert,
const gnutls_datum_t *cli_key,
unsigned client_cert,
- unsigned exp_group);
+ unsigned exp_group,
+ gnutls_certificate_type_t server_ctype,
+ gnutls_certificate_type_t client_ctype);
inline static
void try_with_key(const char *name, const char *client_prio, gnutls_kx_algorithm_t client_kx,
@@ -61,10 +72,12 @@ void try_with_key(const char *name, const char *client_prio, gnutls_kx_algorithm
const gnutls_datum_t *serv_key,
const gnutls_datum_t *cli_cert,
const gnutls_datum_t *cli_key,
- unsigned client_cert)
+ unsigned client_cert,
+ gnutls_certificate_type_t server_ctype,
+ gnutls_certificate_type_t client_ctype)
{
return try_with_key_ks(name, client_prio, client_kx, server_sign_algo, client_sign_algo,
- serv_cert, serv_key, cli_cert, cli_key, client_cert, 0);
+ serv_cert, serv_key, cli_cert, cli_key, client_cert, 0, server_ctype, client_ctype);
}
void try_with_key_fail(const char *name, const char *client_prio,
diff --git a/tests/crt_type-neg-common.c b/tests/crt_type-neg-common.c
index ac99e20984..d6a91d22a3 100644
--- a/tests/crt_type-neg-common.c
+++ b/tests/crt_type-neg-common.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2017 - 2018 ARPA2 project
*
- * Author: Tom Vrancken
+ * Author: Tom Vrancken (dev@tomvrancken.nl)
*
* This file is part of GnuTLS.
*
@@ -15,7 +15,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public License
+ * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include <assert.h>
@@ -39,8 +39,15 @@ typedef struct test_case_st {
gnutls_certificate_type_t expected_srv_ctype;
int client_err;
int server_err;
- bool enable_cert_type_neg_cli;
- bool enable_cert_type_neg_srv;
+ unsigned int init_flags_cli;
+ unsigned int init_flags_srv;
+ bool request_cli_crt;
+ bool cli_srv_may_diverge;
+ // only needed when may_diverge is true
+ gnutls_certificate_type_t expected_cli_cli_ctype; // negotiated cli ctype on the client
+ gnutls_certificate_type_t expected_srv_cli_ctype; // negotiated cli ctype on the server
+ gnutls_certificate_type_t expected_cli_srv_ctype; // negotiated srv ctype on the client
+ gnutls_certificate_type_t expected_srv_srv_ctype; // negotiated srv ctype on the server
} test_case_st;
@@ -55,10 +62,6 @@ static void try(test_case_st * test)
gnutls_certificate_credentials_t server_creds = NULL;
gnutls_session_t server, client;
- gnutls_pubkey_t rawpk = NULL; // For RawPubKey tmp
- gnutls_privkey_t privkey = NULL; // For RawPubKey tmp
-
- sret = cret = GNUTLS_E_AGAIN;
// Initialize creds
assert(gnutls_certificate_allocate_credentials(&client_creds) >= 0);
@@ -68,14 +71,14 @@ static void try(test_case_st * test)
success("Running %s...\n", test->name);
// Init client/server
- if(test->enable_cert_type_neg_cli) {
- assert(gnutls_init(&client, GNUTLS_CLIENT | GNUTLS_ENABLE_CERT_TYPE_NEG) >= 0);
+ if(test->init_flags_cli) {
+ assert(gnutls_init(&client, GNUTLS_CLIENT | test->init_flags_cli) >= 0);
} else {
assert(gnutls_init(&client, GNUTLS_CLIENT) >= 0);
}
- if (test->enable_cert_type_neg_srv) {
- assert(gnutls_init(&server, GNUTLS_SERVER | GNUTLS_ENABLE_CERT_TYPE_NEG) >= 0);
+ if (test->init_flags_srv) {
+ assert(gnutls_init(&server, GNUTLS_SERVER | test->init_flags_srv) >= 0);
} else {
assert(gnutls_init(&server, GNUTLS_SERVER) >= 0);
}
@@ -93,7 +96,9 @@ static void try(test_case_st * test)
// Test for using RawPubKey cli credentials
if (test->set_cli_creds & CRED_RAWPK) {
- // TODO set client RawPubKey when support is ready
+ assert(gnutls_certificate_set_rawpk_key_mem(client_creds,
+ &rawpk_public_key1, &rawpk_private_key1, GNUTLS_X509_FMT_PEM,
+ NULL, 0, NULL, 0, 0) >= 0);
}
// -- Add extra ctype creds here in the future --
@@ -122,8 +127,10 @@ static void try(test_case_st * test)
}
// Test for using RawPubKey srv credentials
- if( test->set_srv_creds & CRED_RAWPK ) {
- //TODO when RawPK support is finished
+ if (test->set_srv_creds & CRED_RAWPK) {
+ assert(gnutls_certificate_set_rawpk_key_mem(server_creds,
+ &rawpk_public_key2, &rawpk_private_key2, GNUTLS_X509_FMT_PEM,
+ NULL, 0, NULL, 0, 0) >= 0);
}
// -- Add extra ctype creds here in the future --
@@ -138,6 +145,9 @@ static void try(test_case_st * test)
gnutls_transport_set_ptr(server, server);
assert(gnutls_priority_set_direct(server, test->server_prio, 0) >= 0);
+ if (test->request_cli_crt)
+ gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);
+
// Client settings
gnutls_transport_set_push_function(client, client_push);
gnutls_transport_set_pull_function(client, client_pull);
@@ -164,12 +174,6 @@ static void try(test_case_st * test)
cli_cli_ctype =
gnutls_certificate_type_get2(client, GNUTLS_CTYPE_CLIENT);
- /* Check whether the API functions return the correct cert types for OURS and PEERS */
- assert(srv_srv_ctype == gnutls_certificate_type_get2(server, GNUTLS_CTYPE_OURS));
- assert(srv_srv_ctype == gnutls_certificate_type_get2(client, GNUTLS_CTYPE_PEERS));
- assert(cli_cli_ctype == gnutls_certificate_type_get2(server, GNUTLS_CTYPE_PEERS));
- assert(cli_cli_ctype == gnutls_certificate_type_get2(client, GNUTLS_CTYPE_OURS));
-
// For debugging
if (debug) {
success("Srv srv ctype: %s\n", gnutls_certificate_type_get_name(srv_srv_ctype));
@@ -179,21 +183,46 @@ static void try(test_case_st * test)
}
/* Check whether the negotiated certificate types match the expected results */
- // Matching server ctype
- if (srv_srv_ctype != cli_srv_ctype) {
- fail("%s: client negotiated different server ctype than server (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(cli_srv_ctype), gnutls_certificate_type_get_name(srv_srv_ctype));
- }
- // Matching client ctype
- if (srv_cli_ctype != cli_cli_ctype) {
- fail("%s: client negotiated different client ctype than server (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(cli_cli_ctype), gnutls_certificate_type_get_name(srv_cli_ctype));
- }
- // Matching expected server ctype
- if (srv_srv_ctype != test->expected_srv_ctype) {
- fail("%s: negotiated server ctype diffs the expected (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(srv_srv_ctype), gnutls_certificate_type_get_name(test->expected_srv_ctype));
- }
- // Matching expected client ctype
- if (srv_cli_ctype != test->expected_cli_ctype) {
- fail("%s: negotiated server ctype diffs the expected (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(srv_cli_ctype), gnutls_certificate_type_get_name(test->expected_cli_ctype));
+ if (test->cli_srv_may_diverge) {
+ // Matching expected client ctype at client
+ if (cli_cli_ctype != test->expected_cli_cli_ctype) {
+ fail("%s: negotiated client ctype at client diffs the expected (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(cli_cli_ctype), gnutls_certificate_type_get_name(test->expected_cli_cli_ctype));
+ }
+ // Matching expected server ctype at client
+ if (cli_srv_ctype != test->expected_cli_srv_ctype) {
+ fail("%s: negotiated server ctype at client diffs the expected (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(cli_srv_ctype), gnutls_certificate_type_get_name(test->expected_cli_srv_ctype));
+ }
+ // Matching expected client ctype at server
+ if (srv_cli_ctype != test->expected_srv_cli_ctype) {
+ fail("%s: negotiated client ctype at server diffs the expected (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(srv_cli_ctype), gnutls_certificate_type_get_name(test->expected_srv_cli_ctype));
+ }
+ // Matching expected server ctype at server
+ if (srv_srv_ctype != test->expected_srv_srv_ctype) {
+ fail("%s: negotiated client ctype at client diffs the expected (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(srv_srv_ctype), gnutls_certificate_type_get_name(test->expected_srv_srv_ctype));
+ }
+ } else {
+ // Matching server ctype
+ if (srv_srv_ctype != cli_srv_ctype) {
+ fail("%s: client negotiated different server ctype than server (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(cli_srv_ctype), gnutls_certificate_type_get_name(srv_srv_ctype));
+ }
+ // Matching client ctype
+ if (srv_cli_ctype != cli_cli_ctype) {
+ fail("%s: client negotiated different client ctype than server (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(cli_cli_ctype), gnutls_certificate_type_get_name(srv_cli_ctype));
+ }
+ // Matching expected server ctype
+ if (srv_srv_ctype != test->expected_srv_ctype) {
+ fail("%s: negotiated server ctype diffs the expected (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(srv_srv_ctype), gnutls_certificate_type_get_name(test->expected_srv_ctype));
+ }
+ // Matching expected client ctype
+ if (srv_cli_ctype != test->expected_cli_ctype) {
+ fail("%s: negotiated client ctype diffs the expected (%s, %s)!\n", test->name, gnutls_certificate_type_get_name(srv_cli_ctype), gnutls_certificate_type_get_name(test->expected_cli_ctype));
+ }
+
+ /* Check whether the API functions return the correct cert types for OURS and PEERS */
+ assert(srv_srv_ctype == gnutls_certificate_type_get2(server, GNUTLS_CTYPE_OURS));
+ assert(srv_srv_ctype == gnutls_certificate_type_get2(client, GNUTLS_CTYPE_PEERS));
+ assert(cli_cli_ctype == gnutls_certificate_type_get2(server, GNUTLS_CTYPE_PEERS));
+ assert(cli_cli_ctype == gnutls_certificate_type_get2(client, GNUTLS_CTYPE_OURS));
}
}
@@ -202,8 +231,6 @@ static void try(test_case_st * test)
gnutls_deinit(client);
gnutls_certificate_free_credentials(client_creds);
gnutls_certificate_free_credentials(server_creds);
- gnutls_pubkey_deinit(rawpk);
- gnutls_privkey_deinit(privkey);
reset_buffers();
}
diff --git a/tests/rawpk-api.c b/tests/rawpk-api.c
new file mode 100644
index 0000000000..1be9acf973
--- /dev/null
+++ b/tests/rawpk-api.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 ARPA2 project
+ *
+ * Author: Tom Vrancken (dev@tomvrancken.nl)
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/abstract.h>
+#include "utils.h"
+#include <assert.h>
+#include "cert-common.h"
+
+/* Here we test the raw public-key API */
+
+void doit(void)
+{
+ int ret;
+ gnutls_certificate_credentials_t cred = NULL;
+ gnutls_pcert_st* pcert;
+ gnutls_pubkey_t pubkey;
+ const char *src;
+ char rawpk_pub_path[256];
+ char rawpk_priv_path[256];
+
+ // Get current src dir
+ src = getenv("srcdir");
+ if (src == NULL)
+ src = ".";
+
+ // Set file paths for pem files
+ snprintf(rawpk_pub_path, sizeof(rawpk_pub_path), "%s/%s", src, "certs/rawpk_pub.pem");
+ snprintf(rawpk_priv_path, sizeof(rawpk_priv_path), "%s/%s", src, "certs/rawpk_priv.pem");
+
+
+ global_init();
+
+ // Initialize creds
+ assert(gnutls_certificate_allocate_credentials(&cred) >= 0);
+ assert((pcert = gnutls_calloc(1, sizeof(*pcert))) != NULL);
+ assert(gnutls_pubkey_init(&pubkey) >= 0);
+ assert(gnutls_pubkey_import(pubkey, &rawpk_public_key1, GNUTLS_X509_FMT_PEM) >= 0);
+
+
+ /* Tests for gnutls_certificate_set_rawpk_key_mem() */
+ success("Testing gnutls_certificate_set_rawpk_key_mem()...\n");
+ // Positive tests
+ ret = gnutls_certificate_set_rawpk_key_mem(cred,
+ &rawpk_public_key2, &rawpk_private_key2, GNUTLS_X509_FMT_PEM,
+ NULL, 0, NULL, 0, 0);
+ if (ret < 0) {
+ fail("Failed to load credentials with error: %d\n", ret);
+ }
+ // Negative tests
+ ret = gnutls_certificate_set_rawpk_key_mem(cred,
+ NULL, &rawpk_private_key2, GNUTLS_X509_FMT_PEM,
+ NULL, 0, NULL, 0, 0);
+ if (ret != GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
+ fail("Failed to detect falsy input. Expected error: %d\n", GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+ ret = gnutls_certificate_set_rawpk_key_mem(cred,
+ &rawpk_public_key2, NULL, GNUTLS_X509_FMT_PEM,
+ NULL, 0, NULL, 0, 0);
+ if (ret != GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
+ fail("Failed to detect falsy input. Expected error: %d\n", GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+
+
+ /* Tests for gnutls_certificate_set_rawpk_key_file() */
+ success("Testing gnutls_certificate_set_rawpk_key_file()...\n");
+ // Positive tests
+ ret = gnutls_certificate_set_rawpk_key_file(cred, rawpk_pub_path, rawpk_priv_path, GNUTLS_X509_FMT_PEM, NULL, 0, NULL, 0, 0, 0);
+ if (ret < 0) {
+ fail("Failed to load credentials with error: %d\n", ret);
+ }
+ // Negative tests
+ ret = gnutls_certificate_set_rawpk_key_file(cred, NULL, rawpk_priv_path, GNUTLS_X509_FMT_PEM, NULL, 0, NULL, 0, 0, 0);
+ if (ret != GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
+ fail("Failed to detect falsy input. Expected error: %d\n", GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+ ret = gnutls_certificate_set_rawpk_key_file(cred, rawpk_pub_path, NULL, GNUTLS_X509_FMT_PEM, NULL, 0, NULL, 0, 0, 0);
+ if (ret != GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
+ fail("Failed to detect falsy input. Expected error: %d\n", GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+
+
+ /* Tests for gnutls_pcert_import_rawpk() */
+ success("Testing gnutls_pcert_import_rawpk()...\n");
+ // Positive tests
+ ret = gnutls_pcert_import_rawpk(pcert, pubkey, 0);
+ if (ret < 0) {
+ fail("Failed to import raw public-key into pcert with error: %d\n", ret);
+ }
+ // Negative tests
+ ret = gnutls_pcert_import_rawpk(pcert, NULL, 0);
+ if (ret != GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
+ fail("Failed to detect falsy input. Expected error: %d\n", GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+ // Cleanup to prevent subsequent API calls to produce memory leaks
+ gnutls_pcert_deinit(pcert);
+
+
+ /* Tests for gnutls_pcert_import_rawpk_raw() */
+ success("Testing gnutls_pcert_import_rawpk_raw()...\n");
+ // Positive tests
+ ret = gnutls_pcert_import_rawpk_raw(pcert, &rawpk_public_key1, GNUTLS_X509_FMT_PEM, 0, 0);
+ if (ret < 0) {
+ fail("Failed to import raw public-key into pcert with error: %d\n", ret);
+ }
+ // Negative tests
+ ret = gnutls_pcert_import_rawpk_raw(pcert, NULL, GNUTLS_X509_FMT_PEM, 0, 0);
+ if (ret != GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
+ fail("Failed to detect falsy input. Expected error: %d\n", GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+ }
+ // Cleanup to prevent subsequent API calls to produce memory leaks
+ gnutls_pcert_deinit(pcert);
+
+
+ // Generic cleanup
+ gnutls_free(pcert);
+ gnutls_certificate_free_credentials(cred);
+
+ gnutls_global_deinit();
+}
+
diff --git a/tests/ssl30-cert-key-exchange.c b/tests/ssl30-cert-key-exchange.c
index eccb4955d8..662721a2bd 100644
--- a/tests/ssl30-cert-key-exchange.c
+++ b/tests/ssl30-cert-key-exchange.c
@@ -40,15 +40,15 @@ void doit(void)
{
#ifdef ENABLE_SSL3
global_init();
- try("SSL 3.0 with anon-dh", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+ANON-DH", GNUTLS_KX_ANON_DH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("SSL 3.0 with dhe-rsa no cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("SSL 3.0 with anon-dh", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+ANON-DH", GNUTLS_KX_ANON_DH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("SSL 3.0 with dhe-rsa no cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("SSL 3.0 with rsa no cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try_cli("SSL 3.0 with dhe-rsa cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
- try_cli("SSL 3.0 with rsa cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
+ try_x509("SSL 3.0 with rsa no cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509_cli("SSL 3.0 with dhe-rsa cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
+ try_x509_cli("SSL 3.0 with rsa cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
- try_cli("SSL 3.0 with dhe-rsa ask cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
- try_cli("SSL 3.0 with rsa ask cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_x509_cli("SSL 3.0 with dhe-rsa ask cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_x509_cli("SSL 3.0 with rsa ask cert", "NORMAL:-VERS-ALL:+VERS-SSL3.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
gnutls_global_deinit();
#else
exit(77);
diff --git a/tests/tls-crt_type-neg.c b/tests/tls-crt_type-neg.c
index ff5aa08885..f09d3cb27f 100644
--- a/tests/tls-crt_type-neg.c
+++ b/tests/tls-crt_type-neg.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2017 - 2018 ARPA2 project
*
- * Author: Tom Vrancken
+ * Author: Tom Vrancken (dev@tomvrancken.nl)
*
* This file is part of GnuTLS.
*
@@ -15,7 +15,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General Public License
+ * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
@@ -40,254 +40,393 @@ test_case_st tests[] = {
/* Tests with only a single credential set for client/server.
* Tests for X.509 cases.
*/
- {
+ {
/* Default case A
*
* Priority cli: NORMAL
* Priority srv: NORMAL
- * Certificate negotiation mechanism: disabled
* Cli creds: None
* Srv creds: X.509
* Handshake: should complete without errors
* Negotiation: cert types should default to X.509
*/
- .name = "Default case A. Neg off (default). Creds set (CLI/SRV): None/X509.",
+ .name = "Default case A. Creds set (CLI/SRV): None/X509.",
.client_prio = "NORMAL",
.server_prio = "NORMAL",
.set_cli_creds = CRED_EMPTY,
.set_srv_creds = CRED_X509,
.expected_cli_ctype = GNUTLS_CRT_X509,
- .expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = false,
- .enable_cert_type_neg_srv = false},
+ .expected_srv_ctype = GNUTLS_CRT_X509},
{
/* Default case B
*
* Priority: NORMAL
- * Certificate negotiation mechanism: disabled
* Cli creds: X.509
* Srv creds: X.509
* Handshake: should complete without errors
* Negotiation: cert types should default to X.509
*/
- .name = "Default case B. Neg off (default). Creds set (CLI/SRV): X509/X509.",
+ .name = "Default case B. Creds set (CLI/SRV): X509/X509. No cli cert asked.",
.client_prio = "NORMAL",
.server_prio = "NORMAL",
.set_cli_creds = CRED_X509,
.set_srv_creds = CRED_X509,
.expected_cli_ctype = GNUTLS_CRT_X509,
- .expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = false,
- .enable_cert_type_neg_srv = false},
- {
- /* No server credentials
- *
- * Priority: NORMAL
- * Certificate negotiation mechanism: disabled
- * Cli creds: None
- * Srv creds: None
- * Handshake: results in errors
- * Negotiation: cert types are not evaluated
- */
- .name = "No server creds. Creds set (CLI/SRV): None/None.",
- .client_prio = "NORMAL",
- .server_prio = "NORMAL",
- .set_cli_creds = CRED_EMPTY,
- .set_srv_creds = CRED_EMPTY,
- .client_err = GNUTLS_E_AGAIN,
- .server_err = GNUTLS_E_NO_CIPHER_SUITES,
- .enable_cert_type_neg_cli = false,
- .enable_cert_type_neg_srv = false},
+ .expected_srv_ctype = GNUTLS_CRT_X509},
{
- /* Client can negotiate, server not
+ /* Default case C
*
* Priority: NORMAL
- * Certificate negotiation mechanism (cli/srv): enabled/disabled
- * Cli creds: None
+ * Cli creds: X.509
* Srv creds: X.509
* Handshake: should complete without errors
* Negotiation: cert types should default to X.509
*/
- .name = "Client can negotiate, server not",
+ .name = "Default case C. Creds set (CLI/SRV): X509/X509. Cli cert asked.",
.client_prio = "NORMAL",
.server_prio = "NORMAL",
- .set_cli_creds = CRED_EMPTY,
+ .set_cli_creds = CRED_X509,
.set_srv_creds = CRED_X509,
.expected_cli_ctype = GNUTLS_CRT_X509,
.expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = true,
- .enable_cert_type_neg_srv = false},
+ .request_cli_crt = true},
{
- /* Server can negotiate, client not
+ /* No server credentials
*
* Priority: NORMAL
- * Certificate negotiation mechanism (cli/srv): disabled/enabled
* Cli creds: None
- * Srv creds: X.509
- * Handshake: should complete without errors
- * Negotiation: cert types should default to X.509
+ * Srv creds: None
+ * Handshake: results in errors
+ * Negotiation: cert types are not evaluated
*/
- .name = "Server can negotiate, client not",
+ .name = "No server creds. Creds set (CLI/SRV): None/None.",
.client_prio = "NORMAL",
.server_prio = "NORMAL",
.set_cli_creds = CRED_EMPTY,
- .set_srv_creds = CRED_X509,
- .expected_cli_ctype = GNUTLS_CRT_X509,
- .expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = false,
- .enable_cert_type_neg_srv = true},
+ .set_srv_creds = CRED_EMPTY,
+ .client_err = GNUTLS_E_AGAIN,
+ .server_err = GNUTLS_E_NO_CIPHER_SUITES},
{
- /* Client and server can negotiate
+ /* Explicit cli/srv ctype negotiation, cli creds x509, srv creds x509
*
- * Priority: NORMAL
- * Certificate negotiation mechanism (cli/srv): enabled/enabled
- * Cli creds: None
+ * Priority: NORMAL + request x509 for cli and srv
+ * Cli creds: X.509
* Srv creds: X.509
* Handshake: should complete without errors
- * Negotiation: cert types should default to X.509
+ * Negotiation: Fallback to default cli X.509, srv X.509 because
+ * we advertise with only the cert type defaults. Extensions
+ * will therefore not be activated.
*/
- .name = "Client and server can negotiate",
- .client_prio = "NORMAL",
- .server_prio = "NORMAL",
- .set_cli_creds = CRED_EMPTY,
+ .name = "Negotiate CLI X.509 + SRV X.509. Creds set (CLI/SRV): X.509/X.509.",
+ .client_prio = "NORMAL:+CTYPE-CLI-X509:+CTYPE-SRV-X509",
+ .server_prio = "NORMAL:+CTYPE-CLI-X509:+CTYPE-SRV-X509",
+ .set_cli_creds = CRED_X509,
.set_srv_creds = CRED_X509,
.expected_cli_ctype = GNUTLS_CRT_X509,
- .expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = true,
- .enable_cert_type_neg_srv = true},
+ .expected_srv_ctype = GNUTLS_CRT_X509},
{
- /* Negotiate both, cli creds x509, srv creds x509
+ /* Explicit cli/srv ctype negotiation, cli creds x509, srv creds x509, no cli cert asked
*
- * Priority: NORMAL + request x509 for cli and srv
- * Certificate negotiation mechanism (cli/srv): enabled/enabled
+ * Priority: NORMAL + request x509 for cli
* Cli creds: X.509
* Srv creds: X.509
* Handshake: should complete without errors
* Negotiation: Fallback to default cli X.509, srv X.509 because
- * we advertise with only the cert type defaults.
+ * we advertise with only the cert type defaults. Extensions
+ * will therefore not be activated.
*/
- .name = "Negotiate CLI X.509 + SRV X.509, cli/srv X.509 creds set",
- .client_prio = "NORMAL:+CTYPE-CLI-X509:+CTYPE-SRV-X509",
- .server_prio = "NORMAL:+CTYPE-CLI-X509:+CTYPE-SRV-X509",
+ .name = "Negotiate CLI X.509. Creds set (CLI/SRV): X.509/X.509.",
+ .client_prio = "NORMAL:+CTYPE-CLI-X509",
+ .server_prio = "NORMAL:+CTYPE-CLI-X509",
.set_cli_creds = CRED_X509,
.set_srv_creds = CRED_X509,
.expected_cli_ctype = GNUTLS_CRT_X509,
- .expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = true,
- .enable_cert_type_neg_srv = true},
+ .expected_srv_ctype = GNUTLS_CRT_X509},
{
- /* Negotiate cli x509, cli creds x509, srv creds x509
+ /* Explicit cli/srv ctype negotiation, cli creds x509, srv creds x509, cli cert asked
*
* Priority: NORMAL + request x509 for cli
- * Certificate negotiation mechanism (cli/srv): enabled/enabled
* Cli creds: X.509
* Srv creds: X.509
* Handshake: should complete without errors
* Negotiation: Fallback to default cli X.509, srv X.509 because
- * we advertise with only the cert type defaults.
+ * we advertise with only the cert type defaults. Extensions
+ * will therefore not be activated.
*/
- .name = "Negotiate CLI X.509, cli/srv X.509 creds set",
+ .name = "Negotiate CLI X.509. Creds set (CLI/SRV): X.509/X.509.",
.client_prio = "NORMAL:+CTYPE-CLI-X509",
.server_prio = "NORMAL:+CTYPE-CLI-X509",
.set_cli_creds = CRED_X509,
.set_srv_creds = CRED_X509,
.expected_cli_ctype = GNUTLS_CRT_X509,
.expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = true,
- .enable_cert_type_neg_srv = true},
+ .request_cli_crt = true},
{
- /* Negotiate srv x509, cli creds x509, srv creds x509
+ /* Explicit cli/srv ctype negotiation, cli creds x509, srv creds x509
*
* Priority: NORMAL + request x509 for srv
- * Certificate negotiation mechanism (cli/srv): enabled/enabled
* Cli creds: X.509
* Srv creds: X.509
* Handshake: should complete without errors
* Negotiation: Fallback to default cli X.509, srv X.509 because
- * we advertise with only the cert type defaults.
+ * we advertise with only the cert type defaults. Extensions
+ * will therefore not be activated.
*/
- .name = "Negotiate SRV X.509, cli/srv X.509 creds set",
+ .name = "Negotiate SRV X.509. Creds set (CLI/SRV): X.509/X.509.",
.client_prio = "NORMAL:+CTYPE-SRV-X509",
.server_prio = "NORMAL:+CTYPE-SRV-X509",
.set_cli_creds = CRED_X509,
.set_srv_creds = CRED_X509,
.expected_cli_ctype = GNUTLS_CRT_X509,
- .expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = true,
- .enable_cert_type_neg_srv = true},
+ .expected_srv_ctype = GNUTLS_CRT_X509},
{
- /* All types allowed for CLI, cli creds x509, srv creds x509
+ /* Explicit cli/srv ctype negotiation, all types allowed for CLI, cli creds x509, srv creds x509
*
* Priority: NORMAL + allow all client cert types
- * Certificate negotiation mechanism (cli/srv): enabled/enabled
* Cli creds: X.509
* Srv creds: X.509
* Handshake: should complete without errors
- * Negotiation: Fallback to default cli X.509, srv X.509 because
- * we advertise with only the cert type defaults.
+ * Negotiation: cli X.509 and srv X.509 because
+ * we only have X.509 credentials set.
*/
- .name = "Negotiate CLI all, cli/srv X.509 creds set",
+ .name = "Negotiate CLI all. Creds set (CLI/SRV): X.509/X.509.",
.client_prio = "NORMAL:+CTYPE-CLI-ALL",
.server_prio = "NORMAL:+CTYPE-CLI-ALL",
.set_cli_creds = CRED_X509,
.set_srv_creds = CRED_X509,
.expected_cli_ctype = GNUTLS_CRT_X509,
- .expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = true,
- .enable_cert_type_neg_srv = true},
+ .expected_srv_ctype = GNUTLS_CRT_X509},
{
- /* All types allowed for SRV, cli creds x509, srv creds x509
+ /* Explicit cli/srv ctype negotiation, all types allowed for SRV, cli creds x509, srv creds x509
*
* Priority: NORMAL + allow all server cert types
- * Certificate negotiation mechanism (cli/srv): enabled/enabled
* Cli creds: X.509
* Srv creds: X.509
* Handshake: should complete without errors
- * Negotiation: Fallback to default cli X.509, srv X.509 because
- * we advertise with only the cert type defaults.
+ * Negotiation: cli X.509 and srv X.509 because
+ * we only have X.509 credentials set.
*/
- .name = "Negotiate SRV all, cli/srv X.509 creds set",
+ .name = "Negotiate SRV all. Creds set (CLI/SRV): X.509/X.509.",
.client_prio = "NORMAL:+CTYPE-SRV-ALL",
.server_prio = "NORMAL:+CTYPE-SRV-ALL",
.set_cli_creds = CRED_X509,
.set_srv_creds = CRED_X509,
.expected_cli_ctype = GNUTLS_CRT_X509,
- .expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = true,
- .enable_cert_type_neg_srv = true},
+ .expected_srv_ctype = GNUTLS_CRT_X509},
{
- /* All types allowed for CLI/SRV, cli creds x509, srv creds x509
+ /* Explicit cli/srv ctype negotiation, all types allowed for CLI/SRV, cli creds x509, srv creds x509
*
* Priority: NORMAL + allow all client and server cert types
- * Certificate negotiation mechanism (cli/srv): enabled/enabled
* Cli creds: X.509
* Srv creds: X.509
* Handshake: should complete without errors
- * Negotiation: Fallback to default cli X.509, srv X.509 because
- * we advertise with only the cert type defaults.
+ * Negotiation: cli X.509 and srv X.509 because
+ * we only have X.509 credentials set.
*/
- .name = "Negotiate CLI/SRV all, cli/srv X.509 creds set",
+ .name = "Negotiate CLI/SRV all. Creds set (CLI/SRV): X.509/X.509.",
.client_prio = "NORMAL:+CTYPE-CLI-ALL:+CTYPE-SRV-ALL",
.server_prio = "NORMAL:+CTYPE-CLI-ALL:+CTYPE-SRV-ALL",
.set_cli_creds = CRED_X509,
.set_srv_creds = CRED_X509,
.expected_cli_ctype = GNUTLS_CRT_X509,
- .expected_srv_ctype = GNUTLS_CRT_X509,
- .enable_cert_type_neg_cli = true,
- .enable_cert_type_neg_srv = true}
+ .expected_srv_ctype = GNUTLS_CRT_X509},
/* Tests with only a single credential set for client/server.
* Tests for Raw public-key cases.
*/
- //TODO implement when Raw public key support is finished
-
- /* Tests with only a single credential set for client/server.
- * Tests for KDH cases.
- */
- //TODO implement when KDH support is finished
+ {
+ /* Explicit cli/srv ctype negotiation, cli creds Raw PK, srv creds Raw PK, Req. cli cert.
+ *
+ * Priority: NORMAL + request rawpk for cli and srv
+ * Cli creds: Raw PK
+ * Srv creds: Raw PK
+ * Request client cert: yes
+ * Handshake: should complete without errors
+ * Negotiation: both parties should have a Raw PK cert negotiated
+ */
+ .name = "Negotiate CLI Raw PK + SRV Raw PK. Creds set (CLI/SRV): RawPK/RawPK. Cert req.",
+ .client_prio = "NORMAL:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK",
+ .server_prio = "NORMAL:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK",
+ .set_cli_creds = CRED_RAWPK,
+ .set_srv_creds = CRED_RAWPK,
+ .expected_cli_ctype = GNUTLS_CRT_RAWPK,
+ .expected_srv_ctype = GNUTLS_CRT_RAWPK,
+ .init_flags_cli = GNUTLS_ENABLE_RAWPK,
+ .init_flags_srv = GNUTLS_ENABLE_RAWPK,
+ .request_cli_crt = true},
+ {
+ /* Explicit cli/srv ctype negotiation (TLS 1.2), cli creds Raw PK, srv creds Raw PK
+ *
+ * Priority: NORMAL + request rawpk for cli and srv
+ * Cli creds: Raw PK
+ * Srv creds: Raw PK
+ * Request client cert: no
+ * Handshake: should complete without errors
+ * Negotiation: a Raw PK server cert. A diverged state for the client
+ * cert type. The server picks Raw PK but does not send a response
+ * to the client (under TLS 1.2). The client therefore falls back to default (X.509).
+ */
+ .name = "Negotiate CLI Raw PK + SRV Raw PK. Creds set (CLI/SRV): RawPK/RawPK.",
+ .client_prio = "NORMAL:-VERS-ALL:+VERS-TLS1.2:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK",
+ .server_prio = "NORMAL:-VERS-ALL:+VERS-TLS1.2:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK",
+ .set_cli_creds = CRED_RAWPK,
+ .set_srv_creds = CRED_RAWPK,
+ .expected_cli_cli_ctype = GNUTLS_CRT_X509,
+ .expected_srv_cli_ctype = GNUTLS_CRT_RAWPK,
+ .expected_cli_srv_ctype = GNUTLS_CRT_RAWPK,
+ .expected_srv_srv_ctype = GNUTLS_CRT_RAWPK,
+ .init_flags_cli = GNUTLS_ENABLE_RAWPK,
+ .init_flags_srv = GNUTLS_ENABLE_RAWPK,
+ .request_cli_crt = false,
+ .cli_srv_may_diverge = true},
+ {
+ /* Explicit cli/srv ctype negotiation (TLS 1.3), cli creds Raw PK, srv creds Raw PK
+ *
+ * Priority: NORMAL + request rawpk for cli and srv
+ * Cli creds: Raw PK
+ * Srv creds: Raw PK
+ * Request client cert: no
+ * Handshake: should complete without errors
+ * Negotiation: a Raw PK server cert and client cert. Under TLS 1.3
+ * a respons is always sent by the server also when no client
+ * cert is requested. This is necessary for post-handshake authentication
+ * to work.
+ */
+ .name = "Negotiate CLI Raw PK + SRV Raw PK. Creds set (CLI/SRV): RawPK/RawPK.",
+ .client_prio = "NORMAL:-VERS-ALL:+VERS-TLS1.3:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK",
+ .server_prio = "NORMAL:-VERS-ALL:+VERS-TLS1.3:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK",
+ .set_cli_creds = CRED_RAWPK,
+ .set_srv_creds = CRED_RAWPK,
+ .expected_cli_cli_ctype = GNUTLS_CRT_RAWPK,
+ .expected_srv_cli_ctype = GNUTLS_CRT_RAWPK,
+ .expected_cli_srv_ctype = GNUTLS_CRT_RAWPK,
+ .expected_srv_srv_ctype = GNUTLS_CRT_RAWPK,
+ .init_flags_cli = GNUTLS_ENABLE_RAWPK,
+ .init_flags_srv = GNUTLS_ENABLE_RAWPK,
+ .request_cli_crt = false,
+ .cli_srv_may_diverge = true},
+ {
+ /* Explicit cli/srv ctype negotiation, cli creds Raw PK, srv creds Raw PK
+ *
+ * Priority: NORMAL + request rawpk for cli
+ * Cli creds: Raw PK
+ * Srv creds: Raw PK
+ * Request client cert: no
+ * Handshake: fails because no valid cred (X.509) can be found for the server.
+ * Negotiation: -
+ */
+ .name = "Negotiate CLI Raw PK. Creds set (CLI/SRV): RawPK/RawPK.",
+ .client_prio = "NORMAL:+CTYPE-CLI-RAWPK",
+ .server_prio = "NORMAL:+CTYPE-CLI-RAWPK",
+ .set_cli_creds = CRED_RAWPK,
+ .set_srv_creds = CRED_RAWPK,
+ .init_flags_cli = GNUTLS_ENABLE_RAWPK,
+ .init_flags_srv = GNUTLS_ENABLE_RAWPK,
+ .client_err = GNUTLS_E_AGAIN,
+ .server_err = GNUTLS_E_NO_CIPHER_SUITES},
+ {
+ /* Explicit cli/srv ctype negotiation, cli creds Raw PK, srv creds Raw PK, request cli cert.
+ *
+ * Priority: NORMAL + request rawpk for srv
+ * Cli creds: Raw PK
+ * Srv creds: Raw PK
+ * Request client cert: yes
+ * Handshake: should complete without errors
+ * Negotiation: Raw PK will be negotiated for server. Client will
+ * default to X.509.
+ */
+ .name = "Negotiate SRV Raw PK. Creds set (CLI/SRV): RawPK/RawPK.",
+ .client_prio = "NORMAL:+CTYPE-SRV-RAWPK",
+ .server_prio = "NORMAL:+CTYPE-SRV-RAWPK",
+ .set_cli_creds = CRED_RAWPK,
+ .set_srv_creds = CRED_RAWPK,
+ .expected_cli_ctype = GNUTLS_CRT_X509,
+ .expected_srv_ctype = GNUTLS_CRT_RAWPK,
+ .init_flags_cli = GNUTLS_ENABLE_RAWPK,
+ .init_flags_srv = GNUTLS_ENABLE_RAWPK,
+ .request_cli_crt = true},
+ {
+ /* Explicit cli/srv ctype negotiation, cli creds Raw PK, srv creds X.509, Request cli cert.
+ *
+ * Priority: NORMAL + request rawpk for cli and srv
+ * Cli creds: Raw PK
+ * Srv creds: X.509
+ * Request client cert: yes
+ * Handshake: should complete without errors
+ * Negotiation: Raw PK will be negotiated for client. Server will
+ * default to X.509.
+ */
+ .name = "Negotiate CLI and SRV Raw PK. Creds set (CLI/SRV): RawPK/X.509.",
+ .client_prio = "NORMAL:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK",
+ .server_prio = "NORMAL:+CTYPE-CLI-RAWPK:+CTYPE-SRV-RAWPK",
+ .set_cli_creds = CRED_RAWPK,
+ .set_srv_creds = CRED_X509,
+ .expected_cli_ctype = GNUTLS_CRT_RAWPK,
+ .expected_srv_ctype = GNUTLS_CRT_X509,
+ .init_flags_cli = GNUTLS_ENABLE_RAWPK,
+ .init_flags_srv = GNUTLS_ENABLE_RAWPK,
+ .request_cli_crt = true},
+ {
+ /* All types allowed for CLI, cli creds Raw PK, srv creds X.509
+ *
+ * Priority: NORMAL + allow all client cert types
+ * Cli creds: Raw PK
+ * Srv creds: X.509
+ * Handshake: should complete without errors
+ * Negotiation: cli Raw PK and srv X.509 because
+ * that are the only credentials set.
+ */
+ .name = "Negotiate CLI all. Creds set (CLI/SRV): Raw PK/X.509.",
+ .client_prio = "NORMAL:+CTYPE-CLI-ALL",
+ .server_prio = "NORMAL:+CTYPE-CLI-ALL",
+ .set_cli_creds = CRED_RAWPK,
+ .set_srv_creds = CRED_X509,
+ .expected_cli_ctype = GNUTLS_CRT_RAWPK,
+ .expected_srv_ctype = GNUTLS_CRT_X509,
+ .init_flags_cli = GNUTLS_ENABLE_RAWPK,
+ .init_flags_srv = GNUTLS_ENABLE_RAWPK,
+ .request_cli_crt = true},
+ {
+ /* All types allowed for SRV, cli creds x509, srv creds Raw PK
+ *
+ * Priority: NORMAL + allow all server cert types
+ * Cli creds: X.509
+ * Srv creds: Raw PK
+ * Handshake: should complete without errors
+ * Negotiation: cli X.509 and srv Raw PK because
+ * that are the only credentials set.
+ */
+ .name = "Negotiate SRV all. Creds set (CLI/SRV): X.509/Raw PK.",
+ .client_prio = "NORMAL:+CTYPE-SRV-ALL",
+ .server_prio = "NORMAL:+CTYPE-SRV-ALL",
+ .set_cli_creds = CRED_X509,
+ .set_srv_creds = CRED_RAWPK,
+ .expected_cli_ctype = GNUTLS_CRT_X509,
+ .expected_srv_ctype = GNUTLS_CRT_RAWPK,
+ .init_flags_cli = GNUTLS_ENABLE_RAWPK,
+ .init_flags_srv = GNUTLS_ENABLE_RAWPK,
+ .request_cli_crt = true},
+ {
+ /* All types allowed for CLI/SRV, cli creds Raw PK, srv creds Raw PK
+ *
+ * Priority: NORMAL + allow all client and server cert types
+ * Cli creds: Raw PK
+ * Srv creds: Raw PK
+ * Handshake: should complete without errors
+ * Negotiation: cli Raw PK and srv Raw PK because
+ * that are the only credentials set.
+ */
+ .name = "Negotiate CLI/SRV all. Creds set (CLI/SRV): Raw PK/Raw PK.",
+ .client_prio = "NORMAL:+CTYPE-CLI-ALL:+CTYPE-SRV-ALL",
+ .server_prio = "NORMAL:+CTYPE-CLI-ALL:+CTYPE-SRV-ALL",
+ .set_cli_creds = CRED_RAWPK,
+ .set_srv_creds = CRED_RAWPK,
+ .expected_cli_ctype = GNUTLS_CRT_RAWPK,
+ .expected_srv_ctype = GNUTLS_CRT_RAWPK,
+ .init_flags_cli = GNUTLS_ENABLE_RAWPK,
+ .init_flags_srv = GNUTLS_ENABLE_RAWPK,
+ .request_cli_crt = true},
- /* Tests with multiple credentials set for client/server. */
- //TODO implement when support for more cert types is ready
};
void doit(void)
diff --git a/tests/tls10-cert-key-exchange.c b/tests/tls10-cert-key-exchange.c
index e1cee39253..1b976c37ee 100644
--- a/tests/tls10-cert-key-exchange.c
+++ b/tests/tls10-cert-key-exchange.c
@@ -40,26 +40,26 @@ void doit(void)
{
global_init();
- try("TLS 1.0 with anon-ecdh", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ANON-ECDH", GNUTLS_KX_ANON_ECDH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.0 with anon-dh", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ANON-DH", GNUTLS_KX_ANON_DH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.0 with dhe-rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.0 with ecdhe x25519 rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-RSA:-CURVE-ALL:+CURVE-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.0 with ecdhe rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.0 with anon-ecdh", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ANON-ECDH", GNUTLS_KX_ANON_ECDH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.0 with anon-dh", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ANON-DH", GNUTLS_KX_ANON_DH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.0 with dhe-rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.0 with ecdhe x25519 rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-RSA:-CURVE-ALL:+CURVE-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.0 with ecdhe rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
try_with_key("TLS 1.0 with ecdhe ecdsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0);
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
- try("TLS 1.0 with rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try_cli("TLS 1.0 with dhe-rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
- try_cli("TLS 1.0 with ecdhe-rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
- try_cli("TLS 1.0 with rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
+ try_x509("TLS 1.0 with rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509_cli("TLS 1.0 with dhe-rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
+ try_x509_cli("TLS 1.0 with ecdhe-rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
+ try_x509_cli("TLS 1.0 with rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
try_with_key("TLS 1.0 with ecdhe ecdsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, USE_CERT);
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, USE_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
- try_cli("TLS 1.0 with dhe-rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
- try_cli("TLS 1.0 with ecdhe-rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
- try_cli("TLS 1.0 with rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_x509_cli("TLS 1.0 with dhe-rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_x509_cli("TLS 1.0 with ecdhe-rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_x509_cli("TLS 1.0 with rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
try_with_key("TLS 1.0 with ecdhe ecdsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.0:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, ASK_CERT);
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, ASK_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
gnutls_global_deinit();
}
diff --git a/tests/tls11-cert-key-exchange.c b/tests/tls11-cert-key-exchange.c
index 860574afdc..ef4b81e5d5 100644
--- a/tests/tls11-cert-key-exchange.c
+++ b/tests/tls11-cert-key-exchange.c
@@ -40,27 +40,27 @@ void doit(void)
{
global_init();
- try("TLS 1.1 with anon-ecdh", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ANON-ECDH", GNUTLS_KX_ANON_ECDH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.1 with anon-dh", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ANON-DH", GNUTLS_KX_ANON_DH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.1 with dhe-rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.1 with ecdhe x25519 rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-RSA:-CURVE-ALL:+CURVE-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.1 with ecdhe rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.1 with anon-ecdh", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ANON-ECDH", GNUTLS_KX_ANON_ECDH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.1 with anon-dh", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ANON-DH", GNUTLS_KX_ANON_DH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.1 with dhe-rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.1 with ecdhe x25519 rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-RSA:-CURVE-ALL:+CURVE-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.1 with ecdhe rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
try_with_key("TLS 1.1 with ecdhe ecdsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0);
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
- try("TLS 1.1 with rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.1 with rsa no cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try_cli("TLS 1.1 with dhe-rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
- try_cli("TLS 1.1 with ecdhe-rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
- try_cli("TLS 1.1 with rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
+ try_x509_cli("TLS 1.1 with dhe-rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
+ try_x509_cli("TLS 1.1 with ecdhe-rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
+ try_x509_cli("TLS 1.1 with rsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, USE_CERT);
try_with_key("TLS 1.1 with ecdhe ecdsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, USE_CERT);
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, USE_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
- try_cli("TLS 1.1 with dhe-rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
- try_cli("TLS 1.1 with ecdhe-rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
- try_cli("TLS 1.1 with rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_x509_cli("TLS 1.1 with dhe-rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_x509_cli("TLS 1.1 with ecdhe-rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_x509_cli("TLS 1.1 with rsa ask cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
try_with_key("TLS 1.1 with ecdhe ecdsa cert", "NORMAL:-VERS-ALL:+VERS-TLS1.1:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, ASK_CERT);
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, ASK_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
/* illegal setups */
server_priority = NULL;
diff --git a/tests/tls12-cert-key-exchange.c b/tests/tls12-cert-key-exchange.c
index bdfd91f72f..7811ae85bb 100644
--- a/tests/tls12-cert-key-exchange.c
+++ b/tests/tls12-cert-key-exchange.c
@@ -40,51 +40,69 @@ void doit(void)
{
global_init();
- try("TLS 1.2 with anon-ecdh", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ANON-ECDH", GNUTLS_KX_ANON_ECDH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.2 with anon-dh", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ANON-DH", GNUTLS_KX_ANON_DH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.2 with dhe-rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.2 with ecdhe x25519 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-CURVE-ALL:+CURVE-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.2 with ecdhe rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
- try_with_key("TLS 1.2 with ecdhe ecdsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0);
- try("TLS 1.2 with ecdhe rsa-pss sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ /** X.509 tests **/
+ try_x509("TLS 1.2 with anon-ecdh", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ANON-ECDH", GNUTLS_KX_ANON_ECDH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.2 with anon-dh", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ANON-DH", GNUTLS_KX_ANON_DH, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.2 with dhe-rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.2 with ecdhe x25519 rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-CURVE-ALL:+CURVE-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.2 with ecdhe rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_with_key("TLS 1.2 with ecdhe ecdsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+ try_x509("TLS 1.2 with ecdhe rsa-pss sig no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
/* Test RSA-PSS cert/key combo issues */
- try_with_key("TLS 1.2 with ecdhe with rsa-pss-sha256 key no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0);
- try_with_key("TLS 1.2 with ecdhe with rsa-pss-sha256 key and 1 sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0);
- try_with_key("TLS 1.2 with ecdhe with rsa-pss-sha256 key and rsa-pss-sha384 first sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0);
- try_with_key("TLS 1.2 with ecdhe with rsa-pss-sha256 key and rsa-pss-sha512 first sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA512:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0);
-
- try("TLS 1.2 with ecdhe rsa-pss no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
- try_with_key("TLS 1.2 with ecdhe rsa-pss/rsa-pss no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, NULL, NULL, 0);
- try("TLS 1.2 with rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
- try_with_key("TLS 1.2 with ecdhe x25519 ed25519 no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA:-CURVE-ALL:+CURVE-X25519:-SIGN-ALL:+SIGN-EDDSA-ED25519", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_EDDSA_ED25519, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_eddsa_cert, &server_ca3_eddsa_key, NULL, NULL, 0);
-
- try_cli("TLS 1.2 with dhe-rsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_RSA_SHA256, USE_CERT);
- try_cli("TLS 1.2 with ecdhe-rsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_RSA_SHA256, USE_CERT);
- try_cli("TLS 1.2 with rsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_RSA_SHA256, USE_CERT);
- try_with_key("TLS 1.2 with ecdhe ecdsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_RSA_SHA256,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, USE_CERT);
- try_cli("TLS 1.2 with ecdhe-rsa-pss cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, USE_CERT);
- try_with_key("TLS 1.2 with ecdhe-rsa-pss/rsa-pss cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256,
- &server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, &cli_ca3_rsa_pss_cert, &cli_ca3_rsa_pss_key, USE_CERT);
-
- try_with_key("TLS 1.2 with ecdhe x25519 ed25519 cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA:-CURVE-ALL:+CURVE-X25519:-SIGN-ALL:+SIGN-EDDSA-ED25519", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_EDDSA_ED25519, GNUTLS_SIGN_EDDSA_ED25519,
- &server_ca3_eddsa_cert, &server_ca3_eddsa_key, &server_ca3_eddsa_cert, &server_ca3_eddsa_key, USE_CERT);
-
- try_cli("TLS 1.2 with dhe-rsa ask cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
- try_cli("TLS 1.2 with ecdhe-rsa ask cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
- try_cli("TLS 1.2 with rsa ask cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
- try_with_key("TLS 1.2 with ecdhe ecdsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, ASK_CERT);
-
- /* illegal setups */
+ try_with_key("TLS 1.2 with ecdhe with rsa-pss-sha256 key no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+ try_with_key("TLS 1.2 with ecdhe with rsa-pss-sha256 key and 1 sig no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+ try_with_key("TLS 1.2 with ecdhe with rsa-pss-sha256 key and rsa-pss-sha384 first sig no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+ try_with_key("TLS 1.2 with ecdhe with rsa-pss-sha256 key and rsa-pss-sha512 first sig no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA512:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+
+ try_x509("TLS 1.2 with ecdhe rsa-pss no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_with_key("TLS 1.2 with ecdhe rsa-pss/rsa-pss no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, NULL, NULL, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+ try_x509("TLS 1.2 with rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+ try_with_key("TLS 1.2 with ecdhe x25519 ed25519 no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA:-CURVE-ALL:+CURVE-X25519:-SIGN-ALL:+SIGN-EDDSA-ED25519", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_EDDSA_ED25519, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_eddsa_cert, &server_ca3_eddsa_key, NULL, NULL, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+
+ try_x509_cli("TLS 1.2 with dhe-rsa cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_RSA_SHA256, USE_CERT);
+ try_x509_cli("TLS 1.2 with ecdhe-rsa cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_RSA_SHA256, USE_CERT);
+ try_x509_cli("TLS 1.2 with rsa cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_RSA_SHA256, USE_CERT);
+ try_with_key("TLS 1.2 with ecdhe ecdsa cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_RSA_SHA256,
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, USE_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
+ try_x509_cli("TLS 1.2 with ecdhe-rsa-pss cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, USE_CERT);
+ try_with_key("TLS 1.2 with ecdhe-rsa-pss/rsa-pss cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256,
+ &server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, &cli_ca3_rsa_pss_cert, &cli_ca3_rsa_pss_key, USE_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
+
+ try_with_key("TLS 1.2 with ecdhe x25519 ed25519 cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA:-CURVE-ALL:+CURVE-X25519:-SIGN-ALL:+SIGN-EDDSA-ED25519", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_EDDSA_ED25519, GNUTLS_SIGN_EDDSA_ED25519,
+ &server_ca3_eddsa_cert, &server_ca3_eddsa_key, &server_ca3_eddsa_cert, &server_ca3_eddsa_key, USE_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
+
+ try_x509_cli("TLS 1.2 with dhe-rsa ask cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-RSA", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_x509_cli("TLS 1.2 with ecdhe-rsa ask cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_x509_cli("TLS 1.2 with rsa ask cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_with_key("TLS 1.2 with ecdhe ecdsa cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_ECDSA_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, ASK_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
+
+ /** Raw public-key tests **/
+ try_rawpk("TLS 1.2 with dhe-rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-RSA:+CTYPE-ALL", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.2 with ecdhe x25519 rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-CURVE-ALL:+CURVE-X25519:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.2 with ecdhe rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.2 with ecdhe rsa-pss sig no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.2 with ecdhe rsa-pss no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.2 with rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA:+CTYPE-ALL", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN);
+
+ try_rawpk_cli("TLS 1.2 with dhe-rsa cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-RSA:+CTYPE-ALL", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_RSA_SHA256, USE_CERT);
+ try_rawpk_cli("TLS 1.2 with ecdhe-rsa cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_RSA_SHA256, USE_CERT);
+ try_rawpk_cli("TLS 1.2 with rsa cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA:+CTYPE-ALL", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_RSA_SHA256, USE_CERT);
+ try_rawpk_cli("TLS 1.2 with ecdhe-rsa-pss cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:-SIGN-ALL:+SIGN-RSA-PSS-RSAE-SHA256:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, USE_CERT);
+ try_rawpk_cli("TLS 1.2 with dhe-rsa ask cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+DHE-RSA:+CTYPE-ALL", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_rawpk_cli("TLS 1.2 with ecdhe-rsa ask cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+ try_rawpk_cli("TLS 1.2 with rsa ask cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+RSA:+CTYPE-ALL", GNUTLS_KX_RSA, GNUTLS_SIGN_UNKNOWN, GNUTLS_SIGN_UNKNOWN, ASK_CERT);
+
+
+ /** Illegal setups **/
server_priority = "NORMAL:-VERS-ALL:+VERS-TLS1.2:-KX-ALL:+ECDHE-RSA";
try_with_key_fail("TLS 1.2 with rsa cert and only RSA-PSS sig algos in client",
"NORMAL:-VERS-ALL:+VERS-TLS1.2:-SIGN-ALL:+SIGN-RSA-PSS-SHA256:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA512",
diff --git a/tests/tls13-cert-key-exchange.c b/tests/tls13-cert-key-exchange.c
index c0963889ae..8b72b8a8d6 100644
--- a/tests/tls13-cert-key-exchange.c
+++ b/tests/tls13-cert-key-exchange.c
@@ -40,69 +40,82 @@ void doit(void)
global_init();
server_priority = "NORMAL:+ANON-DH:+ANON-ECDH:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519:+SIGN-EDDSA-ED25519";
- try("TLS 1.3 with ffdhe2048 rsa no-cli-cert / anon on server", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.3 with ffdhe2048 rsa no-cli-cert / anon on server", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ /** X.509 tests **/
server_priority = "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519:+SIGN-EDDSA-ED25519";
/* TLS 1.3 no client cert */
- try("TLS 1.3 with ffdhe2048 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.3 with ffdhe3072 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.3 with ffdhe4096 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE4096", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.3 with secp256r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.3 with secp384r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP384R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.3 with secp521r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.3 with x25519 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.3 with ffdhe2048 rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.3 with ffdhe3072 rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.3 with ffdhe4096 rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE4096", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.3 with secp256r1 rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.3 with secp384r1 rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP384R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.3 with secp521r1 rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.3 with x25519 rsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
- try_with_key_ks("TLS 1.3 with secp256r1 ecdsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0, GNUTLS_GROUP_SECP256R1);
+ try_with_key_ks("TLS 1.3 with secp256r1 ecdsa no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, NULL, NULL, 0, GNUTLS_GROUP_SECP256R1, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
/* Test RSA-PSS cert/key combo issues */
- try_with_key_ks("TLS 1.3 with x25519 with rsa-pss-sha256 key no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_GROUP_X25519);
- try_with_key_ks("TLS 1.3 with x25519 with rsa-pss-sha256 key and 1 sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_GROUP_X25519);
- try_with_key_ks("TLS 1.3 with x25519 with rsa-pss-sha256 key and rsa-pss-sha384 first sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:-SIGN-ALL:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_GROUP_X25519);
- try_with_key_ks("TLS 1.3 with x25519 with rsa-pss-sha256 key and rsa-pss-sha512 first sig no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:-SIGN-ALL:+SIGN-RSA-PSS-SHA512:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_GROUP_X25519);
-
- try_with_key_ks("TLS 1.3 with x25519 rsa-pss/rsa-pss no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, NULL, NULL, 0, GNUTLS_GROUP_X25519);
- try_with_key_ks("TLS 1.3 with x25519 ed25519 no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-ECDSA:-CURVE-ALL:+CURVE-X25519:-SIGN-ALL:+SIGN-EDDSA-ED25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_EDDSA_ED25519, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_eddsa_cert, &server_ca3_eddsa_key, NULL, NULL, 0, GNUTLS_GROUP_X25519);
+ try_with_key_ks("TLS 1.3 with x25519 with rsa-pss-sha256 key no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_GROUP_X25519, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+ try_with_key_ks("TLS 1.3 with x25519 with rsa-pss-sha256 key and 1 sig no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_GROUP_X25519, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+ try_with_key_ks("TLS 1.3 with x25519 with rsa-pss-sha256 key and rsa-pss-sha384 first sig no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:-SIGN-ALL:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_GROUP_X25519, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+ try_with_key_ks("TLS 1.3 with x25519 with rsa-pss-sha256 key and rsa-pss-sha512 first sig no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:-SIGN-ALL:+SIGN-RSA-PSS-SHA512:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_rsa_pss2_cert, &server_ca3_rsa_pss2_key, NULL, NULL, 0, GNUTLS_GROUP_X25519, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+
+ try_with_key_ks("TLS 1.3 with x25519 rsa-pss/rsa-pss no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:-SIGN-ALL:+SIGN-RSA-PSS-SHA256", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_SHA256, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_rsa_pss_cert, &server_ca3_rsa_pss_key, NULL, NULL, 0, GNUTLS_GROUP_X25519, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+ try_with_key_ks("TLS 1.3 with x25519 ed25519 no-cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-ECDSA:-CURVE-ALL:+CURVE-X25519:-SIGN-ALL:+SIGN-EDDSA-ED25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_EDDSA_ED25519, GNUTLS_SIGN_UNKNOWN,
+ &server_ca3_eddsa_cert, &server_ca3_eddsa_key, NULL, NULL, 0, GNUTLS_GROUP_X25519, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
/* client authentication */
- try_with_key("TLS 1.3 with rsa-pss cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_rsa_pss_cert, &cli_ca3_rsa_pss_key, USE_CERT);
- try_with_key("TLS 1.3 with rsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, USE_CERT);
- try_with_key("TLS 1.3 with ecdsa cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
- &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, USE_CERT);
- try_with_key("TLS 1.3 with x25519 ed25519 cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA:-CURVE-ALL:+CURVE-X25519:-SIGN-ALL:+SIGN-EDDSA-ED25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_EDDSA_ED25519, GNUTLS_SIGN_EDDSA_ED25519,
- &server_ca3_eddsa_cert, &server_ca3_eddsa_key, &server_ca3_eddsa_cert, &server_ca3_eddsa_key, USE_CERT);
+ try_with_key("TLS 1.3 with rsa-pss cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_RSA_PSS_SHA256,
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_rsa_pss_cert, &cli_ca3_rsa_pss_key, USE_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
+ try_with_key("TLS 1.3 with rsa cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256,
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &cli_ca3_cert, &cli_ca3_key, USE_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
+ try_with_key("TLS 1.3 with ecdsa cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256, GNUTLS_SIGN_ECDSA_SECP256R1_SHA256,
+ &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, &server_ca3_localhost_ecc_cert, &server_ca3_ecc_key, USE_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
+ try_with_key("TLS 1.3 with x25519 ed25519 cli-cert (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-KX-ALL:+ECDHE-RSA:-CURVE-ALL:+CURVE-X25519:-SIGN-ALL:+SIGN-EDDSA-ED25519", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_EDDSA_ED25519, GNUTLS_SIGN_EDDSA_ED25519,
+ &server_ca3_eddsa_cert, &server_ca3_eddsa_key, &server_ca3_eddsa_cert, &server_ca3_eddsa_key, USE_CERT, GNUTLS_CRT_X509, GNUTLS_CRT_X509);
/* TLS 1.3 mis-matching groups */
/* Our policy is to send a key share for the first of each type of groups, so make sure
* the server doesn't support them */
server_priority = "NORMAL:-GROUP-ALL:-VERS-TLS-ALL:+VERS-TLS1.3:+GROUP-FFDHE3072:+GROUP-SECP521R1",
- try_ks("TLS 1.3 with default key share", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_GROUP_FFDHE3072);
- try_ks("TLS 1.3 with ffdhe2048 key share", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_GROUP_FFDHE3072);
- try_ks("TLS 1.3 with ffdhe4096 key share", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE4096:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_GROUP_FFDHE3072);
- try_ks("TLS 1.3 with secp256r1 key share", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_GROUP_SECP521R1);
- try_ks("TLS 1.3 with secp384r1 key share", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP384R1:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_GROUP_SECP521R1);
- try_ks("TLS 1.3 with secp521r1 key share", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_GROUP_SECP521R1);
- try_ks("TLS 1.3 with x25519 -> ffdhe3072 key share", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:+GROUP-SECP384R1:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_GROUP_FFDHE3072);
+ try_x509_ks("TLS 1.3 with default key share (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_GROUP_FFDHE3072);
+ try_x509_ks("TLS 1.3 with ffdhe2048 key share (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_GROUP_FFDHE3072);
+ try_x509_ks("TLS 1.3 with ffdhe4096 key share (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE4096:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_GROUP_FFDHE3072);
+ try_x509_ks("TLS 1.3 with secp256r1 key share (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1:+GROUP-SECP384R1:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_GROUP_SECP521R1);
+ try_x509_ks("TLS 1.3 with secp384r1 key share (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP384R1:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_GROUP_SECP521R1);
+ try_x509_ks("TLS 1.3 with secp521r1 key share (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_GROUP_SECP521R1);
+ try_x509_ks("TLS 1.3 with x25519 -> ffdhe3072 key share (ctype X.509)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:+GROUP-SECP384R1:+GROUP-FFDHE3072", GNUTLS_KX_DHE_RSA, GNUTLS_GROUP_FFDHE3072);
/* TLS 1.2 fallback */
server_priority = "NORMAL:-VERS-ALL:+VERS-TLS1.2:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519:+SIGN-EDDSA-ED25519",
try_with_key_ks("TLS 1.2 fallback with x25519 ed25519 no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:-KX-ALL:+ECDHE-ECDSA:-CURVE-ALL:+CURVE-X25519:-SIGN-ALL:+SIGN-EDDSA-ED25519", GNUTLS_KX_ECDHE_ECDSA, GNUTLS_SIGN_EDDSA_ED25519, GNUTLS_SIGN_UNKNOWN,
- &server_ca3_eddsa_cert, &server_ca3_eddsa_key, NULL, NULL, 0, 0);
- try("TLS 1.2 fallback with secp521r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:-GROUP-ALL:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
- try("TLS 1.2 fallback with ffdhe2048 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:-KX-ALL:+DHE-RSA:-GROUP-ALL:+GROUP-FFDHE2048", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
+ &server_ca3_eddsa_cert, &server_ca3_eddsa_key, NULL, NULL, 0, 0, GNUTLS_CRT_X509, GNUTLS_CRT_UNKNOWN);
+ try_x509("TLS 1.2 fallback with secp521r1 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:-GROUP-ALL:+GROUP-SECP521R1", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_x509("TLS 1.2 fallback with ffdhe2048 rsa no-cli-cert", "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:-KX-ALL:+DHE-RSA:-GROUP-ALL:+GROUP-FFDHE2048", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_SHA256, GNUTLS_SIGN_UNKNOWN);
- /* illegal setups */
+ /** Raw public-key tests **/
+ server_priority = "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.1:+VERS-TLS1.0:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519:+SIGN-EDDSA-ED25519:+CTYPE-ALL";
+
+ try_rawpk("TLS 1.3 with ffdhe2048 rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE2048:+CTYPE-ALL", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.3 with ffdhe3072 rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE3072:+CTYPE-ALL", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.3 with ffdhe4096 rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-FFDHE4096:+CTYPE-ALL", GNUTLS_KX_DHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.3 with secp256r1 rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP256R1:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.3 with secp384r1 rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP384R1:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.3 with secp521r1 rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-SECP521R1:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+ try_rawpk("TLS 1.3 with x25519 rsa no-cli-cert (ctype Raw PK)", "NORMAL:-VERS-ALL:+VERS-TLS1.3:-GROUP-ALL:+GROUP-X25519:+CTYPE-ALL", GNUTLS_KX_ECDHE_RSA, GNUTLS_SIGN_RSA_PSS_RSAE_SHA256, GNUTLS_SIGN_UNKNOWN);
+
+
+ /** Illegal setups **/
server_priority = "NORMAL:-VERS-ALL:+VERS-TLS1.3";
try_with_key_fail("TLS 1.3 with rsa cert and only RSA-PSS sig algos in client",
"NORMAL:-VERS-ALL:+VERS-TLS1.3:-SIGN-ALL:+SIGN-RSA-PSS-SHA256:+SIGN-RSA-PSS-SHA384:+SIGN-RSA-PSS-SHA512",
diff --git a/tests/trustdb-tofu.c b/tests/trustdb-tofu.c
index 85d08886a0..5917fadf1d 100644
--- a/tests/trustdb-tofu.c
+++ b/tests/trustdb-tofu.c
@@ -31,6 +31,8 @@
#include <gnutls/gnutls.h>
#include <unistd.h>
#include "utils.h"
+#include "cert-common.h"
+
/* This will test whether the default public key storage backend
* is operating properly */
@@ -40,7 +42,7 @@ static void tls_log_func(int level, const char *str)
fprintf(stderr, "|<%d>| %s", level, str);
}
-static unsigned char server_cert_pem[] =
+static unsigned char tofu_server_cert_pem[] =
"-----BEGIN CERTIFICATE-----\n"
"MIICVjCCAcGgAwIBAgIERiYdMTALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n"
"VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTIxWhcNMDgwNDE3MTMyOTIxWjA3MRsw\n"
@@ -56,8 +58,8 @@ static unsigned char server_cert_pem[] =
"AwUNBRXwd3riUsMnsxgeSDxYBfJYbDLeohNBsqaPDJb7XailWbMQKfAbFQ8cnOxg\n"
"rOKLUQRWJ0K3HyXRMhbqjdLIaQiCvQLuizo=\n" "-----END CERTIFICATE-----\n";
-const gnutls_datum_t server_cert = { server_cert_pem,
- sizeof(server_cert_pem)
+const gnutls_datum_t tofu_server_cert = { tofu_server_cert_pem,
+ sizeof(tofu_server_cert_pem)
};
static char client_pem[] =
@@ -86,6 +88,7 @@ const gnutls_datum_t client_cert =
void doit(void)
{
gnutls_datum_t der_cert, der_cert2;
+ gnutls_datum_t der_rawpk, der_rawpk2;
int ret;
gnutls_datum_t hash;
char path[512];
@@ -100,8 +103,9 @@ void doit(void)
if (debug)
gnutls_global_set_log_level(2);
+ // X.509 certificates
ret =
- gnutls_pem_base64_decode_alloc("CERTIFICATE", &server_cert,
+ gnutls_pem_base64_decode_alloc("CERTIFICATE", &tofu_server_cert,
&der_cert);
if (ret < 0) {
fail("base64 decoding\n");
@@ -116,10 +120,27 @@ void doit(void)
goto fail;
}
+ // Raw public keys
+ ret =
+ gnutls_pem_base64_decode_alloc("PUBLIC KEY", &rawpk_public_key1,
+ &der_rawpk);
+ if (ret < 0) {
+ fail("base64 decoding\n");
+ goto fail;
+ }
+
+ ret =
+ gnutls_pem_base64_decode_alloc("PUBLIC KEY", &rawpk_public_key2,
+ &der_rawpk2);
+ if (ret < 0) {
+ fail("base64 decoding\n");
+ goto fail;
+ }
+
remove(HOSTS_FILE);
remove(TMP_FILE);
- /* verify whether the stored hash verification succeeeds */
+ /* verify whether the stored hash verification succeeds */
ret = gnutls_store_commitment(TMP_FILE, NULL, "localhost", "https",
GNUTLS_DIG_SHA1, &hash, 0, GNUTLS_SCOMMIT_FLAG_ALLOW_BROKEN);
if (ret != 0) {
@@ -175,7 +196,8 @@ void doit(void)
success("Commitment from homedir verification: passed\n");
#endif
- /* verify whether the stored pubkey verification succeeeds */
+ /* verify whether the stored pubkey verification succeeds */
+ // First we test regular X.509 certs
ret = gnutls_store_pubkey(TMP_FILE, NULL, "localhost", "https",
GNUTLS_CRT_X509, &der_cert, 0, 0);
if (ret != 0) {
@@ -184,14 +206,14 @@ void doit(void)
}
if (debug)
- success("Public key storage: passed\n");
+ success("Public key storage (from cert): passed\n");
ret =
gnutls_verify_stored_pubkey(TMP_FILE, NULL, "localhost",
"https", GNUTLS_CRT_X509,
&der_cert, 0);
if (ret != 0) {
- fail("pubkey verification: %s\n", gnutls_strerror(ret));
+ fail("pubkey verification (from cert): %s\n", gnutls_strerror(ret));
goto fail;
}
@@ -200,7 +222,44 @@ void doit(void)
"https", GNUTLS_CRT_X509,
&der_cert2, 0);
if (ret == 0) {
- fail("verification succeed when shouldn't!\n");
+ fail("verification succeeded when shouldn't!\n");
+ goto fail;
+ }
+ if (ret != GNUTLS_E_CERTIFICATE_KEY_MISMATCH) {
+ fail("Wrong error code returned: %s!\n",
+ gnutls_strerror(ret));
+ goto fail;
+ }
+
+ if (debug)
+ success("Public key verification (from cert): passed\n");
+
+ // Secondly we test raw public keys
+ ret = gnutls_store_pubkey(TMP_FILE, NULL, "localhost", "https",
+ GNUTLS_CRT_RAWPK, &der_rawpk, 0, 0);
+ if (ret != 0) {
+ fail("storage: %s\n", gnutls_strerror(ret));
+ goto fail;
+ }
+
+ if (debug)
+ success("Public key storage (from raw pk): passed\n");
+
+ ret =
+ gnutls_verify_stored_pubkey(TMP_FILE, NULL, "localhost",
+ "https", GNUTLS_CRT_RAWPK,
+ &der_rawpk, 0);
+ if (ret != 0) {
+ fail("pubkey verification (from raw pk): %s\n", gnutls_strerror(ret));
+ goto fail;
+ }
+
+ ret =
+ gnutls_verify_stored_pubkey(TMP_FILE, NULL, "localhost",
+ "https", GNUTLS_CRT_RAWPK,
+ &der_rawpk2, 0);
+ if (ret == 0) {
+ fail("verification succeeded when shouldn't!\n");
goto fail;
}
if (ret != GNUTLS_E_CERTIFICATE_KEY_MISMATCH) {
@@ -210,7 +269,7 @@ void doit(void)
}
if (debug)
- success("Public key verification: passed\n");
+ success("Public key verification (from raw pk): passed\n");
remove(HOSTS_FILE);
remove(TMP_FILE);
@@ -219,6 +278,8 @@ void doit(void)
gnutls_global_deinit();
gnutls_free(der_cert.data);
gnutls_free(der_cert2.data);
+ gnutls_free(der_rawpk.data);
+ gnutls_free(der_rawpk2.data);
return;
fail: