Hi,

I'm finally getting back to this issue...

Simon Josefsson <[EMAIL PROTECTED]> writes:

> [EMAIL PROTECTED] (Ludovic Courtès) writes:
>
>> This can be seen as a GnuTLS bug since the FORMAT argument of
>> `gnutls_openpgp_privkey_import' is not honored.  Does CDK provide a way
>> to import ASCII-armored private keys?  Otherwise, `privkey_import'
>> should return `UNIMPLEMENTED_FEATURE' when FORMAT is not `RAW'.
>
> I agree.  There is code in OpenCDK to decode ASCII-armored data, so I
> suspect there is some minor bug that prevents this from working.

Below is a patch (against HEAD) that allows the import of ASCII-armored
OpenPGP private keys.

Thanks,
Ludovic.


ChangeLog entry:

        * lib/gnutls_cert.c (_gnutls_raw_privkey_to_gkey): Pass KEY_ENC to
        `_E_gnutls_openpgp_raw_privkey_to_gkey ()'.

        * libextra/gnutls_extra.h (OPENPGP_RAW_PRIVKEY_TO_GKEY): Added a
        `gnutls_openpgp_key_fmt_t' argument.

        * libextra/gnutls_openpgp.c
        (_gnutls_openpgp_raw_privkey_to_gkey): Take a new FORMAT
        argument.  When FORMAT is `BASE64', set the armor flag on OUT.
        (gnutls_certificate_set_openpgp_key_mem): Pass
        `GNUTLS_OPENPGP_FMT_RAW' as the last argument to
        `_gnutls_openpgp_raw_privkey_to_gkey ()'.

        * libextra/openpgp/gnutls_openpgp.h
        (_gnutls_openpgp_raw_privkey_to_gkey): Updated accordingly.

        * libextra/openpgp/privkey.c (gnutls_openpgp_privkey_import):
        Pass FORMAT to `_gnutls_openpgp_raw_privkey_to_gkey ()'.


--- orig/lib/gnutls_cert.c
+++ mod/lib/gnutls_cert.c
@@ -732,7 +732,8 @@ _gnutls_raw_privkey_to_gkey (gnutls_priv
 	  gnutls_assert ();
 	  return GNUTLS_E_INIT_LIBEXTRA;
 	}
-      return _E_gnutls_openpgp_raw_privkey_to_gkey (key, raw_key);
+      return _E_gnutls_openpgp_raw_privkey_to_gkey (key, raw_key,
+						    key_enc);
     default:
       gnutls_assert ();
       return GNUTLS_E_INTERNAL_ERROR;

--- orig/libextra/gnutls_extra.h
+++ mod/libextra/gnutls_extra.h
@@ -41,7 +41,8 @@ typedef int (*OPENPGP_FINGERPRINT) (cons
 typedef int (*OPENPGP_RAW_KEY_TO_GCERT) (gnutls_cert *,
 					 const gnutls_datum_t *);
 typedef int (*OPENPGP_RAW_PRIVKEY_TO_GKEY) (gnutls_privkey *,
-					    const gnutls_datum_t *);
+					    const gnutls_datum_t *,
+					    gnutls_openpgp_key_fmt_t);
 
 typedef int (*OPENPGP_KEY_TO_GCERT) (gnutls_cert *, gnutls_openpgp_key_t);
 typedef int (*OPENPGP_PRIVKEY_TO_GKEY) (gnutls_privkey *,

--- orig/libextra/gnutls_openpgp.c
+++ mod/libextra/gnutls_openpgp.c
@@ -309,6 +309,7 @@ openpgp_pk_to_gnutls_cert (gnutls_cert *
  * _gnutls_openpgp_raw_privkey_to_gkey - Converts an OpenPGP secret key to GnuTLS
  * @pkey: the GnuTLS private key context to store the key.
  * @raw_key: the raw data which contains the whole key packets.
+ * @format: the format of the key packets.
  *
  * The RFC2440 (OpenPGP Message Format) data is converted into the
  * GnuTLS specific data which is need to perform secret key operations.
@@ -317,9 +318,10 @@ openpgp_pk_to_gnutls_cert (gnutls_cert *
  -*/
 int
 _gnutls_openpgp_raw_privkey_to_gkey (gnutls_privkey * pkey,
-				     const gnutls_datum_t * raw_key)
+				     const gnutls_datum_t * raw_key,
+				     gnutls_openpgp_key_fmt_t format)
 {
-  cdk_kbnode_t snode;
+  cdk_kbnode_t snode = NULL;
   cdk_packet_t pkt;
   cdk_stream_t out;
   cdk_pkt_seckey_t sk = NULL;
@@ -338,6 +340,17 @@ _gnutls_openpgp_raw_privkey_to_gkey (gnu
   if (!out)
     return GNUTLS_E_CERTIFICATE_ERROR;
 
+  if (format == GNUTLS_OPENPGP_FMT_BASE64)
+    {
+      rc = cdk_stream_set_armor_flag (out, 0);
+      if (rc)
+	{
+	  rc = _gnutls_map_cdk_rc (rc);
+	  gnutls_assert ();
+	  goto leave;
+	}
+    }
+
   cdk_stream_write (out, raw_key->data, raw_key->size);
   cdk_stream_seek (out, 0);
 
@@ -559,7 +572,7 @@ stream_to_datum (cdk_stream_t inp, gnutl
  * @key: the datum that contains the secret key.
  *
  * This funtion is used to load OpenPGP keys into the GnuTLS credential structure.
- * It doesn't matter whether the keys are armored or but, but the files
+ * It doesn't matter whether the keys are armored or not, but the files
  * should only contain one key which should not be encrypted.
  **/
 int
@@ -695,7 +708,8 @@ gnutls_certificate_set_openpgp_key_mem (
   cdk_stream_close (inp);
 
   rc = _gnutls_openpgp_raw_privkey_to_gkey (&res->pkey[res->ncerts - 1],
-					    &raw);
+					    &raw,
+					    GNUTLS_OPENPGP_FMT_RAW);
   if (rc)
     {
       gnutls_assert ();
@@ -717,7 +731,7 @@ leave:
  * @keyfile: the file that contains the secret key.
  *
  * This funtion is used to load OpenPGP keys into the GnuTLS credentials structure.
- * It doesn't matter whether the keys are armored or but, but the files
+ * It doesn't matter whether the keys are armored or not, but the files
  * should only contain one key which should not be encrypted.
  **/
 int

--- orig/libextra/openpgp/gnutls_openpgp.h
+++ mod/libextra/openpgp/gnutls_openpgp.h
@@ -66,7 +66,8 @@ int _gnutls_openpgp_raw_key_to_gcert (gn
 
 int
 _gnutls_openpgp_raw_privkey_to_gkey (gnutls_privkey * pkey,
-				     const gnutls_datum_t * raw_key);
+				     const gnutls_datum_t * raw_key,
+				     gnutls_openpgp_key_fmt_t format);
 
 int
 _gnutls_openpgp_request_key (gnutls_session_t,

--- orig/libextra/openpgp/privkey.c
+++ mod/libextra/openpgp/privkey.c
@@ -94,7 +94,8 @@ gnutls_openpgp_privkey_import (gnutls_op
 {
   int rc;
 
-  rc = _gnutls_openpgp_raw_privkey_to_gkey (&key->pkey, data);
+  rc = _gnutls_openpgp_raw_privkey_to_gkey (&key->pkey, data,
+					    format);
   if (rc)
     {
       gnutls_assert ();

_______________________________________________
Help-gnutls mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-gnutls

Reply via email to