gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_3_1_0-126-gb30fda4


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_3_1_0-126-gb30fda4
Date: Sun, 23 Sep 2012 17:06:52 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=b30fda48aef347e678d14d0caee2961dce0ceda7

The branch, master has been updated
       via  b30fda48aef347e678d14d0caee2961dce0ceda7 (commit)
       via  8b8327ee6128321aaa04777ed89e826fb0d307ba (commit)
       via  4366201402fcdecde2331e4d87c05141207e1027 (commit)
       via  a3887dabf27995374a52bc4fd0bd4da10d9081ad (commit)
       via  14aeea2c63cd7ae48292c04356e6ac724be1eee6 (commit)
      from  78084940d8bcb03216e92096fcde4738101e8417 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit b30fda48aef347e678d14d0caee2961dce0ceda7
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Sep 23 19:06:43 2012 +0200

    documented fix

commit 8b8327ee6128321aaa04777ed89e826fb0d307ba
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Sep 23 19:06:17 2012 +0200

    reduced verbosity and better debugging.

commit 4366201402fcdecde2331e4d87c05141207e1027
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Sep 23 19:06:00 2012 +0200

    Corrected bug in PGP subpacket encoding

commit a3887dabf27995374a52bc4fd0bd4da10d9081ad
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sun Sep 23 16:34:25 2012 +0200

    Added script to check against randomly generated certificates.

commit 14aeea2c63cd7ae48292c04356e6ac724be1eee6
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Sat Sep 22 14:28:00 2012 +0200

    removed unused label

-----------------------------------------------------------------------

Summary of changes:
 NEWS                                       |    2 +
 lib/opencdk/kbnode.c                       |    4 +-
 lib/opencdk/main.h                         |    4 +-
 lib/opencdk/misc.c                         |    8 +-
 lib/opencdk/new-packet.c                   |    4 +-
 lib/opencdk/read-packet.c                  |  104 +++++---
 lib/opencdk/stream.c                       |   68 ++++-
 lib/opencdk/write-packet.c                 |  104 +++++---
 tests/mini-dtls-heartbeat.c                |    2 -
 tests/suite/Makefile.am                    |    2 +-
 tests/suite/asn1random.pl                  |  118 ++++++++
 tests/{cert-tests/aki => suite/testrandom} |   52 +++--
 tests/suite/x509random.pl                  |  401 ++++++++++++++++++++++++++++
 13 files changed, 756 insertions(+), 117 deletions(-)
 create mode 100755 tests/suite/asn1random.pl
 copy tests/{cert-tests/aki => suite/testrandom} (51%)
 create mode 100755 tests/suite/x509random.pl

diff --git a/NEWS b/NEWS
index e929d78..e7c772b 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ See the end for copying conditions.
 and gnutls_x509_trust_list_add_trust_mem() that prevented the loading
 of certificates in the windows platform.
 
+** libgnutls: Corrected bug in OpenPGP subpacket encoding.
+
 ** libgnutls: Added support for DTLS/TLS heartbeats by Olga Smolenchuk.
 (the work was done during Google Summer of Code).
 
diff --git a/lib/opencdk/kbnode.c b/lib/opencdk/kbnode.c
index 8a93e9b..51c2748 100644
--- a/lib/opencdk/kbnode.c
+++ b/lib/opencdk/kbnode.c
@@ -415,11 +415,11 @@ cdk_kbnode_read_from_mem (cdk_kbnode_t * ret_node,
 
   *ret_node = NULL;
   if (!buflen)
-    return CDK_Too_Short;
+    return gnutls_assert_val(CDK_Too_Short);
 
   rc = cdk_stream_tmp_from_mem (buf, buflen, &inp);
   if (rc)
-    return rc;
+    return gnutls_assert_val(rc);
   
   if (armor)
     cdk_stream_set_armor_flag (inp, 0);
diff --git a/lib/opencdk/main.h b/lib/opencdk/main.h
index 72bf7a9..e56009a 100644
--- a/lib/opencdk/main.h
+++ b/lib/opencdk/main.h
@@ -68,13 +68,13 @@ cdk_error_t map_gnutls_error (int err);
 #define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10)
 #define IS_UID_REV(s) ((s)->sig_class == 0x30)
 
-#define DEBUG_PKT (_cdk_get_log_level () == (CDK_LOG_DEBUG+1))
-
 /* Helper to find out if a key has the requested capability. */
 #define KEY_CAN_ENCRYPT(a) ((_cdk_pk_algo_usage ((a))) & CDK_KEY_USG_ENCR)
 #define KEY_CAN_SIGN(a)    ((_cdk_pk_algo_usage ((a))) & CDK_KEY_USG_SIGN)
 #define KEY_CAN_AUTH(a)    ((_cdk_pk_algo_usage ((a))) & CDK_KEY_USG_AUTH)
 
+#define DEBUG_PKT 0
+
 /*-- main.c --*/
 char *_cdk_passphrase_get (cdk_ctx_t hd, const char *prompt);
 
diff --git a/lib/opencdk/misc.c b/lib/opencdk/misc.c
index ec6ad08..f270e6f 100644
--- a/lib/opencdk/misc.c
+++ b/lib/opencdk/misc.c
@@ -276,6 +276,8 @@ _pgp_cipher_to_gnutls (int cipher)
 {
   switch (cipher)
     {
+    case 0:
+      return GNUTLS_CIPHER_NULL;
     case 1:
       return GNUTLS_CIPHER_IDEA_PGP_CFB;
     case 2:
@@ -297,7 +299,8 @@ _pgp_cipher_to_gnutls (int cipher)
 
     default:
       gnutls_assert ();
-      return GNUTLS_CIPHER_NULL;
+      _gnutls_debug_log("Unknown openpgp cipher %u\n", cipher);
+      return GNUTLS_CIPHER_UNKNOWN;
     }
 }
 
@@ -306,7 +309,8 @@ _gnutls_cipher_to_pgp (int cipher)
 {
   switch (cipher)
     {
-
+    case GNUTLS_CIPHER_NULL:
+      return 0;
     case GNUTLS_CIPHER_IDEA_PGP_CFB:
       return 1;
     case GNUTLS_CIPHER_3DES_PGP_CFB:
diff --git a/lib/opencdk/new-packet.c b/lib/opencdk/new-packet.c
index 9453476..7a7179a 100644
--- a/lib/opencdk/new-packet.c
+++ b/lib/opencdk/new-packet.c
@@ -711,8 +711,9 @@ _cdk_subpkt_get_array (cdk_subpkt_t s, int count, size_t * 
r_nbytes)
         buf[n++] = nbytes;
       else if (nbytes < 8384)
         {
+          nbytes -= 192;
           buf[n++] = nbytes / 256 + 192;
-          buf[n++] = nbytes % 256;
+          buf[n++] = nbytes & 0xff;
         }
       else
         {
@@ -722,6 +723,7 @@ _cdk_subpkt_get_array (cdk_subpkt_t s, int count, size_t * 
r_nbytes)
           buf[n++] = nbytes >> 8;
           buf[n++] = nbytes;
         }
+
       buf[n++] = list->type;
       memcpy (buf + n, list->d, list->size);
       n += list->size;
diff --git a/lib/opencdk/read-packet.c b/lib/opencdk/read-packet.c
index 3e92909..6abb088 100644
--- a/lib/opencdk/read-packet.c
+++ b/lib/opencdk/read-packet.c
@@ -130,7 +130,7 @@ read_mpi (cdk_stream_t inp, bigint_t * ret_m, int secure)
   if (nbits > MAX_MPI_BITS || nbits == 0)
     {
       _gnutls_write_log ("read_mpi: too large %d bits\n", (int) nbits);
-      return CDK_MPI_Error;     /* Sanity check */
+      return gnutls_assert_val(CDK_MPI_Error);     /* Sanity check */
     }
 
   rc = stream_read (inp, buf + 2, nread, &nread);
@@ -138,7 +138,7 @@ read_mpi (cdk_stream_t inp, bigint_t * ret_m, int secure)
     {
       _gnutls_write_log ("read_mpi: too short %d < %d\n", (int) nread,
                          (int) ((nbits + 7) / 8));
-      return CDK_MPI_Error;
+      return gnutls_assert_val(CDK_MPI_Error);
     }
 
   buf[0] = nbits >> 8;
@@ -146,7 +146,7 @@ read_mpi (cdk_stream_t inp, bigint_t * ret_m, int secure)
   nread += 2;
   err = _gnutls_mpi_scan_pgp (&m, buf, nread);
   if (err < 0)
-    return map_gnutls_error (err);
+    return gnutls_assert_val(map_gnutls_error (err));
 
   *ret_m = m;
   return rc;
@@ -217,7 +217,7 @@ read_pubkey_enc (cdk_stream_t inp, size_t pktlen, 
cdk_pkt_pubkey_enc_t pke)
     {
       cdk_error_t rc = read_mpi (inp, &pke->mpi[i], 0);
       if (rc)
-        return rc;
+        return gnutls_assert_val(rc);
     }
 
   return 0;
@@ -309,7 +309,7 @@ read_public_key (cdk_stream_t inp, size_t pktlen, 
cdk_pkt_pubkey_t pk)
     {
       cdk_error_t rc = read_mpi (inp, &pk->mpi[i], 0);
       if (rc)
-        return rc;
+        return gnutls_assert_val(rc);
     }
 
   /* This value is just for the first run and will be
@@ -351,6 +351,9 @@ read_secret_key (cdk_stream_t inp, size_t pktlen, 
cdk_pkt_seckey_t sk)
     {
       sk->protect.sha1chk = (sk->s2k_usage == 254);
       sk->protect.algo = _pgp_cipher_to_gnutls (cdk_stream_getc (inp));
+      if (sk->protect.algo == GNUTLS_CIPHER_UNKNOWN)
+        return gnutls_assert_val(CDK_Inv_Algo);
+
       sk->protect.s2k = cdk_calloc (1, sizeof *sk->protect.s2k);
       if (!sk->protect.s2k)
         return CDK_Out_Of_Core;
@@ -374,7 +377,9 @@ read_secret_key (cdk_stream_t inp, size_t pktlen, 
cdk_pkt_seckey_t sk)
     }
   else
     sk->protect.algo = _pgp_cipher_to_gnutls (sk->s2k_usage);
-  if (sk->protect.algo == GNUTLS_CIPHER_NULL)
+  if (sk->protect.algo == GNUTLS_CIPHER_UNKNOWN)
+    return gnutls_assert_val(CDK_Inv_Algo);
+  else if (sk->protect.algo == GNUTLS_CIPHER_NULL)
     {
       sk->csum = 0;
       nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo);
@@ -387,7 +392,7 @@ read_secret_key (cdk_stream_t inp, size_t pktlen, 
cdk_pkt_seckey_t sk)
         {
           rc = read_mpi (inp, &sk->mpi[i], 1);
           if (rc)
-            return rc;
+            return gnutls_assert_val(rc);
         }
       sk->csum = read_16 (inp);
       sk->is_protected = 0;
@@ -405,7 +410,7 @@ read_secret_key (cdk_stream_t inp, size_t pktlen, 
cdk_pkt_seckey_t sk)
         {
           rc = read_mpi (inp, &sk->mpi[i], 1);
           if (rc)
-            return rc;
+            return gnutls_assert_val(rc);
         }
       sk->csum = read_16 (inp);
       sk->is_protected = 1;
@@ -726,20 +731,21 @@ static cdk_error_t
 read_signature (cdk_stream_t inp, size_t pktlen, cdk_pkt_signature_t sig)
 {
   size_t nbytes;
-  size_t i, size, nsig;
+  size_t i, nsig;
+  ssize_t size;
   cdk_error_t rc;
 
   if (!inp || !sig)
-    return CDK_Inv_Value;
+    return gnutls_assert_val(CDK_Inv_Value);
 
   if (DEBUG_PKT)
     _gnutls_write_log ("read_signature: %d octets\n", (int) pktlen);
 
   if (pktlen < 16)
-    return CDK_Inv_Packet;
+    return gnutls_assert_val(CDK_Inv_Packet);
   sig->version = cdk_stream_getc (inp);
   if (sig->version < 2 || sig->version > 4)
-    return CDK_Inv_Packet_Ver;
+    return gnutls_assert_val(CDK_Inv_Packet_Ver);
 
   sig->flags.exportable = 1;
   sig->flags.revocable = 1;
@@ -747,7 +753,7 @@ read_signature (cdk_stream_t inp, size_t pktlen, 
cdk_pkt_signature_t sig)
   if (sig->version < 4)
     {
       if (cdk_stream_getc (inp) != 5)
-        return CDK_Inv_Packet;
+        return gnutls_assert_val(CDK_Inv_Packet);
       sig->sig_class = cdk_stream_getc (inp);
       sig->timestamp = read_32 (inp);
       sig->keyid[0] = read_32 (inp);
@@ -758,12 +764,12 @@ read_signature (cdk_stream_t inp, size_t pktlen, 
cdk_pkt_signature_t sig)
       sig->digest_start[1] = cdk_stream_getc (inp);
       nsig = cdk_pk_get_nsig (sig->pubkey_algo);
       if (!nsig)
-        return CDK_Inv_Algo;
+        return gnutls_assert_val(CDK_Inv_Algo);
       for (i = 0; i < nsig; i++)
         {
           rc = read_mpi (inp, &sig->mpi[i], 0);
           if (rc)
-            return rc;
+            return gnutls_assert_val(rc);
         }
     }
   else
@@ -778,7 +784,7 @@ read_signature (cdk_stream_t inp, size_t pktlen, 
cdk_pkt_signature_t sig)
         {
           rc = read_subpkt (inp, &sig->hashed, &nbytes);
           if (rc)
-            return rc;
+            return gnutls_assert_val(rc);
           size -= nbytes;
         }
       sig->unhashed_size = read_16 (inp);
@@ -788,24 +794,24 @@ read_signature (cdk_stream_t inp, size_t pktlen, 
cdk_pkt_signature_t sig)
         {
           rc = read_subpkt (inp, &sig->unhashed, &nbytes);
           if (rc)
-            return rc;
+            return gnutls_assert_val(rc);
           size -= nbytes;
         }
 
       rc = parse_sig_subpackets (sig);
       if (rc)
-        return rc;
+        return gnutls_assert_val(rc);
 
       sig->digest_start[0] = cdk_stream_getc (inp);
       sig->digest_start[1] = cdk_stream_getc (inp);
       nsig = cdk_pk_get_nsig (sig->pubkey_algo);
       if (!nsig)
-        return CDK_Inv_Algo;
+        return gnutls_assert_val(CDK_Inv_Algo);
       for (i = 0; i < nsig; i++)
         {
           rc = read_mpi (inp, &sig->mpi[i], 0);
           if (rc)
-            return rc;
+            return gnutls_assert_val(rc);
         }
     }
 
@@ -955,7 +961,7 @@ cdk_pkt_read (cdk_stream_t inp, cdk_packet_t pkt)
   if (cdk_stream_eof (inp) || ctb == EOF)
     return CDK_EOF;
   else if (!ctb)
-    return CDK_Inv_Packet;
+    return gnutls_assert_val(CDK_Inv_Packet);
 
   pktsize++;
   if (!(ctb & 0x80))
@@ -963,7 +969,7 @@ cdk_pkt_read (cdk_stream_t inp, cdk_packet_t pkt)
       _cdk_log_info ("cdk_pkt_read: no openpgp data found. "
                      "(ctb=%02X; fpos=%02X)\n", (int) ctb,
                      (int) cdk_stream_tell (inp));
-      return CDK_Inv_Packet;
+      return gnutls_assert_val(CDK_Inv_Packet);
     }
 
   if (ctb & 0x40)               /* RFC2440 packet format. */
@@ -981,7 +987,7 @@ cdk_pkt_read (cdk_stream_t inp, cdk_packet_t pkt)
   if (pkttype > 63)
     {
       _cdk_log_info ("cdk_pkt_read: unknown type %d\n", pkttype);
-      return CDK_Inv_Packet;
+      return gnutls_assert_val(CDK_Inv_Packet);
     }
 
   if (is_newctb)
@@ -1002,100 +1008,124 @@ cdk_pkt_read (cdk_stream_t inp, cdk_packet_t pkt)
       pkt->pkt.user_id = cdk_calloc (1, sizeof *pkt->pkt.user_id
                                      + NAME_SIZE);
       if (!pkt->pkt.user_id)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       pkt->pkt.user_id->name =
         (char *) pkt->pkt.user_id + sizeof (*pkt->pkt.user_id);
 
       rc = read_attribute (inp, pktlen, pkt->pkt.user_id, NAME_SIZE);
       pkt->pkttype = CDK_PKT_ATTRIBUTE;
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_USER_ID:
       pkt->pkt.user_id = cdk_calloc (1, sizeof *pkt->pkt.user_id
                                      + pkt->pktlen + 1);
       if (!pkt->pkt.user_id)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       pkt->pkt.user_id->name =
         (char *) pkt->pkt.user_id + sizeof (*pkt->pkt.user_id);
       rc = read_user_id (inp, pktlen, pkt->pkt.user_id);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_PUBLIC_KEY:
       pkt->pkt.public_key = cdk_calloc (1, sizeof *pkt->pkt.public_key);
       if (!pkt->pkt.public_key)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       rc = read_public_key (inp, pktlen, pkt->pkt.public_key);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_PUBLIC_SUBKEY:
       pkt->pkt.public_key = cdk_calloc (1, sizeof *pkt->pkt.public_key);
       if (!pkt->pkt.public_key)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       rc = read_public_subkey (inp, pktlen, pkt->pkt.public_key);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_SECRET_KEY:
       pkt->pkt.secret_key = cdk_calloc (1, sizeof *pkt->pkt.secret_key);
       if (!pkt->pkt.secret_key)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       pkt->pkt.secret_key->pk = cdk_calloc (1,
                                             sizeof *pkt->pkt.secret_key->pk);
       if (!pkt->pkt.secret_key->pk)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       rc = read_secret_key (inp, pktlen, pkt->pkt.secret_key);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_SECRET_SUBKEY:
       pkt->pkt.secret_key = cdk_calloc (1, sizeof *pkt->pkt.secret_key);
       if (!pkt->pkt.secret_key)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       pkt->pkt.secret_key->pk = cdk_calloc (1,
                                             sizeof *pkt->pkt.secret_key->pk);
       if (!pkt->pkt.secret_key->pk)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       rc = read_secret_subkey (inp, pktlen, pkt->pkt.secret_key);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_LITERAL:
       pkt->pkt.literal = cdk_calloc (1, sizeof *pkt->pkt.literal);
       if (!pkt->pkt.literal)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       rc = read_literal (inp, pktlen, &pkt->pkt.literal, is_partial);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_ONEPASS_SIG:
       pkt->pkt.onepass_sig = cdk_calloc (1, sizeof *pkt->pkt.onepass_sig);
       if (!pkt->pkt.onepass_sig)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       rc = read_onepass_sig (inp, pktlen, pkt->pkt.onepass_sig);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_SIGNATURE:
       pkt->pkt.signature = cdk_calloc (1, sizeof *pkt->pkt.signature);
       if (!pkt->pkt.signature)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       rc = read_signature (inp, pktlen, pkt->pkt.signature);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_PUBKEY_ENC:
       pkt->pkt.pubkey_enc = cdk_calloc (1, sizeof *pkt->pkt.pubkey_enc);
       if (!pkt->pkt.pubkey_enc)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       rc = read_pubkey_enc (inp, pktlen, pkt->pkt.pubkey_enc);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_COMPRESSED:
       pkt->pkt.compressed = cdk_calloc (1, sizeof *pkt->pkt.compressed);
       if (!pkt->pkt.compressed)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       rc = read_compressed (inp, pktlen, pkt->pkt.compressed);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     case CDK_PKT_MDC:
       pkt->pkt.mdc = cdk_calloc (1, sizeof *pkt->pkt.mdc);
       if (!pkt->pkt.mdc)
-        return CDK_Out_Of_Core;
+        return gnutls_assert_val(CDK_Out_Of_Core);
       rc = read_mdc (inp, pkt->pkt.mdc);
+      if (rc)
+        return gnutls_assert_val(rc);
       break;
 
     default:
diff --git a/lib/opencdk/stream.c b/lib/opencdk/stream.c
index bfc96ab..aff1109 100644
--- a/lib/opencdk/stream.c
+++ b/lib/opencdk/stream.c
@@ -82,7 +82,9 @@ _cdk_stream_open_mode (const char *file, const char *mode,
       return CDK_Inv_Value;
     }
 
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("open stream `%s'\n", file);
+#endif
   *ret_s = NULL;
   s = cdk_calloc (1, sizeof *s);
   if (!s)
@@ -105,7 +107,9 @@ _cdk_stream_open_mode (const char *file, const char *mode,
       gnutls_assert ();
       return CDK_File_Error;
     }
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("open stream fd=%d\n", fileno (s->fp));
+#endif
   s->flags.write = 0;
   *ret_s = s;
   return 0;
@@ -175,7 +179,9 @@ cdk_stream_new (const char *file, cdk_stream_t * ret_s)
       return CDK_Inv_Value;
     }
 
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("new stream `%s'\n", file ? file : "[temp]");
+#endif
   *ret_s = NULL;
   s = cdk_calloc (1, sizeof *s);
   if (!s)
@@ -204,7 +210,9 @@ cdk_stream_new (const char *file, cdk_stream_t * ret_s)
       gnutls_assert ();
       return CDK_File_Error;
     }
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("new stream fd=%d\n", fileno (s->fp));
+#endif
   *ret_s = s;
   return 0;
 }
@@ -229,7 +237,9 @@ cdk_stream_create (const char *file, cdk_stream_t * ret_s)
       return CDK_Inv_Value;
     }
 
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("create stream `%s'\n", file);
+#endif
   *ret_s = NULL;
   s = cdk_calloc (1, sizeof *s);
   if (!s)
@@ -254,7 +264,9 @@ cdk_stream_create (const char *file, cdk_stream_t * ret_s)
       gnutls_assert ();
       return CDK_File_Error;
     }
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("stream create fd=%d\n", fileno (s->fp));
+#endif
   *ret_s = s;
   return 0;
 }
@@ -323,7 +335,9 @@ _cdk_stream_fpopen (FILE * fp, unsigned write_mode, 
cdk_stream_t * ret_out)
       return CDK_Out_Of_Core;
     }
 
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("stream ref fd=%d\n", fileno (fp));
+#endif
   s->fp = fp;
   s->fp_ref = 1;
   s->flags.filtrated = 1;
@@ -457,8 +471,10 @@ cdk_stream_close (cdk_stream_t s)
       return CDK_Inv_Value;
     }
 
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("close stream ref=%d `%s'\n",
                     s->fp_ref, s->fname ? s->fname : "[temp]");
+#endif
 
   /* In the user callback mode, we call the release cb if possible
      and just free the stream. */
@@ -481,7 +497,9 @@ cdk_stream_close (cdk_stream_t s)
     {
       int err;
 
+#ifdef DEBUG_STREAM
       _gnutls_read_log ("close stream fd=%d\n", fileno (s->fp));
+#endif
       err = fclose (s->fp);
       s->fp = NULL;
       if (err)
@@ -510,7 +528,10 @@ cdk_stream_close (cdk_stream_t s)
   s->cache.alloced = 0;
 
   cdk_free (s);
-  gnutls_assert ();
+  
+  if (rc)
+    gnutls_assert ();
+
   return rc;
 }
 
@@ -754,8 +775,10 @@ stream_fp_replace (cdk_stream_t s, FILE ** tmp)
 
   assert (s);
 
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("replace stream fd=%d with fd=%d\n",
                     fileno (s->fp), fileno (*tmp));
+#endif
   rc = fclose (s->fp);
   if (rc)
     {
@@ -791,8 +814,10 @@ stream_filter_write (cdk_stream_t s)
       if (!f->flags.enabled)
         continue;
       /* if there is no next filter, create the final output file */
+#ifdef DEBUG_STREAM
       _gnutls_read_log ("filter [write]: last filter=%d fname=%s\n",
                         f->next ? 1 : 0, s->fname);
+#endif
       if (!f->next && s->fname)
         f->tmp = fopen (s->fname, "w+b");
       else
@@ -812,14 +837,18 @@ stream_filter_write (cdk_stream_t s)
             break;
         }
       rc = f->fnct (f->uint8_t, f->ctl, s->fp, f->tmp);
+#ifdef DEBUG_STREAM
       _gnutls_read_log ("filter [write]: type=%d rc=%d\n", f->type, rc);
+#endif
       if (!rc)
         rc = stream_fp_replace (s, &f->tmp);
       if (!rc)
         rc = cdk_stream_seek (s, 0);
       if (rc)
         {
+#ifdef DEBUG_STREAM
           _gnutls_read_log ("filter [close]: fd=%d\n", fileno (f->tmp));
+#endif
           fclose (f->tmp);
           f->tmp = NULL;
           break;
@@ -851,8 +880,10 @@ stream_filter_read (cdk_stream_t s)
         continue;
       if (f->flags.error)
         {
+#ifdef DEBUG_STREAM
           _gnutls_read_log ("filter %s [read]: has the error flag; skipped\n",
                             s->fname ? s->fname : "[temp]");
+#endif
           continue;
         }
 
@@ -863,8 +894,10 @@ stream_filter_read (cdk_stream_t s)
           break;
         }
       rc = f->fnct (f->uint8_t, f->ctl, s->fp, f->tmp);
+#ifdef DEBUG_STREAM
       _gnutls_read_log ("filter %s [read]: type=%d rc=%d\n",
                         s->fname ? s->fname : "[temp]", f->type, rc);
+#endif
       if (rc)
         {
           f->flags.error = 1;
@@ -1047,6 +1080,10 @@ cdk_stream_write (cdk_stream_t s, const void *buf, 
size_t count)
 
   if (s->cache.on)
     {
+#ifdef DEBUG_STREAM
+      _gnutls_read_log ("stream[ref=%u]: written %d bytes\n", s->fp_ref, (int) 
count);
+#endif
+
       /* We need to resize the buffer if the additional data wouldn't
          fit into it. We allocate more memory to avoid to resize it the
          next time the function is used. */
@@ -1059,14 +1096,21 @@ cdk_stream_write (cdk_stream_t s, const void *buf, 
size_t count)
           s->cache.alloced += (count + STREAM_BUFSIZE);
           memcpy (s->cache.buf, old, s->cache.size);
           cdk_free (old);
+#ifdef DEBUG_STREAM
           _gnutls_read_log ("stream: enlarge cache to %d octets\n",
                             (int) s->cache.alloced);
+#endif
         }
+
       memcpy (s->cache.buf + s->cache.size, buf, count);
       s->cache.size += count;
       return count;
     }
 
+#ifdef DEBUG_STREAM
+  _gnutls_read_log ("stream[fd=%u]: written %d bytes\n", fileno (s->fp), (int) 
count);
+#endif
+
   nwritten = fwrite (buf, 1, count, s->fp);
   if (!nwritten)
     nwritten = EOF;
@@ -1197,7 +1241,9 @@ cdk_stream_set_literal_flag (cdk_stream_t s, 
cdk_lit_format_t mode,
   struct stream_filter_s *f;
   const char *orig_fname;
 
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("stream: enable literal mode.\n");
+#endif
 
   if (!s)
     {
@@ -1242,20 +1288,6 @@ cdk_stream_set_compress_flag (cdk_stream_t s, int algo, 
int level)
 
   gnutls_assert ();
   return CDK_Not_Implemented;
-
-#if 0
-  struct stream_filter_s *f;
-
-  if (!s)
-    return CDK_Inv_Value;
-  f = filter_add (s, _cdk_filter_compress, fCOMPRESS);
-  if (!f)
-    return CDK_Out_Of_Core;
-  f->ctl = stream_get_mode (s);
-  f->u.zfx.algo = algo;
-  f->u.zfx.level = level;
-  return 0;
-#endif
 }
 
 
@@ -1349,8 +1381,10 @@ cdk_stream_enable_cache (cdk_stream_t s, int val)
     {
       s->cache.buf = cdk_calloc (1, STREAM_BUFSIZE);
       s->cache.alloced = STREAM_BUFSIZE;
+#ifdef DEBUG_STREAM
       _gnutls_read_log ("stream: allocate cache of %d octets\n",
                         STREAM_BUFSIZE);
+#endif
     }
   return 0;
 }
@@ -1455,7 +1489,9 @@ cdk_stream_mmap_part (cdk_stream_t s, off_t off, size_t 
len,
   /* Memory mapping is not supported on custom I/O objects. */
   if (s->cbs_hd)
     {
+#ifdef DEBUG_STREAM
       _gnutls_read_log ("cdk_stream_mmap_part: not supported on callbacks\n");
+#endif
       gnutls_assert ();
       return CDK_Inv_Mode;
     }
@@ -1579,8 +1615,10 @@ _cdk_stream_set_blockmode (cdk_stream_t s, size_t nbytes)
 {
   assert (s);
 
+#ifdef DEBUG_STREAM
   _gnutls_read_log ("stream: activate block mode with blocksize %d\n",
                     (int) nbytes);
+#endif
   s->blkmode = nbytes;
   return 0;
 }
diff --git a/lib/opencdk/write-packet.c b/lib/opencdk/write-packet.c
index 77b9db1..7a53e84 100644
--- a/lib/opencdk/write-packet.c
+++ b/lib/opencdk/write-packet.c
@@ -369,57 +369,81 @@ write_signature (cdk_stream_t out, cdk_pkt_signature_t 
sig, int old_ctb)
     return CDK_Inv_Value;
 
   if (!KEY_CAN_SIGN (sig->pubkey_algo))
-    return CDK_Inv_Algo;
+    return gnutls_assert_val(CDK_Inv_Algo);
   if (sig->version < 2 || sig->version > 4)
-    return CDK_Inv_Packet;
+    return gnutls_assert_val(CDK_Inv_Packet);
 
   if (DEBUG_PKT)
     _gnutls_write_log ("write_signature:\n");
 
   nsig = cdk_pk_get_nsig (sig->pubkey_algo);
   if (!nsig)
-    return CDK_Inv_Algo;
+    return gnutls_assert_val(CDK_Inv_Algo);
   if (sig->version < 4)
     return write_v3_sig (out, sig, nsig);
 
   size = 10 + calc_subpktsize (sig->hashed)
     + calc_subpktsize (sig->unhashed) + calc_mpisize (sig->mpi, nsig);
+
   rc = pkt_write_head (out, 0, size, CDK_PKT_SIGNATURE);
-  if (!rc)
-    rc = stream_putc (out, 4);
-  if (!rc)
-    rc = stream_putc (out, sig->sig_class);
-  if (!rc)
-    rc = stream_putc (out, _cdk_pub_algo_to_pgp (sig->pubkey_algo));
-  if (!rc)
-    rc = stream_putc (out, _gnutls_hash_algo_to_pgp (sig->digest_algo));
-  if (!rc)
-    rc = write_16 (out, sig->hashed_size);
-  if (!rc)
-    {
-      buf = _cdk_subpkt_get_array (sig->hashed, 0, &nbytes);
-      if (!buf)
-        return CDK_Out_Of_Core;
-      rc = stream_write (out, buf, nbytes);
-      cdk_free (buf);
-    }
-  if (!rc)
-    rc = write_16 (out, sig->unhashed_size);
-  if (!rc)
-    {
-      buf = _cdk_subpkt_get_array (sig->unhashed, 0, &nbytes);
-      if (!buf)
-        return CDK_Out_Of_Core;
-      rc = stream_write (out, buf, nbytes);
-      cdk_free (buf);
-    }
-  if (!rc)
-    rc = stream_putc (out, sig->digest_start[0]);
-  if (!rc)
-    rc = stream_putc (out, sig->digest_start[1]);
-  if (!rc)
-    rc = write_mpibuf (out, sig->mpi, nsig);
-  return rc;
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  rc = stream_putc (out, 4);
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  rc = stream_putc (out, sig->sig_class);
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  rc = stream_putc (out, _cdk_pub_algo_to_pgp (sig->pubkey_algo));
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  rc = stream_putc (out, _gnutls_hash_algo_to_pgp (sig->digest_algo));
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  rc = write_16 (out, sig->hashed_size);
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  buf = _cdk_subpkt_get_array (sig->hashed, 0, &nbytes);
+  if (!buf)
+    return gnutls_assert_val(CDK_Out_Of_Core);
+
+  rc = stream_write (out, buf, nbytes);
+  cdk_free (buf);
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  rc = write_16 (out, sig->unhashed_size);
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  buf = _cdk_subpkt_get_array (sig->unhashed, 0, &nbytes);
+  if (!buf)
+    return gnutls_assert_val(CDK_Out_Of_Core);
+
+  rc = stream_write (out, buf, nbytes);
+  cdk_free (buf);
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  rc = stream_putc (out, sig->digest_start[0]);
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  rc = stream_putc (out, sig->digest_start[1]);
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  rc = write_mpibuf (out, sig->mpi, nsig);
+  if (rc)
+    return gnutls_assert_val(rc);
+
+  return 0;
 }
 
 
@@ -776,7 +800,9 @@ cdk_pkt_write (cdk_stream_t out, cdk_packet_t pkt)
   if (!out || !pkt)
     return CDK_Inv_Value;
 
-  _gnutls_write_log ("write packet pkttype=%d\n", pkt->pkttype);
+  if (DEBUG_PKT)
+    _gnutls_write_log ("write packet pkttype=%d\n", pkt->pkttype);
+
   switch (pkt->pkttype)
     {
     case CDK_PKT_LITERAL:
diff --git a/tests/mini-dtls-heartbeat.c b/tests/mini-dtls-heartbeat.c
index 1d502f9..ddda127 100644
--- a/tests/mini-dtls-heartbeat.c
+++ b/tests/mini-dtls-heartbeat.c
@@ -180,8 +180,6 @@ client (int fd, int server_init)
 
     gnutls_bye (session, GNUTLS_SHUT_WR);
 
-  end:
-
     close (fd);
 
     gnutls_deinit (session);
diff --git a/tests/suite/Makefile.am b/tests/suite/Makefile.am
index c938e9a..0ed7437 100644
--- a/tests/suite/Makefile.am
+++ b/tests/suite/Makefile.am
@@ -86,6 +86,6 @@ nodist_eagain_cli_SOURCES = mini-eagain2.c
 
 noinst_PROGRAMS = eagain-cli
 
-nodist_check_SCRIPTS = eagain testsrn testcompat chain invalid-cert
+nodist_check_SCRIPTS = eagain testsrn testcompat chain invalid-cert testrandom
 
 TESTS = eagain testsrn testcompat chain invalid-cert
diff --git a/tests/suite/asn1random.pl b/tests/suite/asn1random.pl
new file mode 100755
index 0000000..e967f68
--- /dev/null
+++ b/tests/suite/asn1random.pl
@@ -0,0 +1,118 @@
+#!/usr/bin/perl -w
+#
+# Generate random but valid ASN.1 data.
+#
+# Format:
+#
+#      asn1random.pl >output
+#
+use strict;
+
+my $depth = 0;
+my $maxdepth = 12;
+
+#print STDERR "SEED: ", srand(), "\n";
+
+###############################################################################
+#
+# Generate a header
+#
+###############################################################################
+sub emit_asn1_hdr($$)
+{
+    my ($tag, $len) = @_;
+    my $output = "";
+    my $l;
+
+    if ($len < 0x80) {
+       $l = $len;
+    } elsif ($len <= 0xff) {
+       $l = 0x81;
+    } elsif ($len <= 0xffff) {
+       $l = 0x82;
+    } elsif ($len <= 0xffffff) {
+       $l = 0x83;
+    } else {
+       $l = 0x84;
+    }
+
+    $output .= pack("CC", $tag == -1 ? int(rand(255)) & ~0x20 : $tag, $l);
+    if ($len < 0x80) {
+    } elsif ($len <= 0xff) {
+       $output .= pack("C", $len);
+    } elsif ($len <= 0xffff) {
+       $output .= pack("n", $len);
+    } elsif ($len <= 0xffffff) {
+       $output .= pack("Cn", $len >> 16, $len & 0xffff);
+    } else {
+       $output .= pack("N", $len);
+    }
+
+    return $output;
+}
+
+###############################################################################
+#
+# Generate a random primitive
+#
+###############################################################################
+sub emit_asn1_prim($)
+{
+    my ($tag) = @_;
+    my $output;
+    my $len = int(rand(255));
+
+    $tag = int(rand(255)) & ~0x20
+       if ($tag == -1);
+
+    $output = emit_asn1_hdr($tag, $len);
+
+    my $i = $len;
+    while ($i > 16) {
+       $output .= "abcdefghijklmnop";
+       $i -= 16;
+    }
+
+    $output .= substr("abcdefghijklmnop", 0, $i);
+    return $output;
+}
+
+###############################################################################
+#
+# Generate a random construct
+#
+###############################################################################
+sub emit_asn1_cons($);
+sub emit_asn1_cons($)
+{
+    my $output = "";
+    my $count = int(rand(20));
+    my ($tag) = @_;
+
+    if ($depth >= $maxdepth) {
+       return emit_asn1_prim($tag);
+    }
+
+    if ($tag == -1) {
+       $tag = int(rand(255)) & ~0x20;
+       if ($tag < 0x40 && $tag != 0x11) {
+           $tag = 0x10;
+       }
+       $tag |= 0x20;
+    }
+
+    $depth++;
+    while ($count > 0) {
+       if (int(rand(4 + $depth)) == 1) {
+           $output .= emit_asn1_cons(-1);
+       } else {
+           $output .= emit_asn1_prim(-1);
+       }
+       $count--;
+    }
+    $depth--;
+
+    return emit_asn1_hdr($tag, length($output)) . $output;
+}
+
+print emit_asn1_cons(-1);
diff --git a/tests/cert-tests/aki b/tests/suite/testrandom
similarity index 51%
copy from tests/cert-tests/aki
copy to tests/suite/testrandom
index e0722a0..81ba75e 100755
--- a/tests/cert-tests/aki
+++ b/tests/suite/testrandom
@@ -1,8 +1,8 @@
 #!/bin/sh
 
-# Copyright (C) 2006-2008, 2010, 2012 Free Software Foundation, Inc.
+# Copyright (C) 2012 Free Software Foundation, Inc.
 #
-# Author: Simon Josefsson
+# Author: Nikos Mavrogiannopoulos
 #
 # This file is part of GnuTLS.
 #
@@ -20,22 +20,42 @@
 # along with GnuTLS; if not, write to the Free Software Foundation,
 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
-set -e
-
 srcdir=${srcdir:-.}
 CERTTOOL=${CERTTOOL:-../../src/certtool$EXEEXT}
 
-$CERTTOOL --certificate-info --infile $srcdir/aki-cert.pem \
-         --outfile tmp-aki.pem
-
-diff $srcdir/aki-cert.pem tmp-aki.pem
-rc=$?
-
-rm -f tmp-aki.pem
-
-# We're done.
-if test "$rc" != "0"; then
-  exit $rc
-fi
+counter=0
+file=test.out
+
+echo "Testing with randomly generated certificates..."
+while [ $counter -lt 200 ]
+do
+  $srcdir/x509random.pl > $srcdir/$file
+  $CERTTOOL -i --inder --infile $srcdir/$file >/dev/null
+  ret=$?
+  if [ $ret != 0 -a $ret != 1 ];then
+       echo "Unknown exit code with $file"
+       exit 1
+  fi
+
+  counter=`expr $counter + 1`
+done
+
+counter=0
+
+echo "Testing with random ASN.1 data..."
+while [ $counter -lt 200 ]
+do
+  $srcdir/asn1random.pl > $srcdir/$file
+  $CERTTOOL -i --inder --infile $srcdir/$file >/dev/null 2>/dev/null
+  ret=$?
+  if [ $ret != 0 -a $ret != 1 ];then
+       echo "Unknown exit code with $file"
+       exit 1
+  fi
+
+  counter=`expr $counter + 1`
+done
+
+rm -f $srcdir/$file
 
 exit 0
diff --git a/tests/suite/x509random.pl b/tests/suite/x509random.pl
new file mode 100755
index 0000000..5144e29
--- /dev/null
+++ b/tests/suite/x509random.pl
@@ -0,0 +1,401 @@
+#!/usr/bin/perl -w
+#
+# Author David Howells <address@hidden>
+#
+# Generate validly formatted X.509 certificates filled with mostly random data,
+# including for the RSA key and signature fields (so it is extremely improbable
+# that key will be useful and the signature will verify).
+#
+# If an argument of any sort is passed this will cause random bytes to be
+# inserted into the ASN.1 structure (whilst keeping the lengths of the wrapping
+# constructed elements correct).
+#
+# Format:
+#
+#      x509random.pl [-i] >output
+#
+use strict;
+
+#print STDERR "SEED: ", srand(), "\n";
+
+my $do_inject = ($#ARGV == 0);
+
+my $UNIV = 0 << 6;
+my $APPL = 1 << 6;
+my $CONT = 2 << 6;
+my $PRIV = 3 << 6;
+
+my $BOOLEAN    = 0x01;
+my $INTEGER    = 0x02;
+my $BIT_STRING = 0x03;
+my $OCTET_STRING = 0x04;
+my $NULL       = 0x05;
+my $OBJ_ID     = 0x06;
+my $UTF8String = 0x0c;
+my $SEQUENCE   = 0x10;
+my $SET                = 0x11;
+my $UTCTime    = 0x17;
+my $GeneralizedTime = 0x18;
+
+sub maybe($)
+{
+    return (int(rand(6)) == 0) ? '' : $_[0];
+}
+
+###############################################################################
+#
+# Generate a header
+#
+###############################################################################
+sub emit_asn1_hdr($$)
+{
+    my ($tag, $len) = @_;
+    my $output = "";
+    my $l;
+
+    if ($len < 0x80) {
+       $l = $len;
+    } elsif ($len <= 0xff) {
+       $l = 0x81;
+    } elsif ($len <= 0xffff) {
+       $l = 0x82;
+    } elsif ($len <= 0xffffff) {
+       $l = 0x83;
+    } else {
+       $l = 0x84;
+    }
+
+    $output .= pack("CC", $tag == -1 ? int(rand(255)) & ~0x20 : $tag, $l);
+    if ($len < 0x80) {
+    } elsif ($len <= 0xff) {
+       $output .= pack("C", $len);
+    } elsif ($len <= 0xffff) {
+       $output .= pack("n", $len);
+    } elsif ($len <= 0xffffff) {
+       $output .= pack("Cn", $len >> 16, $len & 0xffff);
+    } else {
+       $output .= pack("N", $len);
+    }
+
+    return $output;
+}
+
+###############################################################################
+#
+# Generate random data
+#
+###############################################################################
+sub emit_random_data($$)
+{
+    my ($minlen, $maxlen) = @_;
+    my $output = '';
+
+    my $len = $minlen + int(rand($maxlen - $minlen));
+
+    my $i = $len;
+    while ($i > 16) {
+       $output .= "abcdefghijklmnop";
+       $i -= 16;
+    }
+
+    $output .= substr("abcdefghijklmnop", 0, $i);
+    return $output;
+}
+
+###############################################################################
+#
+# Generate a primitive containing some random data
+#
+###############################################################################
+sub emit_asn1_prim(@)
+{
+    my ($class, $tag, $minlen, $maxlen) = @_;
+    my $content;
+
+    $minlen = 0 if (!$minlen);
+    $maxlen = 255 if (!$maxlen);
+    $content = ($tag == $NULL) ? '' : emit_random_data($minlen, $maxlen);
+
+    $tag |= $class;
+    return emit_asn1_hdr($tag, length($content)) . $content;
+}
+
+###############################################################################
+#
+# Generate an object identifier
+#
+###############################################################################
+my %OIDs = (
+    commonName => pack("CCC", 85, 4, 3),
+    countryName => pack("CCC", 85, 4, 6),
+    organizationName => pack("CCC", 85, 4, 10),
+    organizationUnitName => pack("CCC", 85, 4, 11),
+    rsaEncryption => pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 1),
+    sha1WithRSAEncryption => pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 
1, 5),
+    authorityKeyIdentifier => pack("CCC", 85, 29, 35),
+    subjectKeyIdentifier => pack("CCC", 85, 29, 14),
+    basicConstraints => pack("CCC", 85, 29, 19)
+);
+
+sub emit_asn1_OID($$$)
+{
+    my ($class, $tag, $oid_name) = @_;
+    my $oid;
+    my $len;
+
+    if (!exists($OIDs{$oid_name})) {
+       print STDERR "Unknown OID: $oid_name\n";
+       exit(2);
+    }
+
+    $oid = $OIDs{$oid_name};
+    $len = length($oid);
+
+    $tag |= $class;
+
+    return emit_asn1_hdr($tag, $len) . $oid;
+}
+
+###############################################################################
+#
+# Generate a UTC time
+#
+###############################################################################
+sub emit_asn1_utctime($$)
+{
+    my ($class, $tag) = @_;
+    my $output = "";
+    my $len;
+
+    for (my $i = 0; $i < 12; $i++) {
+       $output .= pack("C", int(rand(9)) + 0x30);
+    }
+    $output .= 'Z';
+
+    $len = length($output);
+
+    $tag |= $class;
+
+    return emit_asn1_hdr($tag, $len) . $output;
+}
+
+###############################################################################
+#
+# Generate a generalized time
+#
+###############################################################################
+sub emit_asn1_gentime($$)
+{
+    my ($class, $tag) = @_;
+    my $output = "";
+    my $len;
+
+    for (my $i = 0; $i < 14; $i++) {
+       $output .= pack("C", int(rand(9)) + 0x30);
+    }
+    $output .= 'Z';
+
+    $len = length($output);
+
+    $tag |= $class;
+
+    return emit_asn1_hdr($tag, $len) . $output;
+}
+
+###############################################################################
+#
+# Generate a construct
+#
+###############################################################################
+sub emit_asn1_cons($$$)
+{
+    my ($class, $tag, $content) = @_;
+    my $inject = '';
+
+    if ($do_inject) {
+       if (int(rand(20)) == 0) {
+           $inject = pack("C", int(rand(255)));
+       }
+    }
+
+    $tag |= $class | 0x20;
+    return emit_asn1_hdr($tag, length($content)) . $content . $inject;
+}
+
+###############################################################################
+#
+# Generate a name
+#
+###############################################################################
+sub emit_x509_AttributeValueAssertion($@)
+{
+    my ($type, $min, $max) = @_;
+    my $output;
+    $output  = emit_asn1_OID($UNIV, $OBJ_ID, $type);   # attributeType
+    $output .= emit_asn1_prim($UNIV, $UTF8String, $min, $max); # attributeValue
+    return emit_asn1_cons($UNIV, $SEQUENCE, $output);
+}
+
+sub emit_x509_RelativeDistinguishedName()
+{
+    my $output;
+    # Set of AttributeValueAssertion
+    $output  = emit_x509_AttributeValueAssertion("countryName", 2, 2);
+    $output .= emit_x509_AttributeValueAssertion("organizationName", 3, 10);
+    $output .= emit_x509_AttributeValueAssertion("organizationUnitName", 3, 
10);
+    $output .= emit_x509_AttributeValueAssertion("commonName", 4, 16);
+    return emit_asn1_cons($UNIV, $SET, $output);
+}
+
+sub emit_x509_Name()
+{
+    my $output;
+    # Sequence of RDN
+    $output  = emit_x509_RelativeDistinguishedName();
+    return emit_asn1_cons($UNIV, $SEQUENCE, $output);
+}
+
+###############################################################################
+#
+# Generate some X.509 extensions
+#
+###############################################################################
+sub emit_x509_SubjectKeyIdentifier()
+{
+    my $content = emit_asn1_prim($UNIV, $OCTET_STRING, 10, 20);
+    return $content;
+}
+
+sub emit_x509_AuthorityKeyIdentifier()
+{
+    my $content = emit_asn1_prim($CONT, 0, 10, 20);
+    my $wrapper = emit_asn1_cons($UNIV, $SEQUENCE, $content);
+    return $wrapper;
+}
+
+sub emit_x509_BasicConstraints()
+{
+    my $content = emit_asn1_prim($UNIV, $BIT_STRING, 1, 7);
+    return $content;
+}
+
+sub emit_x509_Extension($)
+{
+    my ($ext) = @_;
+    my $output;
+    my $value = "";
+
+    if ($ext eq "authorityKeyIdentifier") {
+       $output = emit_asn1_OID($UNIV, $OBJ_ID, $ext);
+       $value = emit_x509_AuthorityKeyIdentifier();
+    } elsif ($ext eq "subjectKeyIdentifier") {
+       $output = emit_asn1_OID($UNIV, $OBJ_ID, $ext);
+       $value = emit_x509_SubjectKeyIdentifier();
+    } elsif ($ext eq "basicConstraints") {
+       $output = emit_asn1_OID($UNIV, $OBJ_ID, $ext);
+       $value = emit_x509_BasicConstraints();
+    } else {
+       $output = emit_asn1_prim($UNIV, $OBJ_ID, 3, 10);
+       $value = emit_random_data(10, 20);
+    }
+
+    $output .= maybe emit_asn1_prim($UNIV, $BOOLEAN, 1, 1);    # critical
+    $output .= emit_asn1_hdr($UNIV | $OCTET_STRING, length($value)) . $value;
+
+    return emit_asn1_cons($UNIV, $SEQUENCE, $output);
+}
+
+sub emit_x509_Extensions()
+{
+    my $output = "";
+
+    # Probably do want a sequence of extensions here
+    $output .= maybe emit_x509_Extension("authorityKeyIdentifier");
+    $output .= maybe emit_x509_Extension("subjectKeyIdentifier");
+    $output .= maybe emit_x509_Extension("basicConstraints");
+    $output .= maybe emit_x509_Extension("");
+    $output .= maybe emit_x509_Extension("");
+    $output .= maybe emit_x509_Extension("");
+    $output .= maybe emit_x509_Extension("");
+
+    return emit_asn1_cons($CONT, 3, emit_asn1_cons($UNIV, $SEQUENCE, $output));
+}
+
+###############################################################################
+#
+# Generate an X.509 certificate
+#
+###############################################################################
+sub emit_x509_Time()
+{
+    # UTCTime or GeneralizedTime
+    if (int(rand(2)) == 0) {
+       return emit_asn1_utctime($UNIV, $UTCTime);
+    } else {
+       return emit_asn1_gentime($UNIV, $GeneralizedTime);
+    }
+}
+
+sub emit_x509_Validity()
+{
+    my $output;
+    $output  = emit_x509_Time();                       # notBefore
+    $output .= emit_x509_Time();                       # notAfter
+    return emit_asn1_cons($UNIV, $SEQUENCE, $output);
+}
+
+sub emit_x509_AlgorithmIdentifier($)
+{
+    my ($oid) = @_;
+    my $output;
+ 
+    #$output  = emit_asn1_prim($UNIV, $OBJ_ID);                # algorithm
+    $output  = emit_asn1_OID($UNIV, $OBJ_ID, $oid); # algorithm
+    $output .= emit_asn1_prim($UNIV, $NULL);           # parameters
+    return emit_asn1_cons($UNIV, $SEQUENCE, $output);
+}
+
+sub emit_x509_Version()
+{
+    my $output = emit_asn1_prim($UNIV, $INTEGER, 0, 3);
+    return emit_asn1_cons($CONT, 0, $output);
+}
+
+sub emit_x509_SubjectPublicKeyInfo()
+{
+    my $output;
+    $output  = emit_x509_AlgorithmIdentifier("rsaEncryption"); # algorithm
+    $output .= emit_asn1_prim($UNIV, $BIT_STRING);     # subjectPublicKey
+    return emit_asn1_cons($UNIV, $SEQUENCE, $output);
+}
+
+sub emit_x509_TBSCertificate()
+{
+    my $output;
+
+    $output  = emit_x509_Version;                      # version
+    $output .= emit_asn1_prim($UNIV, $INTEGER);                # serialNumber
+    $output .= emit_x509_AlgorithmIdentifier("sha1WithRSAEncryption"); # 
signature
+    $output .= emit_x509_Name();                       # issuer
+    $output .= emit_x509_Validity();                   # validity
+    $output .= emit_x509_Name();                       # subject
+    $output .= emit_x509_SubjectPublicKeyInfo();       # subjectPublicKeyInfo
+    $output .= maybe emit_asn1_prim($CONT, 1);         # issuerUniqueID
+    $output .= maybe emit_asn1_prim($CONT, 2);         # subjectUniqueID
+    $output .= emit_x509_Extensions();                 # extensions
+
+    return emit_asn1_cons($UNIV, $SEQUENCE, $output);
+}
+
+sub emit_x509_Certificate()
+{
+    my $output;
+
+    $output  = emit_x509_TBSCertificate();             # tbsCertificate
+    $output .= emit_x509_AlgorithmIdentifier("sha1WithRSAEncryption"); # 
signatureAlgorithm
+    $output .= emit_asn1_prim($UNIV, $BIT_STRING);     # signature
+
+    return emit_asn1_cons($UNIV, $SEQUENCE, $output);
+}
+
+print emit_x509_Certificate();


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]