diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | doc/cha-cert-auth2.texi | 3 | ||||
-rw-r--r-- | doc/cha-gtls-app.texi | 4 | ||||
-rw-r--r-- | doc/cha-tokens.texi | 4 | ||||
-rw-r--r-- | lib/gnutls_x509.c | 85 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 15 | ||||
-rw-r--r-- | lib/libgnutls.map | 2 |
7 files changed, 104 insertions, 11 deletions
@@ -18,6 +18,8 @@ This makes it consistent with verification with GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_R flag. ** API and ABI modifications: +gnutls_certificate_set_x509_key_mem2: Added +gnutls_certificate_set_x509_key_file2: Added gnutls_sign_algorithm_get_client: Added GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA: Added diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi index d66558ea44..762821e72e 100644 --- a/doc/cha-cert-auth2.texi +++ b/doc/cha-cert-auth2.texi @@ -328,7 +328,8 @@ import plain or encrypted keys and will auto-detect the encrypted key format. @showfuncdesc{gnutls_x509_privkey_import2} Any keys imported using those functions can be imported to a certificate -credentials structure using @funcref{gnutls_certificate_set_key}. +credentials structure using @funcref{gnutls_certificate_set_key}, or alternatively +they can be directly imported using @funcref{gnutls_certificate_set_x509_key_file2}. @subsubheading @acronym{PKCS} #8 structures @cindex PKCS #8 diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi index 0f264def59..78fc90a162 100644 --- a/doc/cha-gtls-app.texi +++ b/doc/cha-gtls-app.texi @@ -421,11 +421,11 @@ certificate certifies the one before it. The trusted authority's certificate need not to be included since the peer should possess it already. -@showfuncC{gnutls_certificate_set_x509_key_mem,gnutls_certificate_set_x509_key,gnutls_certificate_set_x509_key_file} +@showfuncC{gnutls_certificate_set_x509_key_mem2,gnutls_certificate_set_x509_key,gnutls_certificate_set_x509_key_file2} @showfuncC{gnutls_certificate_set_openpgp_key_mem,gnutls_certificate_set_openpgp_key,gnutls_certificate_set_openpgp_key_file} -Note however, that since functions like @funcref{gnutls_certificate_set_x509_key_file} +Note however, that since functions like @funcref{gnutls_certificate_set_x509_key_file2} may accept URLs that specify objects stored in token, another important function is @funcref{gnutls_certificate_set_pin_function}. That allows setting a callback function to retrieve a PIN if the input keys are diff --git a/doc/cha-tokens.texi b/doc/cha-tokens.texi index 348996a4d6..09be6e5d20 100644 --- a/doc/cha-tokens.texi +++ b/doc/cha-tokens.texi @@ -357,7 +357,7 @@ session, as shown in @ref{ex:pkcs11-client}. In addition the following functions can be used to load PKCS #11 key and certificates by specifying a PKCS #11 URL instead of a filename. -@showfuncB{gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_x509_key_file} +@showfuncB{gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_x509_key_file2} @showfuncdesc{gnutls_certificate_set_x509_system_trust} @include invoke-p11tool.texi @@ -440,7 +440,7 @@ done using @funcref{gnutls_tpm_privkey_generate}. @subsubheading Importing keys The TPM keys can be used directly by the abstract key types and do not require -any special structures. Moreover functions like @funcref{gnutls_certificate_set_x509_key_file} +any special structures. Moreover functions like @funcref{gnutls_certificate_set_x509_key_file2} can access TPM URLs. @showfuncB{gnutls_privkey_import_tpm_raw,gnutls_pubkey_import_tpm_raw} diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index bbcd84a532..acdd5b9236 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -632,7 +632,8 @@ read_cert_mem (gnutls_certificate_credentials_t res, const void *cert, */ static int read_key_mem (gnutls_certificate_credentials_t res, - const void *key, int key_size, gnutls_x509_crt_fmt_t type) + const void *key, int key_size, gnutls_x509_crt_fmt_t type, + const char* pass, unsigned int flags) { int ret; gnutls_datum_t tmp; @@ -653,7 +654,7 @@ read_key_mem (gnutls_certificate_credentials_t res, if (res->pin.cb) gnutls_privkey_set_pin_function(privkey, res->pin.cb, res->pin.data); - ret = gnutls_privkey_import_x509_raw (privkey, &tmp, type, NULL, 0); + ret = gnutls_privkey_import_x509_raw (privkey, &tmp, type, pass, flags); if (ret < 0) { gnutls_assert (); @@ -912,7 +913,8 @@ read_cert_file (gnutls_certificate_credentials_t res, */ static int read_key_file (gnutls_certificate_credentials_t res, - const char *keyfile, gnutls_x509_crt_fmt_t type) + const char *keyfile, gnutls_x509_crt_fmt_t type, const char* pass, + unsigned int flags) { int ret; size_t size; @@ -934,7 +936,7 @@ read_key_file (gnutls_certificate_credentials_t res, return GNUTLS_E_FILE_ERROR; } - ret = read_key_mem (res, data, size, type); + ret = read_key_mem (res, data, size, type, pass, flags); free (data); return ret; @@ -970,12 +972,49 @@ gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res, const gnutls_datum_t * key, gnutls_x509_crt_fmt_t type) { + return gnutls_certificate_set_x509_key_mem2(res, cert, key, type, NULL, 0); +} + +/** + * gnutls_certificate_set_x509_key_mem2: + * @res: is a #gnutls_certificate_credentials_t structure. + * @cert: contains a certificate list (path) for the specified private key + * @key: is the private key, or %NULL + * @type: is PEM or DER + * @pass: is the key's password + * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t + * + * This function sets a certificate/private key pair in the + * gnutls_certificate_credentials_t structure. This function may be called + * more than once, in case multiple keys/certificates exist for the + * server. + * + * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates + * is supported. This means that certificates intended for signing cannot + * be used for ciphersuites that require encryption. + * + * If the certificate and the private key are given in PEM encoding + * then the strings that hold their values must be null terminated. + * + * The @key may be %NULL if you are using a sign callback, see + * gnutls_sign_callback_set(). + * + * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code. + **/ +int +gnutls_certificate_set_x509_key_mem2 (gnutls_certificate_credentials_t res, + const gnutls_datum_t * cert, + const gnutls_datum_t * key, + gnutls_x509_crt_fmt_t type, + const char* pass, + unsigned int flags) +{ int ret; /* this should be first */ if ((ret = read_key_mem (res, key ? key->data : NULL, - key ? key->size : 0, type)) < 0) + key ? key->size : 0, type, pass, flags)) < 0) return ret; if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0) @@ -1306,11 +1345,45 @@ gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res, const char *keyfile, gnutls_x509_crt_fmt_t type) { + return gnutls_certificate_set_x509_key_file2(res, certfile, keyfile, type, NULL, 0); +} + +/** + * gnutls_certificate_set_x509_key_file2: + * @res: is a #gnutls_certificate_credentials_t structure. + * @certfile: is a file that containing the certificate list (path) for + * the specified private key, in PKCS7 format, or a list of certificates + * @keyfile: is a file that contains the private key + * @type: is PEM or DER + * @pass: is the password of the key + * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t + * + * This function sets a certificate/private key pair in the + * gnutls_certificate_credentials_t structure. This function may be + * called more than once, in case multiple keys/certificates exist for + * the server. For clients that need to send more than its own end + * entity certificate, e.g., also an intermediate CA cert, then the + * @certfile must contain the ordered certificate chain. + * + * This function can also accept URLs at @keyfile and @certfile. In that case it + * will import the private key and certificate indicated by the URLs. Note + * that the supported URLs are the ones indicated by gnutls_url_is_supported(). + * + * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code. + **/ +int +gnutls_certificate_set_x509_key_file2 (gnutls_certificate_credentials_t res, + const char *certfile, + const char *keyfile, + gnutls_x509_crt_fmt_t type, + const char* pass, + unsigned int flags) +{ int ret; /* this should be first */ - if ((ret = read_key_file (res, keyfile, type)) < 0) + if ((ret = read_key_file (res, keyfile, type, pass, flags)) < 0) return ret; if ((ret = read_cert_file (res, certfile, type)) < 0) diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 5a02dee73c..221208ee3f 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1264,11 +1264,26 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session); const char *keyfile, gnutls_x509_crt_fmt_t type); + int + gnutls_certificate_set_x509_key_file2 (gnutls_certificate_credentials_t + res, const char *certfile, + const char *keyfile, + gnutls_x509_crt_fmt_t type, + const char* pass, + unsigned int flags); + int gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res, const gnutls_datum_t * cert, const gnutls_datum_t * key, gnutls_x509_crt_fmt_t type); + int gnutls_certificate_set_x509_key_mem2 (gnutls_certificate_credentials_t + res, const gnutls_datum_t * cert, + const gnutls_datum_t * key, + gnutls_x509_crt_fmt_t type, + const char* pass, + unsigned int flags); + void gnutls_certificate_send_x509_rdn_sequence (gnutls_session_t session, int status); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 334db47fa7..29e243f076 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -904,6 +904,8 @@ GNUTLS_3_1_0 { gnutls_privkey_sign_raw_data; gnutls_privkey_status; gnutls_sign_algorithm_get_client; + gnutls_certificate_set_x509_key_mem2; + gnutls_certificate_set_x509_key_file2; } GNUTLS_3_0_0; GNUTLS_PRIVATE { |