Fix names of extension types and subsequent fallout.
diff --git a/src/crypto/netscape_spki.c b/src/crypto/netscape_spki.c
index 4fa9d8d..51bb83e 100644
--- a/src/crypto/netscape_spki.c
+++ b/src/crypto/netscape_spki.c
@@ -243,7 +243,7 @@
 PyTypeObject crypto_NetscapeSPKI_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "NetscapeSPKI",
+    "OpenSSL.crypto.NetscapeSPKI",
     sizeof(crypto_NetscapeSPKIObj),
     0,
     (destructor)crypto_NetscapeSPKI_dealloc,
diff --git a/src/crypto/pkcs12.c b/src/crypto/pkcs12.c
index 2302242..c86b23f 100644
--- a/src/crypto/pkcs12.c
+++ b/src/crypto/pkcs12.c
@@ -514,7 +514,7 @@
 PyTypeObject crypto_PKCS12_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "PKCS12",
+    "OpenSSL.crypto.PKCS12",
     sizeof(crypto_PKCS12Obj),
     0,
     (destructor)crypto_PKCS12_dealloc,
diff --git a/src/crypto/pkcs7.c b/src/crypto/pkcs7.c
index 1cb0813..ad9cbae 100644
--- a/src/crypto/pkcs7.c
+++ b/src/crypto/pkcs7.c
@@ -177,7 +177,7 @@
 PyTypeObject crypto_PKCS7_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "PKCS7",
+    "OpenSSL.crypto.PKCS7",
     sizeof(crypto_PKCS7Obj),
     0,
     (destructor)crypto_PKCS7_dealloc,
diff --git a/src/crypto/x509.c b/src/crypto/x509.c
index e089d40..7d3e46d 100644
--- a/src/crypto/x509.c
+++ b/src/crypto/x509.c
@@ -800,7 +800,7 @@
 PyTypeObject crypto_X509_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "X509",
+    "OpenSSL.crypto.X509",
     sizeof(crypto_X509Obj),
     0,
     (destructor)crypto_X509_dealloc,
diff --git a/src/crypto/x509ext.c b/src/crypto/x509ext.c
index 90ef543..a8e5f14 100644
--- a/src/crypto/x509ext.c
+++ b/src/crypto/x509ext.c
@@ -256,7 +256,7 @@
 PyTypeObject crypto_X509Extension_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "X509Extension",
+    "OpenSSL.crypto.X509Extension",
     sizeof(crypto_X509ExtensionObj),
     0,
     (destructor)crypto_X509Extension_dealloc, 
diff --git a/src/crypto/x509name.c b/src/crypto/x509name.c
index 39fdcf8..3418d91 100644
--- a/src/crypto/x509name.c
+++ b/src/crypto/x509name.c
@@ -423,7 +423,7 @@
 PyTypeObject crypto_X509Name_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "X509Name",
+    "OpenSSL.crypto.X509Name",
     sizeof(crypto_X509NameObj),
     0,
     (destructor)crypto_X509Name_dealloc,
diff --git a/src/crypto/x509req.c b/src/crypto/x509req.c
index 07bd44b..486df93 100644
--- a/src/crypto/x509req.c
+++ b/src/crypto/x509req.c
@@ -372,7 +372,7 @@
 PyTypeObject crypto_X509Req_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "X509Req",
+    "OpenSSL.crypto.X509Req",
     sizeof(crypto_X509ReqObj),
     0,
     (destructor)crypto_X509Req_dealloc,
diff --git a/src/crypto/x509store.c b/src/crypto/x509store.c
index 16af3b0..ce67e46 100644
--- a/src/crypto/x509store.c
+++ b/src/crypto/x509store.c
@@ -109,7 +109,7 @@
 PyTypeObject crypto_X509Store_Type = {
     PyObject_HEAD_INIT(NULL)
     0,
-    "X509Store",
+    "OpenSSL.crypto.X509Store",
     sizeof(crypto_X509StoreObj),
     0,
     (destructor)crypto_X509Store_dealloc,
diff --git a/src/ssl/context.c b/src/ssl/context.c
index df7411f..d1ffbe8 100644
--- a/src/ssl/context.c
+++ b/src/ssl/context.c
@@ -335,36 +335,63 @@
     return Py_None;
 }
 
+static PyTypeObject *
+type_modified_error(const char *name)
+{
+    PyErr_Format(PyExc_RuntimeError,
+                 "OpenSSL.crypto's '%s' attribute has been modified",
+                 name);
+    return NULL;
+}
+
+static PyTypeObject *
+import_crypto_type(const char *name, size_t objsize)
+{
+    PyObject *module, *type;
+    PyTypeObject *res;
+    char modname[] = "OpenSSL.crypto";
+    char buffer[256] = "OpenSSL.crypto.";
+
+    if (strlen(buffer) + strlen(name) >= sizeof(buffer)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    strcat(buffer, name);
+    module = PyImport_ImportModule(modname);
+    if (module == NULL) {
+        return NULL;
+    }
+    type = PyObject_GetAttrString(module, name);
+    Py_DECREF(module);
+    if (type == NULL) {
+        return NULL;
+    }
+    if (!(PyType_Check(type))) {
+        Py_DECREF(type);
+        return type_modified_error(name);
+    }
+    res = (PyTypeObject *)type;
+    if (strcmp(buffer, res->tp_name) != 0 || res->tp_basicsize != objsize) {
+        Py_DECREF(type);
+        return type_modified_error(name);
+    }
+    return res;
+}
+
 static crypto_X509Obj *
-parse_certificate_argument(const char* format1, const char* format2, PyObject* args)
+parse_certificate_argument(const char* format, PyObject* args)
 {
     static PyTypeObject *crypto_X509_type = NULL;
     crypto_X509Obj *cert;
 
-    /* We need to check that cert really is an X509 object before
-       we deal with it. The problem is we can't just quickly verify
-       the type (since that comes from another module). This should
-       do the trick (reasonably well at least): Once we have one
-       verified object, we use it's type object for future
-       comparisons. */
-
     if (!crypto_X509_type)
     {
-	if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format1, &cert))
-	    return NULL;
-
-	if (strcmp(cert->ob_type->tp_name, "X509") != 0 || 
-	    cert->ob_type->tp_basicsize != sizeof(crypto_X509Obj))
-	{
-	    PyErr_SetString(PyExc_TypeError, "Expected an X509 object");
-	    return NULL;
-	}
-
-	crypto_X509_type = cert->ob_type;
+        crypto_X509_type = import_crypto_type("X509", sizeof(crypto_X509Obj));
+        if (!crypto_X509_type)
+            return NULL;
     }
-    else
-	if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format2, crypto_X509_type,
-			      &cert))
+    if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format,
+                          crypto_X509_type, &cert))
 	    return NULL;
     return cert;
 }
@@ -381,7 +408,7 @@
 {
     X509* cert_original;
     crypto_X509Obj *cert = parse_certificate_argument(
-        "O:add_extra_chain_cert", "O!:add_extra_chain_cert", args);
+        "O!:add_extra_chain_cert", args);
     if (cert == NULL)
     {
         return NULL;
@@ -471,7 +498,7 @@
 ssl_Context_use_certificate(ssl_ContextObj *self, PyObject *args)
 {
     crypto_X509Obj *cert = parse_certificate_argument(
-        "O:use_certificate", "O!:use_certificate", args);
+        "O!:use_certificate", args);
     if (cert == NULL) {
         return NULL;
     }
@@ -538,28 +565,12 @@
     static PyTypeObject *crypto_PKey_type = NULL;
     crypto_PKeyObj *pkey;
 
-    /* We need to check that cert really is a PKey object before
-       we deal with it. The problem is we can't just quickly verify
-       the type (since that comes from another module). This should
-       do the trick (reasonably well at least): Once we have one
-       verified object, we use it's type object for future
-       comparisons. */
-
     if (!crypto_PKey_type)
     {
-	if (!PyArg_ParseTuple(args, "O:use_privatekey", &pkey))
-	    return NULL;
-
-	if (strcmp(pkey->ob_type->tp_name, "OpenSSL.crypto.PKey") != 0 ||
-	    pkey->ob_type->tp_basicsize != sizeof(crypto_PKeyObj))
-	{
-	    PyErr_SetString(PyExc_TypeError, "Expected a PKey object");
-	    return NULL;
-	}
-
-	crypto_PKey_type = pkey->ob_type;
+        crypto_PKey_type = import_crypto_type("PKey", sizeof(crypto_PKeyObj));
+        if (!crypto_PKey_type)
+            return NULL;
     }
-    else
     if (!PyArg_ParseTuple(args, "O!:use_privatekey", crypto_PKey_type, &pkey))
         return NULL;