diff --git a/lib/modules/Standards.pmod/X509.pmod b/lib/modules/Standards.pmod/X509.pmod
index be0bcb035b9eb05c19a9e4064cb0a97060b7d973..d878976a1f7666d5752cb40898993e7a285e5033 100644
--- a/lib/modules/Standards.pmod/X509.pmod
+++ b/lib/modules/Standards.pmod/X509.pmod
@@ -1,23 +1,20 @@
 #pike __REAL_VERSION__
 //#pragma strict_types
 
-/* 
- * Some random functions for creating RFC-2459 style X.509 certificates.
- *
- */
+//! Functions to generate and validate RFC2459 style X.509 v3
+//! certificates.
 
 constant dont_dump_module = 1;
 
-#if constant(Standards.ASN1.Types.Sequence) && constant(Crypto.Hash)
+#if constant(Crypto.Hash)
 
 import Standards.ASN1.Types;
 import Standards.PKCS;
 
-// Note: Redump this module if you change X509_DEBUG
 #ifdef X509_DEBUG
-#define X509_WERR werror
+#define DBG(X ...) werror(X)
 #else
-#define X509_WERR
+#define DBG(X ...)
 #endif
 
 //!
@@ -59,7 +56,9 @@ UTC make_time(int t)
 		     second->second_no()));
 }
 
-//! Returns a mapping similar to that returned by gmtime
+//! Returns a mapping similar to that returned by gmtime. Returns
+//! @expr{0@} on invalid dates.
+//!
 //! @returns
 //!   @mapping
 //!     @member int "year"
@@ -79,8 +78,6 @@ mapping(string:int) parse_time(UTC asn1)
   if ( (sizeof(s) != 12) && (c != 'Z') )
     return 0;
 
-  /* NOTE: This relies on pike-0.7 not interpreting leading zeros as
-   * an octal prefix. */
   mapping(string:int) m = mkmapping( ({ "year", "mon", "mday",
 					"hour", "min", "sec" }),
 				     (array(int)) (s/2));
@@ -135,11 +132,15 @@ Sequence rsa_sha1_algorithm = Sequence( ({ Identifiers.rsa_sha1_id,
 
 Sequence dsa_sha1_algorithm = Sequence( ({ Identifiers.dsa_sha_id }) );
 
-//!
-Sequence make_tbs(object issuer, object algorithm,
-		object subject, object keyinfo,
-		object serial, int ttl,
-		array extensions)
+//! Creates the ASN.1 TBSCertificate sequence (see RFC2459 section
+//! 4.1) to be signed (TBS) by the CA. version is explicitly set to
+//! v3, validity is calculated based on time and @[ttl], and
+//! @[extensions] is optionally added to the sequence. issuerUniqueID
+//! and subjectUniqueID are not supported.
+Sequence make_tbs(Sequence issuer, Sequence algorithm,
+                  Sequence subject, Sequence keyinfo,
+                  Integer serial, int ttl,
+                  array extensions)
 {
   int now = time();
   Sequence validity = Sequence( ({ make_time(now), make_time(now + ttl) }) );
@@ -380,7 +381,7 @@ Verifier make_verifier(Object _keyinfo)
   }
 }
 
-//!
+//! Represents a TBSCertificate.
 class TBSCertificate
 {
   //!
@@ -424,7 +425,10 @@ class TBSCertificate
   //! optional
   object extensions;
 
-  //!
+  //! Populates the object from a certificate decoded into an ASN.1
+  //! Object. Returns the object on success, otherwise @expr{0@}. You
+  //! probably want to call @[decode_certificate] or even
+  //! @[verify_certificate].
   this_program init(Object asn1)
   {
     der = asn1->get_der();
@@ -432,7 +436,7 @@ class TBSCertificate
       return 0;
 
     array(Object) a = ([object(Sequence)]asn1)->elements;
-    X509_WERR("TBSCertificate: sizeof(a) = %d\n", sizeof(a));
+    DBG("TBSCertificate: sizeof(a) = %d\n", sizeof(a));
       
     if (sizeof(a) < 6)
       return 0;
@@ -453,12 +457,12 @@ class TBSCertificate
     } else
       version = 1;
 
-    X509_WERR("TBSCertificate: version = %d\n", version);
+    DBG("TBSCertificate: version = %d\n", version);
     if (a[0]->type_name != "INTEGER")
       return 0;
     serial = a[0]->value;
 
-    X509_WERR("TBSCertificate: serial = %s\n", (string) serial);
+    DBG("TBSCertificate: serial = %s\n", (string) serial);
       
     if ((a[1]->type_name != "SEQUENCE")
 	|| !sizeof(a[1]->elements )
@@ -467,13 +471,13 @@ class TBSCertificate
 
     algorithm = a[1];
 
-    X509_WERR("TBSCertificate: algorithm = %s\n", algorithm->debug_string());
+    DBG("TBSCertificate: algorithm = %s\n", algorithm->debug_string());
 
     if (a[2]->type_name != "SEQUENCE")
       return 0;
     issuer = a[2];
 
-    X509_WERR("TBSCertificate: issuer = %s\n", issuer->debug_string());
+    DBG("TBSCertificate: issuer = %s\n", issuer->debug_string());
 
     if ((a[3]->type_name != "SEQUENCE")
 	|| (sizeof(a[3]->elements) != 2))
@@ -485,27 +489,27 @@ class TBSCertificate
     if (!not_before)
       return 0;
       
-    X509_WERR("TBSCertificate: not_before = %O\n", not_before);
+    DBG("TBSCertificate: not_before = %O\n", not_before);
 
     not_after = parse_time(validity[1]);
     if (!not_after)
       return 0;
 
-    X509_WERR("TBSCertificate: not_after = %O\n", not_after);
+    DBG("TBSCertificate: not_after = %O\n", not_after);
 
     if (a[4]->type_name != "SEQUENCE")
       return 0;
     subject = a[4];
 
-    X509_WERR("TBSCertificate: keyinfo = %s\n", a[5]->debug_string());
+    DBG("TBSCertificate: keyinfo = %s\n", a[5]->debug_string());
       
     public_key = make_verifier(a[5]);
 
     if (!public_key)
       return 0;
 
-    X509_WERR("TBSCertificate: parsed public key. type = %s\n",
-	      public_key->type);
+    DBG("TBSCertificate: parsed public key. type = %s\n",
+        public_key->type);
 
     int i = 6;
     if (i == sizeof(a))
@@ -543,7 +547,8 @@ class TBSCertificate
   }
 }
 
-//!
+//! Decodes a certificate and verifies that it is structually sound.
+//! Returns a @[TBSCertificate] object if ok, otherwise @expr{0@}.
 TBSCertificate decode_certificate(string|object cert)
 {
   if (stringp (cert)) cert = Standards.ASN1.Decode.simple_der_decode(cert);
@@ -587,7 +592,7 @@ TBSCertificate verify_certificate(string s, mapping authorities)
   if (tbs->issuer->get_der() == tbs->subject->get_der())
   {
     /* A self signed certificate */
-    X509_WERR("Self signed certificate\n");
+    DBG("Self signed certificate\n");
     v = tbs->public_key;
   }
   else
@@ -699,7 +704,7 @@ mapping verify_certificate_chain(array(string) cert_chain,
         
         if(! caok)
         {
-          X509_WERR("a CA certificate does not have the CA basic constraint.\n");
+          DBG("a CA certificate does not have the CA basic constraint.\n");
           m->error_code = CERT_UNAUTHORIZED_CA;
           m->error_cert = idx;
           return m;
@@ -715,7 +720,7 @@ mapping verify_certificate_chain(array(string) cert_chain,
       // require trust, we're done.
       if(!v && require_trust)
       {
-         X509_WERR("we require trust, but haven't got it.\n");
+         DBG("we require trust, but haven't got it.\n");
         m->error_code = CERT_ROOT_UNTRUSTED;
         m->error_cert = idx;
         return m;
@@ -726,7 +731,7 @@ mapping verify_certificate_chain(array(string) cert_chain,
       {
         /* A self signed certificate */
         m->self_signed = 1;
-        X509_WERR("Self signed certificate\n");
+        DBG("Self signed certificate\n");
 
         // always trust our own authority first, even if it is self signed.
         if(!v) 
@@ -761,7 +766,7 @@ mapping verify_certificate_chain(array(string) cert_chain,
       // (more rootward) certificate?
       if(tbs->issuer->get_der() != chain_obj[idx-1]->subject->get_der())
       {
-        X509_WERR("issuer chain is broken!\n");
+        DBG("issuer chain is broken!\n");
         m->verified = 0;
         m->error_code = CERT_CHAIN_BROKEN;
         m->error_cert = idx;
@@ -779,7 +784,7 @@ mapping verify_certificate_chain(array(string) cert_chain,
                     chain_cert[idx]->elements[2]->value)
           && tbs)
       {
-        X509_WERR("signature is verified..\n");
+        DBG("signature is verified..\n");
         m->verified = 1;
 
         // if we're the root of the chain and we've verified, this is
@@ -791,7 +796,7 @@ mapping verify_certificate_chain(array(string) cert_chain,
       }
       else
       {
-        X509_WERR("signature _not_ verified...\n");
+        DBG("signature _not_ verified...\n");
         m->error_code = CERT_BAD_SIGNATURE;
         m->error_cert = idx;
         m->verified = 0;