]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added new signing callback in gnutls_privkey_t.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 7 Oct 2011 15:47:09 +0000 (17:47 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Fri, 7 Oct 2011 16:00:58 +0000 (18:00 +0200)
NEWS
doc/cha-auth.texi
doc/cha-cert-auth.texi
lib/auth/cert.c
lib/gnutls_cert.c
lib/gnutls_privkey.c
lib/gnutls_x509.c
lib/includes/gnutls/abstract.h
lib/includes/gnutls/compat.h
lib/includes/gnutls/gnutls.h.in
lib/libgnutls.map

diff --git a/NEWS b/NEWS
index b240191cf3b8453111ad80fcb2020c29f394a342..b01bbb4bc637fc63e30cce808ed1dfe18c4a95a6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -24,8 +24,13 @@ Used to get the PKIX Authority Information Access (AIA) field.
 
 ** libgnutls: gnutls_x509_crt_print supports printing AIA fields.
 
+** libgnutls: Added ability to gnutls_privkey_t to operate with
+signing callback function.
+
 ** API and ABI modifications:
 gnutls_x509_crt_get_authority_info_access (x509.h): Added function.
+gnutls_privkey_import_ext: Added function.
+gnutls_certificate_set_key: Added function.
 gnutls_info_access_what_t (x509.h): Added enum.
 GNUTLS_OID_AIA (x509.h): Added symbol.
 GNUTLS_OID_AD_OCSP (x509.h): Added symbol.
index 1cfa08d595b5d6021674141ee08589859a4ebb00..fcbe26bce1c7a3d17ad2c31dbe618574c47572a0 100644 (file)
@@ -83,7 +83,8 @@ certificate certifies the one before it. The trusted authority's
 certificate need not to be included, since the peer should possess it
 already.
 
-@showfuncE{gnutls_certificate_set_x509_key,gnutls_certificate_set_x509_key_mem,gnutls_certificate_set_openpgp_key,gnutls_certificate_set_openpgp_key_file,gnutls_certificate_set_openpgp_key_mem}
+@showfuncD{gnutls_certificate_set_x509_key_mem,gnutls_certificate_set_openpgp_key,gnutls_certificate_set_openpgp_key_file,gnutls_certificate_set_openpgp_key_mem}
+@showfuncB{gnutls_certificate_set_x509_key,gnutls_certificate_set_key}
 
 @showfuncdesc{gnutls_certificate_set_x509_key_file}
 
index f1309bd7209c64d0296f0e2901d8661595f0b510..26a23e7eb1b827092adbbfc546182234322f6f3b 100644 (file)
@@ -588,7 +588,7 @@ are not extractable.
 
 @showfuncdesc{gnutls_privkey_import_x509}
 
-@showfuncB{gnutls_privkey_import_openpgp,gnutls_privkey_import_pkcs11}
+@showfuncC{gnutls_privkey_import_openpgp,gnutls_privkey_import_pkcs11,gnutls_privkey_import_ext}
 @showfuncdesc{gnutls_privkey_get_pk_algorithm}
 @showfuncdesc{gnutls_privkey_get_type}
 
index 2deb5e2b641439094607851d1bdec5f52e6b6bc9..fddc10249adb8421620058da53e6684ba1858298 100644 (file)
@@ -620,6 +620,10 @@ call_get_cert_callback (gnutls_session_t session,
             }
         }
       break;
+    default:
+      gnutls_assert();
+      ret = GNUTLS_E_INVALID_REQUEST;
+      goto cleanup;
     }
 
   _gnutls_selected_certs_set (session, local_certs,
index e72a662e43f504c212b6e166c8907e61b7e61504..802f671672b72c020d746268f098fb619c20ed64 100644 (file)
@@ -790,7 +790,7 @@ gnutls_certificate_activation_time_peers (gnutls_session_t session)
  * can be used to store application-specific data needed in the
  * callback function.  See also gnutls_sign_callback_get().
  *
- * Deprecated: Use the PKCS 11 interfaces instead.
+ * Deprecated: Use the PKCS 11 or #gnutls_privkey_t interfacess instead.
  */
 void
 gnutls_sign_callback_set (gnutls_session_t session,
index 87ed1c17fec6bcfdd55d00e387f3fbe34a5fb69d..f572ce5e924e65b18b37019f3919400507ddc4de 100644 (file)
@@ -47,6 +47,11 @@ struct gnutls_privkey_st
 #ifdef ENABLE_OPENPGP
     gnutls_openpgp_privkey_t openpgp;
 #endif
+    struct {
+      gnutls_privkey_sign_func sign_func;
+      gnutls_privkey_decrypt_func decrypt_func;
+      void* userdata;
+    } ext;
   } key;
 
   unsigned int flags;
@@ -101,6 +106,10 @@ gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, unsigned int *bits)
       if (bits)
         *bits = _gnutls_mpi_get_nbits (key->key.x509->params.params[0]);
       return gnutls_x509_privkey_get_pk_algorithm (key->key.x509);
+    case GNUTLS_PRIVKEY_EXT:
+      if (bits)
+        *bits = 0;
+      return key->pk_algorithm;
     default:
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
@@ -359,6 +368,54 @@ int ret;
 
 #endif /* ENABLE_PKCS11 */
 
+/**
+ * gnutls_privkey_import_ext:
+ * @pkey: The private key
+ * @pk: The public key algorithm
+ * @userdata: private data to be provided to the callbacks
+ * @sign_func: callback for signature operations
+ * @decrypt_func: callback for decryption operations
+ * @flags: Flags for the import
+ *
+ * This function will associate the given callbacks with the
+ * #gnutls_privkey_t structure. At least one of the two callbacks
+ * must be non-null.
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ *
+ * Since: 3.0.0
+ **/
+int
+gnutls_privkey_import_ext (gnutls_privkey_t pkey,
+                           gnutls_pk_algorithm_t pk,
+                           void* userdata,
+                           gnutls_privkey_sign_func sign_func,
+                           gnutls_privkey_decrypt_func decrypt_func,
+                           unsigned int flags)
+{
+int ret;
+
+  ret = check_if_clean(pkey);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      return ret;
+    }
+  
+  if (sign_func == NULL && decrypt_func == NULL)
+    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+  pkey->key.ext.sign_func = sign_func;
+  pkey->key.ext.decrypt_func = decrypt_func;
+  pkey->key.ext.userdata = userdata;
+  pkey->type = GNUTLS_PRIVKEY_EXT;
+  pkey->pk_algorithm = pk;
+  pkey->flags = flags;
+
+  return 0;
+}
+
 /**
  * gnutls_privkey_import_x509:
  * @pkey: The private key
@@ -646,6 +703,10 @@ _gnutls_privkey_sign_hash (gnutls_privkey_t key,
       return _gnutls_soft_sign (key->key.x509->pk_algorithm,
                                 &key->key.x509->params,
                                 hash, signature);
+    case GNUTLS_PRIVKEY_EXT:
+      if (key->key.ext.sign_func == NULL)
+        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+      return key->key.ext.sign_func(key, key->key.ext.userdata, hash, signature);
     default:
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
@@ -696,6 +757,11 @@ gnutls_privkey_decrypt_data (gnutls_privkey_t key,
                                                  flags,
                                                  ciphertext, plaintext);
 #endif
+    case GNUTLS_PRIVKEY_EXT:
+      if (key->key.ext.decrypt_func == NULL)
+        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
+      return key->key.ext.decrypt_func(key, key->key.ext.userdata, ciphertext, plaintext);
     default:
       gnutls_assert ();
       return GNUTLS_E_INVALID_REQUEST;
index 1d4ed530103f1258107f439ba46d39e3c09911f7..025456364f0b406f2b3d5e245fc301817ab35f69 100644 (file)
@@ -1099,6 +1099,83 @@ cleanup:
   return ret;
 }
 
+/**
+ * gnutls_certificate_set_key:
+ * @res: is a #gnutls_certificate_credentials_t structure.
+ * @name: is the DNS name of the certificate (NULL if none)
+ * @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_x509_privkey_t key
+ *
+ * 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 wants to send more than its own end
+ * entity certificate (e.g., also an intermediate CA cert) then put
+ * the certificate chain in @pcert_list. The @pcert_list and @key will
+ * become part of the credentials structure and must not
+ * be deallocated. They will be automatically deallocated when
+ * @res is deinitialized.
+ *
+ * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code.
+ *
+ * Since: 3.0.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_str_array_init(&str_names);
+
+  if (names != NULL && names_size > 0)
+    {
+      for (i=0;i<names_size;i++)
+        {
+          ret = _gnutls_str_array_append(&str_names, names[i], strlen(names[i]));
+          if (ret < 0)
+            {
+              ret = gnutls_assert_val(ret);
+              goto cleanup;
+            }
+        }
+    }
+
+  ret = certificate_credentials_append_pkey (res, key);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = certificate_credential_append_crt_list (res, str_names, pcert_list, pcert_list_size);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  res->ncerts++;
+
+  if ((ret = _gnutls_check_key_cert_match (res)) < 0)
+    {
+      gnutls_assert ();
+      return ret;
+    }
+
+  return 0;
+  
+cleanup:
+  _gnutls_str_array_clear(&str_names);
+  return ret;
+}
+
 /**
  * gnutls_certificate_set_x509_key_file:
  * @res: is a #gnutls_certificate_credentials_t structure.
index 2d570798a6613c11f7745796a770607270312e27..7644e18025a2ae2d8b570668cedf037f0f447229 100644 (file)
@@ -37,6 +37,15 @@ typedef struct gnutls_pubkey_st *gnutls_pubkey_t;
 struct gnutls_privkey_st;
 typedef struct gnutls_privkey_st *gnutls_privkey_t;
 
+typedef int (*gnutls_privkey_sign_func) (gnutls_privkey_t key,
+                                         void *userdata,
+                                         const gnutls_datum_t * raw_data,
+                                         gnutls_datum_t * signature);
+typedef int (*gnutls_privkey_decrypt_func) (gnutls_privkey_t key,
+                                            void *userdata,
+                                            const gnutls_datum_t * ciphertext,
+                                            gnutls_datum_t * plaintext);
+
 int gnutls_pubkey_init (gnutls_pubkey_t * key);
 void gnutls_pubkey_deinit (gnutls_pubkey_t key);
 int gnutls_pubkey_get_pk_algorithm (gnutls_pubkey_t key, unsigned int *bits);
@@ -157,6 +166,13 @@ int gnutls_privkey_import_x509 (gnutls_privkey_t pkey,
 int gnutls_privkey_import_openpgp (gnutls_privkey_t pkey,
                                    gnutls_openpgp_privkey_t key,
                                    unsigned int flags);
+int
+gnutls_privkey_import_ext (gnutls_privkey_t pkey,
+                           gnutls_pk_algorithm_t pk,
+                           void* userdata,
+                           gnutls_privkey_sign_func sign_func,
+                           gnutls_privkey_decrypt_func decrypt_func,
+                           unsigned int flags);
 
 int gnutls_privkey_sign_data (gnutls_privkey_t signer,
                               gnutls_digest_algorithm_t hash,
@@ -252,9 +268,16 @@ void gnutls_pcert_deinit (gnutls_pcert_st* pcert);
                                                     gnutls_privkey_t *privkey);
 
 
-  void gnutls_certificate_set_retrieve_function2
-    (gnutls_certificate_credentials_t cred,
-     gnutls_certificate_retrieve_function2 * func);
+void gnutls_certificate_set_retrieve_function2
+  (gnutls_certificate_credentials_t cred,
+   gnutls_certificate_retrieve_function2 * func);
 
+int
+gnutls_certificate_set_key (gnutls_certificate_credentials_t res,
+                            const char** name,
+                            int name_size,
+                            gnutls_pcert_st * pcert_list,
+                            int pcert_list_size,
+                            gnutls_privkey_t key);
 
 #endif
index becf98bb1297d834ed8165cdd3f37c3cf1bd5313..d18424b34fe52bc2603d702cad7e67cad5e9322b 100644 (file)
@@ -192,7 +192,7 @@ void
    func) _GNUTLS_GCC_ATTR_DEPRECATED;
 
   /* External signing callback.  No longer supported because it
-   * was deprecated by the PKCS #11 API. */
+   * was deprecated by the PKCS #11 API and gnutls_privkey_t. */
 typedef int (*gnutls_sign_func) (gnutls_session_t session,
                                  void *userdata,
                                  gnutls_certificate_type_t cert_type,
index 83d4743ef009eb71058f0fc83f9ff73d4eb6860a..77ee1f49be5ce2030e72c8723897b6164a195052 100644 (file)
@@ -1468,6 +1468,7 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
  * @GNUTLS_PRIVKEY_X509: X.509 private key, #gnutls_x509_privkey_t.
  * @GNUTLS_PRIVKEY_OPENPGP: OpenPGP private key, #gnutls_openpgp_privkey_t.
  * @GNUTLS_PRIVKEY_PKCS11: PKCS11 private key, #gnutls_pkcs11_privkey_t.
+ * @GNUTLS_PRIVKEY_EXT: External private key, operating using callbacks.
  *
  * Enumeration of different private key types.
  */
@@ -1475,7 +1476,8 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
     {
       GNUTLS_PRIVKEY_X509,
       GNUTLS_PRIVKEY_OPENPGP,
-      GNUTLS_PRIVKEY_PKCS11
+      GNUTLS_PRIVKEY_PKCS11,
+      GNUTLS_PRIVKEY_EXT
     } gnutls_privkey_type_t;
 
   typedef struct gnutls_retr2_st
index b80f7bc0f88d7fc36f8e8ad712d7e598ec13eb1d..4d3ba84b9bb33049251489bef8dc1b432cada425 100644 (file)
@@ -718,6 +718,8 @@ GNUTLS_3_0_0 {
        gnutls_pubkey_import_ecc_raw2;
        gnutls_record_get_discarded;
        gnutls_x509_crt_get_authority_info_access;
+       gnutls_privkey_import_ext;
+       gnutls_certificate_set_key;
 } GNUTLS_2_12;
 
 GNUTLS_PRIVATE {