Some more misc tests
diff --git a/OpenSSL/crypto/x509req.c b/OpenSSL/crypto/x509req.c
index 07bd44b..14ae072 100644
--- a/OpenSSL/crypto/x509req.c
+++ b/OpenSSL/crypto/x509req.c
@@ -138,12 +138,14 @@
     Py_INCREF(Py_None);
     return Py_None;
 }
- 
+
 static char crypto_X509Req_verify_doc[] = "\n\
 Verifies a certificate request using the supplied public key\n\
 \n\
 @param key: a public key\n\
-@return: True if the signature is correct, False otherwise.\n\
+@return: True if the signature is correct.\n\
+@raise OpenSSL.crypto.Error: If the signature is invalid or there is a\n\
+    problem verifying the signature.\n\
 ";
 
 PyObject *
@@ -153,13 +155,13 @@
     crypto_PKeyObj *key;
     int answer;
 
-    if (!PyArg_ParseTuple(args, "O!:verify", &crypto_PKey_Type, &obj)) 
+    if (!PyArg_ParseTuple(args, "O!:verify", &crypto_PKey_Type, &obj)) {
         return NULL;
+    }
 
     key = (crypto_PKeyObj *)obj;
 
-    if ((answer = X509_REQ_verify(self->x509_req, key->pkey)) < 0)
-    {
+    if ((answer = X509_REQ_verify(self->x509_req, key->pkey)) <= 0) {
         exception_from_error_queue(crypto_Error);
         return NULL;
     }
@@ -213,7 +215,7 @@
         }
         sk_X509_EXTENSION_push(exts, ext->x509_extension);
     }
-    
+
     if (!X509_REQ_add_extensions(self->x509_req, exts))
     {
         sk_X509_EXTENSION_free(exts);
@@ -222,7 +224,7 @@
     }
 
     sk_X509_EXTENSION_free(exts);
-    
+
     Py_INCREF(Py_None);
     return Py_None;
 }
diff --git a/OpenSSL/test/test_crypto.py b/OpenSSL/test/test_crypto.py
index 13efb9a..168596e 100644
--- a/OpenSSL/test/test_crypto.py
+++ b/OpenSSL/test/test_crypto.py
@@ -269,6 +269,18 @@
         self.x509.set_notAfter(expire)
 
 
+    def test_str(self):
+        """
+        The string representation of L{X509Extension} instances as returned by
+        C{str} includes stuff.
+        """
+        # This isn't necessarily the best string representation.  Perhaps it
+        # will be changed/improved in the future.
+        self.assertEquals(
+            str(X509Extension('basicConstraints', True, 'CA:false')),
+            'CA:FALSE')
+
+
     def test_type(self):
         """
         L{X509Extension} and L{X509ExtensionType} refer to the same type object
@@ -852,6 +864,50 @@
         self.assertRaises(TypeError, request.get_subject, None)
 
 
+    def test_add_extensions(self):
+        """
+        L{X509Req.add_extensions} accepts a C{list} of L{X509Extension}
+        instances and adds them to the X509 request.
+        """
+        request = X509Req()
+        request.add_extensions([
+                X509Extension('basicConstraints', True, 'CA:false')])
+        # XXX Add get_extensions so the rest of this unit test can be written.
+
+
+    def test_add_extensions_wrong_args(self):
+        """
+        L{X509Req.add_extensions} raises L{TypeError} if called with the wrong
+        number of arguments or with a non-C{list}.  Or it raises L{ValueError}
+        if called with a C{list} containing objects other than L{X509Extension}
+        instances.
+        """
+        request = X509Req()
+        self.assertRaises(TypeError, request.add_extensions)
+        self.assertRaises(TypeError, request.add_extensions, object())
+        self.assertRaises(ValueError, request.add_extensions, [object()])
+        self.assertRaises(TypeError, request.add_extensions, [], None)
+
+
+    def test_sign(self):
+        """
+        L{X509Req.sign} succeeds when passed a private key object and a valid
+        digest function.  C{X509Req.verify} can be used to check the signature.
+        """
+        request = self.signable()
+        key = PKey()
+        key.generate_key(TYPE_RSA, 512)
+        request.set_pubkey(key)
+        request.sign(key, 'MD5')
+        pub = request.get_pubkey()
+        self.assertTrue(request.verify(pub))
+
+        # Make another key that won't verify.
+        key = PKey()
+        key.generate_key(TYPE_RSA, 512)
+        self.assertRaises(Error, request.verify, key)
+
+
 
 class X509Tests(TestCase, _PKeyInteractionTestsMixin):
     """
@@ -986,6 +1042,7 @@
         self.assertRaises(TypeError, set, "20040203040506Z", "20040203040506Z")
         self.assertRaises(TypeError, get, "foo bar")
 
+    # XXX ASN1_TIME (not GENERALIZEDTIME)
 
     def test_set_notBefore(self):
         """
@@ -1109,6 +1166,15 @@
             "A8:EB:07:F8:53:25:0A:F2:56:05:C5:A5:C4:C4:C7:15")
 
 
+    def test_invalid_digest_algorithm(self):
+        """
+        L{X509.digest} raises L{ValueError} if called with an unrecognized hash
+        algorithm.
+        """
+        cert = X509()
+        self.assertRaises(ValueError, cert.digest, "monkeys")
+
+
     def test_get_subject_wrong_args(self):
         """
         L{X509.get_subject} raises L{TypeError} if called with any arguments.
@@ -1609,6 +1675,33 @@
     """
     Tests for free-functions in the L{OpenSSL.crypto} module.
     """
+
+    def test_load_privatekey_invalid_format(self):
+        """
+        L{load_privatekey} raises L{ValueError} if passed an unknown filetype.
+        """
+        self.assertRaises(ValueError, load_privatekey, 100, root_key_pem)
+
+
+    def test_load_privatekey_invalid_passphrase_type(self):
+        """
+        L{load_privatekey} raises L{TypeError} if passed a passphrase that is
+        neither a c{str} nor a callable.
+        """
+        self.assertRaises(
+            TypeError,
+            load_privatekey,
+            FILETYPE_PEM, encryptedPrivateKeyPEMPassphrase, object())
+
+
+    def test_load_privatekey_wrong_args(self):
+        """
+        L{load_privatekey} raises L{TypeError} if called with the wrong number
+        of arguments.
+        """
+        self.assertRaises(TypeError, load_privatekey)
+
+
     def test_load_privatekey_wrongPassphrase(self):
         """
         L{load_privatekey} raises L{OpenSSL.crypto.Error} when it is passed an
@@ -1660,6 +1753,48 @@
         self.assertEqual(called, [False])
 
 
+    def test_dump_privatekey_wrong_args(self):
+        """
+        L{dump_privatekey} raises L{TypeError} if called with the wrong number
+        of arguments.
+        """
+        self.assertRaises(TypeError, dump_privatekey)
+
+
+    def test_dump_privatekey_unknown_cipher(self):
+        """
+        L{dump_privatekey} raises L{ValueError} if called with an unrecognized
+        cipher name.
+        """
+        key = PKey()
+        key.generate_key(TYPE_RSA, 512)
+        self.assertRaises(
+            ValueError, dump_privatekey,
+            FILETYPE_PEM, key, "zippers", "passphrase")
+
+
+    def test_dump_privatekey_invalid_passphrase_type(self):
+        """
+        L{dump_privatekey} raises L{TypeError} if called with a passphrase which
+        is neither a C{str} nor a callable.
+        """
+        key = PKey()
+        key.generate_key(TYPE_RSA, 512)
+        self.assertRaises(
+            TypeError,
+            dump_privatekey, FILETYPE_PEM, key, "blowfish", object())
+
+
+    def test_dump_privatekey_invalid_filetype(self):
+        """
+        L{dump_privatekey} raises L{ValueError} if called with an unrecognized
+        filetype.
+        """
+        key = PKey()
+        key.generate_key(TYPE_RSA, 512)
+        self.assertRaises(ValueError, dump_privatekey, 100, key)
+
+
     def test_dump_privatekey_passphrase(self):
         """
         L{dump_privatekey} writes an encrypted PEM when given a passphrase.
@@ -1775,6 +1910,8 @@
         # self.assertIdentical(PKCS7, PKCS7Type)
 
 
+    # XXX Opposite results for all these following methods
+
     def test_type_is_signed_wrong_args(self):
         pkcs7 = load_pkcs7_data(FILETYPE_PEM, pkcs7Data)
         self.assertRaises(TypeError, pkcs7.type_is_signed, None)
@@ -1851,6 +1988,12 @@
         nspki = NetscapeSPKI()
         self.assertTrue(isinstance(nspki, NetscapeSPKIType))
 
+    # XXX sign
+    # XXX verify
+    # XXX get_pubkey
+    # XXX set_pubkey
+    # XXX getattr
+
 
 class RevokedTests(TestCase):
     """