]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
* auth_cert.h: Added OpenPGP keyring item.
authorTimo Schulz <twoaday@gnutls.org>
Sat, 9 Feb 2002 13:18:44 +0000 (13:18 +0000)
committerTimo Schulz <twoaday@gnutls.org>
Sat, 9 Feb 2002 13:18:44 +0000 (13:18 +0000)
* gnutls_openpgp.c: Improved support for keyring handling.

lib/auth_cert.h
lib/gnutls_openpgp.c
lib/gnutls_openpgp.h

index 9e1ad6bbffe032a3845562b323e41ce37d6e4d9a..a28e5ccf262c98e6e67284fe7f6fe6da737af5c0 100644 (file)
@@ -28,6 +28,10 @@ typedef struct {
                                * cert_list[i][0].
                                */
 
+       /* OpenPGP specific stuff */
+
+       gnutls_datum keyring;
+    
        /* X509 specific stuff */
 
        gnutls_cert * x509_ca_list;
index d34e226f25d1dc32492ed5c4fa07e6a669fd6032..9becee1ea96434df0a775d68c2059bf513379fc2 100644 (file)
@@ -35,8 +35,6 @@
 #include "gnutls_global.h"
 #include "auth_cert.h"
 
-#define DEBUG_OPENPGP 1
-
 static void
 release_mpi_array(MPI *arr, size_t n)
 {
@@ -45,7 +43,8 @@ release_mpi_array(MPI *arr, size_t n)
   while (arr && n--)
     {
       x = *arr;
-      _gnutls_mpi_release(&x);
+      /*_gnutls_mpi_release(&x);*/
+      gcry_mpi_release(x);
       *arr = NULL; arr++;
     }
 }
@@ -76,10 +75,6 @@ is_file_armored(char *file)
       cdk_free(data); data = NULL;      
     }
 
-#ifdef DEBUG_OPENPGP
-  fprintf(stderr, "is_file_armored(%s) = %d\n", file, armored);
-#endif
-
 leave:
   return armored;
 }    
@@ -104,10 +99,6 @@ datum_to_openpgp_pkt( const gnutls_datum *raw, PKT *r_pkt )
   else
     rc = 0;
 
-#ifdef DEBUG_OPENPGP
-  fprintf(stderr, "datum_to_openpgp_pkt(%p, %p) = %d\n", raw, *r_pkt, rc);
-#endif
-
 leave:
   cdk_iobuf_close(buf);
   if (!rc)
@@ -233,10 +224,6 @@ leave:
   if (rc)
     release_mpi_array(cert->params, i-1);
 
-#ifdef DEBUG_OPENPGP
-  fprintf(stderr, "openpgp_pk_to_gnutls_cert(%p, %p) = %d\n", cert, pk, rc);
-#endif
-  
   return rc;
 }
 
@@ -256,8 +243,12 @@ openpgp_sig_to_gnutls_cert(gnutls_cert *cert, PKT_signature *sig)
     goto leave;
   data = cdk_iobuf_get_data_as_buffer(buf, &n);
   if (data && n)
-    {      
-      gnutls_datum_append( &cert->signature, data, n);
+    {
+      if ( gnutls_datum_append( &cert->signature, data, n) < 0 )
+        {
+          gnutls_assert();
+          return GNUTLS_E_MEMORY_ERROR;
+        }
       cdk_free(data); data = NULL;
     }
   else
@@ -266,10 +257,6 @@ openpgp_sig_to_gnutls_cert(gnutls_cert *cert, PKT_signature *sig)
 leave:
   cdk_iobuf_close(buf);
 
-#ifdef DEBUG_OPENPGP
-  fprintf(stderr, "openpgp_sig_to_gnutls_cert(%p, %p) = %d\n", cert, sig, rc);
-#endif
-  
   return rc;
 }
 
@@ -363,11 +350,6 @@ leave:
   cdk_iobuf_close(buf);
   cdk_pkt_release(pkt);
 
-#ifdef DEBUG_OPENPGP
-  fprintf(stderr, "_gnutls_openpgp_key2gnutls_key(%p, %p) = %d\n",
-          pkey, raw_key, rc);
-#endif
-  
   return rc;
 }
 
@@ -415,11 +397,6 @@ _gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw)
     }
   rc = openpgp_pk_to_gnutls_cert(cert, p->p.pk);
 
-#if DEBUG_OPENPGP
-  fprintf(stderr, "_gnutls_openpgp_cert2gnutls_cert (%p, %p) = %d\n",
-          cert, raw, 0);
-#endif
-
 leave:
   return rc;
 }
@@ -557,10 +534,6 @@ gnutls_certificate_set_openpgp_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res,
   rc =_gnutls_openpgp_key2gnutls_key( &res->pkey[res->ncerts-1], raw);
 
 leave:
-#ifdef DEBUG_OPENPGP
-  fprintf(stderr, "gnutls_certificate_set_openpgp_key_file(%p, %s, %s) = %d\n",
-          res, CERTFILE, KEYFILE, rc);
-#endif
   
   return rc;
 }
@@ -701,6 +674,29 @@ gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert )
   return expiredate;
 }
 
+static char*
+read_keyring_blob(const gnutls_datum* keyring, size_t pos,
+                  int *r_type, size_t *r_size)
+{
+  byte *blob;
+  
+  if (!keyring)
+    return NULL;
+
+  *r_type = keyring->data[pos];
+  if (*r_type < 0 || *r_type > 1)
+    return NULL;
+  *r_size = keyring->data[pos+1] << 24 | keyring->data[pos+2] << 16
+          | keyring->data[pos+3] <<  8 | keyring->data[pos+4];
+  if (!*r_size)
+    return NULL;
+  blob = gnutls_malloc(*r_size + 1);
+  memcpy(blob, keyring->data+(pos+5), *r_size);
+  blob[*r_size] = '\0';
+
+  return blob;
+}
+                   
 /**
  * gnutls_openpgp_verify_key - Verify all signatures on the key
  *
@@ -709,30 +705,73 @@ gnutls_openpgp_extract_key_expiration_time( const gnutls_datum *cert )
  *
  * Verify all signatures in the certificate list. When the key
  * is not available, the signature is skipped.
- * A return value of '0' means that all checked signatures are good.
+ * The return value is one of the CertificateStatus entries.
  **/
 int
-gnutls_openpgp_verify_key( const gnutls_datum* cert_list,
+gnutls_openpgp_verify_key( const gnutls_datum* keyring,
+                           const gnutls_datum* cert_list,
                            int cert_list_length)
-
 {
   PKT pkt = NULL;
+  KEYDB_HD khd = NULL;
   int rc = 0;
+  size_t size = 0;
+  int status = 0, type = -1;
+  char *data;
   
-  if (!cert_list || !cert_list_length )
-    return GNUTLS_E_INVALID_PARAMETERS;
-
-  if (cert_list_length != 1)
-    return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+  if (!cert_list || !cert_list_length || !keyring)
+    return GNUTLS_CERT_CORRUPTED;
+
+  if (cert_list_length != 1 || !keyring->size)
+    return GNUTLS_CERT_CORRUPTED;
+
+  data = read_keyring_blob(keyring, 0, &type, &size);
+  if (!data)
+    return GNUTLS_CERT_CORRUPTED;
+  khd = cdk_alloc_clear(sizeof *khd);
+  khd->used = 1;
+  if (type == 0x00) /* file */
+    {
+      khd->name = cdk_strdup(data);
+    }
+  else if (type == 0x01) /* data */
+    {
+      cdk_iobuf_new(&khd->buf, size);
+      cdk_iobuf_write(khd->buf, data, size);
+    }
+  else /* error */
+    {
+      rc = GNUTLS_CERT_CORRUPTED;
+      goto leave;
+    }
   
   if ( (rc = datum_to_openpgp_pkt(cert_list, &pkt)) )
-    return rc;
-  rc = cdk_key_check_sigs(pkt);
+    {
+      goto leave;
+      return GNUTLS_CERT_CORRUPTED;
+    }
+  rc = cdk_key_check_sigs(pkt, khd, &status);
   if (rc == CDKERR_NOKEY)
     rc = 0; /* fixme */
-  else if (rc == CDKERR_BAD_SIGNATURE)
-    rc = GNUTLS_E_PK_SIGNATURE_FAILED;
-  
+      
+  switch (status)
+    {
+    case CDK_KEY_INVALID:
+      rc = GNUTLS_CERT_CORRUPTED;
+      break;
+    case CDK_KEY_REVOKED:
+      rc = GNUTLS_CERT_REVOKED;
+      break;
+    case CDK_KEY_EXPIRED:
+      rc = GNUTLS_CERT_EXPIRED;
+      break;
+    case CDK_KEY_VALID:
+      rc = GNUTLS_CERT_TRUSTED;
+      break;
+    }
+
+leave:
+  cdk_free(khd); khd = NULL;
   return rc;
 }
 
@@ -809,23 +848,94 @@ gnutls_openpgp_keyid( const gnutls_datum *cert, u32 *keyid )
   return 0;
 }
 
+/* Creates a keyring blob from raw data
+ *
+ * Format:
+ * 1 octet  type
+ * 4 octet  size of blob
+ * n octets data
+ */
+static byte*
+conv_data_to_keyring(int type, const char *data, size_t size, size_t *r_size)
+{
+  byte *p;
+  
+  p = gnutls_malloc( 1+4+size );
+  p[0] = type; /* type: keyring name */
+  p[1] = (size >> 24) & 0xff;
+  p[2] = (size >> 16) & 0xff;
+  p[3] = (size >>  8) & 0xff;
+  p[4] = (size      ) & 0xff;
+  memcpy(p+5, data, size);
+  *r_size = 1+4+size;
+
+  return p;
+}
+
 /**
- * gnutls_openpgp_add_keyring - Adds a global keyring for OpenPGP
+ * gnutls_openpgp_add_keyring_file - Adds a keyring file for OpenPGP
  *
- * @fname: the filename of the keyring.
- * @is_secret: if the keyring contains secret keys or not.
+ * @keyring: data buffer to store the file.
+ * @name: filename of the keyring.
  *
  * The function is used to set keyrings that will be used internally
  * by various OpenCDK functions. For example to find a key when it
- * is need for an operations.
+ * is needed for an operations.
  **/
 int
-gnutls_openpgp_add_keyring(const char *fname, int is_secret)
+gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name)
 {
+  byte *blob;
+  size_t n;
   
-  if ( cdk_keydb_add_resource(fname, is_secret) )
-    return GNUTLS_E_UNKNOWN_ERROR;
+  if (!keyring || !name)
+    return GNUTLS_E_INVALID_PARAMETERS;
 
+  blob = conv_data_to_keyring(0x00, name, strlen(name), &n);
+  if (blob && n)
+    { 
+      if ( gnutls_datum_append( keyring, blob, n ) < 0 )
+        {
+          gnutls_assert();
+          return GNUTLS_E_MEMORY_ERROR;
+        }
+      gnutls_free(blob);
+    }
+  
+  return 0;
+}
+
+/**
+ * gnutls_openpgp_add_keyring_mem - Adds keyring data for OpenPGP
+ *
+ * @keyring: data buffer to store the file.
+ * @data: the binary data of the keyring.
+ * @len: the size of the binary buffer.
+ *
+ * Same as gnutls_openpgp_add_keyring_mem but now we store the
+ * data instead of the filename.
+ **/
+int
+gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring,
+                               const char *data, size_t len)
+{
+  byte *blob;
+  size_t n = 0;
+  
+  if (!keyring || !data || !len)
+    return GNUTLS_E_INVALID_PARAMETERS;
+  
+  blob = conv_data_to_keyring(0x01, data, len, &n);
+  if (blob && n)
+    {
+      if ( gnutls_datum_append( keyring, blob, n ) < 0 )
+        {
+          gnutls_assert();
+          return GNUTLS_E_MEMORY_ERROR;
+        }
+      gnutls_free(blob);
+    }
+  
   return 0;
 }
 
index 04c7f905d95c09fae8f6454ccbdb76f11bac46f7..2673fe8728bb6de31c26ddbac8e89976efed24a3 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef GNUTLS_OPENPGP_H
 #define GNUTLS_OPENPGP_H
 
-#ifdef HAVE_LIBOPENCDK
-
 int gnutls_certificate_set_openpgp_key_file(
                                             GNUTLS_CERTIFICATE_CREDENTIALS res,
                                             char* CERTFILE,
@@ -17,7 +15,8 @@ time_t gnutls_openpgp_extract_key_creation_time( const gnutls_datum *cert );
 
 time_t gnutls_openpgp_extract_key_expiration_time( const gnutls_datum  *cert );
 
-int gnutls_openpgp_verify_key( const gnutls_datum* cert_list,
+int gnutls_openpgp_verify_key( const gnutls_datum *keyring,
+                               const gnutls_datum* cert_list,
                                int cert_list_length );
 
 int gnutls_openpgp_fingerprint( const gnutls_datum *cert, opaque *fpr,
@@ -25,11 +24,21 @@ int gnutls_openpgp_fingerprint( const gnutls_datum *cert, opaque *fpr,
 
 int gnutls_openpgp_keyid( const gnutls_datum *cert, uint32 *keyid );
 
-int gnutls_openpgp_add_keyring( const char *fname, int is_secret );
+int gnutls_openpgp_add_keyring_mem(gnutls_datum *keyring,
+                                   const char *data, size_t len);
+
+int gnutls_openpgp_add_keyring_file(gnutls_datum *keyring, const char *name);
 
 /* internal */
 int _gnutls_openpgp_cert2gnutls_cert(gnutls_cert *cert, gnutls_datum raw);
 
-#endif /* HAVE_LIBOPENCDK */
-
 #endif /*GNUTLS_OPENPGP_H*/
+
+
+
+
+
+
+
+
+