diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-03-16 20:47:20 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-03-16 20:54:56 +0100 |
commit | a8265d9832e5d0bfb7d008cdd144637a376f06ba (patch) | |
tree | b2cc474247dcc7e287a59161222646bb5a904ae2 | |
parent | ca57ed4ddb4bcd503c1755c4f80e4a1803d2254a (diff) | |
download | gnutls-a8265d9832e5d0bfb7d008cdd144637a376f06ba.tar.gz |
gnutls_pubkey_t and gnutls_privkey_t can import either an openpgp subkey or a master key.
-rw-r--r-- | lib/gnutls_privkey.c | 21 | ||||
-rw-r--r-- | lib/gnutls_pubkey.c | 45 | ||||
-rw-r--r-- | lib/includes/gnutls/abstract.h | 1 | ||||
-rw-r--r-- | lib/openpgp/gnutls_openpgp.c | 7 | ||||
-rw-r--r-- | tests/openpgp-auth.c | 361 |
5 files changed, 228 insertions, 207 deletions
diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index 201686d225..886eb99e34 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -375,7 +375,8 @@ int ret; * #gnutls_privkey_t structure. * * The #gnutls_openpgp_privkey_t object must not be deallocated - * during the lifetime of this structure. + * during the lifetime of this structure. The subkey set as + * preferred will be used, or the master key otherwise. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. @@ -399,12 +400,20 @@ gnutls_openpgp_keyid_t keyid; pkey->type = GNUTLS_PRIVKEY_OPENPGP; ret = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid); - if (ret < 0) - return gnutls_assert_val(ret); - - idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid); + if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR) + { + pkey->pk_algorithm = gnutls_openpgp_privkey_get_pk_algorithm(key, NULL); + } + else + { + if (ret < 0) + return gnutls_assert_val(ret); + + idx = gnutls_openpgp_privkey_get_subkey_idx (key, keyid); - pkey->pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL); + pkey->pk_algorithm = gnutls_openpgp_privkey_get_subkey_pk_algorithm (key, idx, NULL); + } + pkey->flags = flags; return 0; diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c index b4deb73eca..0e788b2c49 100644 --- a/lib/gnutls_pubkey.c +++ b/lib/gnutls_pubkey.c @@ -327,7 +327,8 @@ gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key, * @flags: should be zero * * This function will import the given public key to the abstract - * #gnutls_pubkey_t structure. + * #gnutls_pubkey_t structure. The subkey set as preferred will be + * imported or the master key otherwise. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. @@ -335,32 +336,50 @@ gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t key, int gnutls_pubkey_import_openpgp (gnutls_pubkey_t key, gnutls_openpgp_crt_t crt, - gnutls_openpgp_keyid_t keyid, unsigned int flags) { - int ret; + int ret, idx; uint32_t kid32[2]; + uint32_t *k; + gnutls_openpgp_keyid_t keyid; ret = gnutls_openpgp_crt_get_preferred_key_id (crt, keyid); - if (ret < 0) + if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR) { - gnutls_assert (); - return ret; + key->pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm(crt, NULL); + key->pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (crt, &key->bits); + + ret = gnutls_openpgp_crt_get_key_usage (crt, &key->key_usage); + if (ret < 0) + key->key_usage = 0; + + k = NULL; } + else + { + if (ret < 0) + { + gnutls_assert (); + return ret; + } - KEYID_IMPORT (kid32, keyid); + KEYID_IMPORT (kid32, keyid); + k = kid32; - key->pk_algorithm = gnutls_openpgp_crt_get_pk_algorithm (crt, &key->bits); + idx = gnutls_openpgp_crt_get_subkey_idx (crt, keyid); - ret = gnutls_openpgp_crt_get_key_usage (crt, &key->key_usage); - if (ret < 0) - key->key_usage = 0; + ret = gnutls_openpgp_crt_get_subkey_usage (crt, idx, &key->key_usage); + if (ret < 0) + key->key_usage = 0; + + key->pk_algorithm = gnutls_openpgp_crt_get_subkey_pk_algorithm (crt, idx, NULL); + } switch (key->pk_algorithm) { case GNUTLS_PK_RSA: ret = - _gnutls_openpgp_crt_get_mpis (crt, kid32, key->params, + _gnutls_openpgp_crt_get_mpis (crt, k, key->params, &key->params_size); if (ret < 0) { @@ -370,7 +389,7 @@ gnutls_pubkey_import_openpgp (gnutls_pubkey_t key, break; case GNUTLS_PK_DSA: ret = - _gnutls_openpgp_crt_get_mpis (crt, kid32, key->params, + _gnutls_openpgp_crt_get_mpis (crt, k, key->params, &key->params_size); if (ret < 0) { diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h index 6791b8299d..8bc46c6d90 100644 --- a/lib/includes/gnutls/abstract.h +++ b/lib/includes/gnutls/abstract.h @@ -25,7 +25,6 @@ int gnutls_pubkey_import_pkcs11 (gnutls_pubkey_t pkey, gnutls_pkcs11_obj_t crt, unsigned int flags); int gnutls_pubkey_import_openpgp (gnutls_pubkey_t pkey, gnutls_openpgp_crt_t crt, - gnutls_openpgp_keyid_t keyid, unsigned int flags); int gnutls_pubkey_import_privkey (gnutls_pubkey_t key, gnutls_privkey_t pkey, diff --git a/lib/openpgp/gnutls_openpgp.c b/lib/openpgp/gnutls_openpgp.c index bc7cb1c863..ba7cd2740a 100644 --- a/lib/openpgp/gnutls_openpgp.c +++ b/lib/openpgp/gnutls_openpgp.c @@ -126,7 +126,9 @@ _gnutls_openpgp_raw_crt_to_gcert (gnutls_cert * gcert, * called more than once (in case multiple keys/certificates exist * for the server). * - * With this function the subkeys of the certificate are not used. + * Note that this function requires that the preferred key ids have + * been set and be used. See gnutls_openpgp_crt_set_preferred_key_id(). + * Otherwise the master key will be used. * * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned, * otherwise an error code is returned. @@ -139,6 +141,7 @@ gnutls_certificate_set_openpgp_key (gnutls_certificate_credentials_t res, int ret; gnutls_privkey_t privkey; gnutls_cert *ccert; + /* this should be first */ ret = gnutls_privkey_init (&privkey); @@ -147,7 +150,7 @@ gnutls_certificate_set_openpgp_key (gnutls_certificate_credentials_t res, gnutls_assert (); return ret; } - + ret = gnutls_privkey_import_openpgp (privkey, pkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); diff --git a/tests/openpgp-auth.c b/tests/openpgp-auth.c index 2622f7749d..37c967cf99 100644 --- a/tests/openpgp-auth.c +++ b/tests/openpgp-auth.c @@ -43,12 +43,7 @@ static const char message[] = "Hello, brave GNU world!"; /* The OpenPGP key pair for use and the key ID in those keys. */ static const char pub_key_file[] = "../guile/tests/openpgp-pub.asc"; static const char priv_key_file[] = "../guile/tests/openpgp-sec.asc"; -static const char *key_id = NULL - /* FIXME: The values below don't work as expected. */ - /* "auto" */ - /* "bd572cdcccc07c35" */ ; - -static const char rsa_params_file[] = "../guile/tests/rsa-parameters.pem"; +static const char *key_id = NULL; static void log_message (int level, const char *message) @@ -60,205 +55,201 @@ log_message (int level, const char *message) void doit () { - int err; + int err, i; int sockets[2]; const char *srcdir; - char *pub_key_path, *priv_key_path, *rsa_params_path; + char *pub_key_path, *priv_key_path; pid_t child; gnutls_global_init (); srcdir = getenv ("srcdir") ? getenv ("srcdir") : "."; - if (debug) - { - gnutls_global_set_log_level (10); - gnutls_global_set_log_function (log_message); - } - - err = socketpair (PF_UNIX, SOCK_STREAM, 0, sockets); - if (err != 0) - fail ("socketpair %s\n", strerror (errno)); - - pub_key_path = alloca (strlen (srcdir) + strlen (pub_key_file) + 2); - strcpy (pub_key_path, srcdir); - strcat (pub_key_path, "/"); - strcat (pub_key_path, pub_key_file); - - priv_key_path = alloca (strlen (srcdir) + strlen (priv_key_file) + 2); - strcpy (priv_key_path, srcdir); - strcat (priv_key_path, "/"); - strcat (priv_key_path, priv_key_file); - - rsa_params_path = alloca (strlen (srcdir) + strlen (rsa_params_file) + 2); - strcpy (rsa_params_path, srcdir); - strcat (rsa_params_path, "/"); - strcat (rsa_params_path, rsa_params_file); - - child = fork (); - if (child == -1) - fail ("fork %s\n", strerror (errno)); - - if (child == 0) + for (i = 0; i < 3; i++) { - /* Child process (client). */ - gnutls_session_t session; - gnutls_certificate_credentials_t cred; - ssize_t sent; - - if (debug) - printf ("client process %i\n", getpid ()); - - err = gnutls_init (&session, GNUTLS_CLIENT); - if (err != 0) - fail ("client session %d\n", err); - - gnutls_priority_set_direct (session, "NORMAL:+CTYPE-OPENPGP:-CTYPE-X.509", NULL); - gnutls_transport_set_ptr (session, - (gnutls_transport_ptr_t) (intptr_t) - sockets[0]); - err = gnutls_certificate_allocate_credentials (&cred); - if (err != 0) - fail ("client credentials %d\n", err); - - err = - gnutls_certificate_set_openpgp_key_file2 (cred, - pub_key_path, priv_key_path, - key_id, - GNUTLS_OPENPGP_FMT_BASE64); - if (err != 0) - fail ("client openpgp keys %d\n", err); - - err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred); - if (err != 0) - fail ("client credential_set %d\n", err); - - gnutls_dh_set_prime_bits (session, 1024); - - err = gnutls_handshake (session); - if (err != 0) - fail ("client handshake %s (%d) \n", gnutls_strerror(err), err); - else if (debug) - printf ("client handshake successful\n"); - - sent = gnutls_record_send (session, message, sizeof (message)); - if (sent != sizeof (message)) - fail ("client sent %li vs. %li\n", - (long) sent, (long) sizeof (message)); - - err = gnutls_bye (session, GNUTLS_SHUT_RDWR); - if (err != 0) - fail ("client bye %d\n", err); + if (i == 0) + key_id = NULL; /* try using the master key */ + else if (i == 1) + key_id = "auto"; /* test auto */ + else if (i == 2) + key_id = "f30fd423c143e7ba"; if (debug) - printf ("client done\n"); - } - else - { - /* Parent process (server). */ - gnutls_session_t session; - gnutls_dh_params_t dh_params; - gnutls_rsa_params_t rsa_params; - gnutls_certificate_credentials_t cred; - char greetings[sizeof (message) * 2]; - ssize_t received; - pid_t done; - int status; - size_t rsa_size; - gnutls_datum_t rsa_data; - const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) }; - - if (debug) - printf ("server process %i (child %i)\n", getpid (), child); - - err = gnutls_init (&session, GNUTLS_SERVER); - if (err != 0) - fail ("server session %d\n", err); - - gnutls_priority_set_direct (session, "NORMAL:+CTYPE-OPENPGP:-CTYPE-X.509", NULL); - gnutls_transport_set_ptr (session, - (gnutls_transport_ptr_t) (intptr_t) - sockets[1]); - - err = gnutls_certificate_allocate_credentials (&cred); - if (err != 0) - fail ("server credentials %d\n", err); - - err = - gnutls_certificate_set_openpgp_key_file2 (cred, - pub_key_path, priv_key_path, - key_id, - GNUTLS_OPENPGP_FMT_BASE64); - if (err != 0) - fail ("server openpgp keys %d\n", err); - - err = gnutls_dh_params_init (&dh_params); - if (err) - fail ("server DH params init %d\n", err); - - err = - gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM); - if (err) - fail ("server DH params generate %d\n", err); - - gnutls_certificate_set_dh_params (cred, dh_params); - - rsa_data.data = - (unsigned char *) read_binary_file (rsa_params_path, &rsa_size); - if (rsa_data.data == NULL) - fail ("server rsa params error\n"); - rsa_data.size = rsa_size; - - err = gnutls_rsa_params_init (&rsa_params); - if (err) - fail ("server RSA params init %d\n", err); - - err = gnutls_rsa_params_import_pkcs1 (rsa_params, &rsa_data, - GNUTLS_X509_FMT_PEM); - if (err) - fail ("server RSA params import %d\n", err); - - gnutls_certificate_set_rsa_export_params (cred, rsa_params); - - err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred); - if (err != 0) - fail ("server credential_set %d\n", err); - - gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUIRE); - - err = gnutls_handshake (session); - if (err != 0) - fail ("server handshake %s (%d) \n", gnutls_strerror(err), err); - - received = gnutls_record_recv (session, greetings, sizeof (greetings)); - if (received != sizeof (message) - || memcmp (greetings, message, sizeof (message))) - fail ("server received %li vs. %li\n", - (long) received, (long) sizeof (message)); + { + gnutls_global_set_log_level (10); + gnutls_global_set_log_function (log_message); + } - err = gnutls_bye (session, GNUTLS_SHUT_RDWR); + err = socketpair (PF_UNIX, SOCK_STREAM, 0, sockets); if (err != 0) - fail ("server bye %s (%d) \n", gnutls_strerror(err), err); + fail ("socketpair %s\n", strerror (errno)); - if (debug) - printf ("server done\n"); + pub_key_path = alloca (strlen (srcdir) + strlen (pub_key_file) + 2); + strcpy (pub_key_path, srcdir); + strcat (pub_key_path, "/"); + strcat (pub_key_path, pub_key_file); - done = wait (&status); - if (done < 0) - fail ("wait %s\n", strerror (errno)); + priv_key_path = alloca (strlen (srcdir) + strlen (priv_key_file) + 2); + strcpy (priv_key_path, srcdir); + strcat (priv_key_path, "/"); + strcat (priv_key_path, priv_key_file); - if (done != child) - fail ("who's that?! %d\n", done); + child = fork (); + if (child == -1) + fail ("fork %s\n", strerror (errno)); - if (WIFEXITED (status)) + if (child == 0) { - if (WEXITSTATUS (status) != 0) - fail ("child exited with status %d\n", WEXITSTATUS (status)); + /* Child process (client). */ + gnutls_session_t session; + gnutls_certificate_credentials_t cred; + ssize_t sent; + + if (debug) + printf ("client process %i\n", getpid ()); + + err = gnutls_init (&session, GNUTLS_CLIENT); + if (err != 0) + fail ("client session %d\n", err); + + gnutls_priority_set_direct (session, + "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP", + NULL); + gnutls_transport_set_ptr (session, + (gnutls_transport_ptr_t) (intptr_t) + sockets[0]); + + err = gnutls_certificate_allocate_credentials (&cred); + if (err != 0) + fail ("client credentials %d\n", err); + + err = + gnutls_certificate_set_openpgp_key_file2 (cred, + pub_key_path, + priv_key_path, key_id, + GNUTLS_OPENPGP_FMT_BASE64); + if (err != 0) + fail ("client openpgp keys %s\n", gnutls_strerror (err)); + + err = + gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred); + if (err != 0) + fail ("client credential_set %d\n", err); + + gnutls_dh_set_prime_bits (session, 1024); + + err = gnutls_handshake (session); + if (err != 0) + fail ("client handshake %s (%d) \n", gnutls_strerror (err), err); + else if (debug) + printf ("client handshake successful\n"); + + sent = gnutls_record_send (session, message, sizeof (message)); + if (sent != sizeof (message)) + fail ("client sent %li vs. %li\n", + (long) sent, (long) sizeof (message)); + + err = gnutls_bye (session, GNUTLS_SHUT_RDWR); + if (err != 0) + fail ("client bye %d\n", err); + + if (debug) + printf ("client done\n"); } - else if (WIFSIGNALED (status)) - fail ("child stopped by signal %d\n", WTERMSIG (status)); else - fail ("child failed: %d\n", status); + { + /* Parent process (server). */ + gnutls_session_t session; + gnutls_dh_params_t dh_params; + gnutls_certificate_credentials_t cred; + char greetings[sizeof (message) * 2]; + ssize_t received; + pid_t done; + int status; + const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) }; + + if (debug) + printf ("server process %i (child %i)\n", getpid (), child); + + err = gnutls_init (&session, GNUTLS_SERVER); + if (err != 0) + fail ("server session %d\n", err); + + gnutls_priority_set_direct (session, + "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP", + NULL); + gnutls_transport_set_ptr (session, + (gnutls_transport_ptr_t) (intptr_t) + sockets[1]); + + err = gnutls_certificate_allocate_credentials (&cred); + if (err != 0) + fail ("server credentials %d\n", err); + + err = + gnutls_certificate_set_openpgp_key_file2 (cred, + pub_key_path, + priv_key_path, key_id, + GNUTLS_OPENPGP_FMT_BASE64); + if (err != 0) + fail ("server openpgp keys %s\n", gnutls_strerror (err)); + + err = gnutls_dh_params_init (&dh_params); + if (err) + fail ("server DH params init %d\n", err); + + err = + gnutls_dh_params_import_pkcs3 (dh_params, &p3, + GNUTLS_X509_FMT_PEM); + if (err) + fail ("server DH params generate %d\n", err); + + gnutls_certificate_set_dh_params (cred, dh_params); + + err = + gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred); + if (err != 0) + fail ("server credential_set %d\n", err); + + gnutls_certificate_server_set_request (session, + GNUTLS_CERT_REQUIRE); + + err = gnutls_handshake (session); + if (err != 0) + fail ("server handshake %s (%d) \n", gnutls_strerror (err), err); + + received = + gnutls_record_recv (session, greetings, sizeof (greetings)); + if (received != sizeof (message) + || memcmp (greetings, message, sizeof (message))) + fail ("server received %li vs. %li\n", (long) received, + (long) sizeof (message)); + + err = gnutls_bye (session, GNUTLS_SHUT_RDWR); + if (err != 0) + fail ("server bye %s (%d) \n", gnutls_strerror (err), err); + + if (debug) + printf ("server done\n"); + + done = wait (&status); + if (done < 0) + fail ("wait %s\n", strerror (errno)); + + if (done != child) + fail ("who's that?! %d\n", done); + + if (WIFEXITED (status)) + { + if (WEXITSTATUS (status) != 0) + fail ("child exited with status %d\n", WEXITSTATUS (status)); + } + else if (WIFSIGNALED (status)) + fail ("child stopped by signal %d\n", WTERMSIG (status)); + else + fail ("child failed: %d\n", status); + } + } } |