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

[minion-cvs] Fix 3 outstanding MMTP issues: cert confusion, self-to-...



Update of /home/minion/cvsroot/src/minion/src
In directory moria.mit.edu:/tmp/cvs-serv20486/src/minion/src

Modified Files:
	crypt.c tls.c 
Log Message:
Fix 3 outstanding MMTP issues: cert confusion, self-to-self connections, avoid multiple connections to same server.

Index: crypt.c
===================================================================
RCS file: /home/minion/cvsroot/src/minion/src/crypt.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- crypt.c	16 Feb 2003 18:46:31 -0000	1.20
+++ crypt.c	28 Mar 2003 15:36:23 -0000	1.21
@@ -963,15 +963,16 @@
   "=private= key <rsa>.  The certificate\'s commonName field will be set to\n"
   "<cn>.  The key will be valid from <start_time> until <end_time>.\n"
   "All other fields will be given reasonable defaults.\n";
-
+/* DOCDOC new arguments */
 PyObject *
 mm_generate_cert(PyObject *self, PyObject *args, PyObject *kwargs)
 {
         /* ???? should be threadified? */
-        static char *kwlist[] = { "filename", "rsa", "cn",
+        static char *kwlist[] = { "filename", "rsa", "rsa_sign",
+                                  "cn", "cn_issuer",
                                   "start_time", "end_time", NULL };
-        char *filename, *cn;
-        PyObject *_rsa;
+        char *filename, *cn, *cn_issuer;
+        PyObject *_rsa, *_rsa_sign;
 
         /*
          * Python wants time to be a double. OpenSSL wants time_t.
@@ -982,17 +983,23 @@
         double start_time, end_time;
 
         RSA *rsa = NULL;
+        RSA *rsa_sign = NULL;
         EVP_PKEY *pkey = NULL;
+        EVP_PKEY *pkey_sign = NULL;
         BIO *out = NULL;
         X509 *x509 = NULL;
         X509_NAME *name = NULL;
+        X509_NAME *name_issuer = NULL;
         int nid;
         PyObject *retval;
         time_t time;
 
-        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!sdd:generate_cert",
+        if (!PyArg_ParseTupleAndKeywords(args, kwargs, 
+                                         "sO!O!ssdd:generate_cert",
                                          kwlist, &filename,
-                                         &mm_RSA_Type, &_rsa, &cn,
+                                         &mm_RSA_Type, &_rsa, 
+                                         &mm_RSA_Type, &_rsa_sign, 
+                                         &cn, &cn_issuer,
                                          &start_time, &end_time))
                 return NULL;
 
@@ -1004,25 +1011,41 @@
                 goto error;
         rsa = NULL;
 
+        if (!(rsa_sign = RSAPrivateKey_dup(((mm_RSA*)_rsa_sign)->rsa)))
+                goto error;
+        if (!(pkey_sign = EVP_PKEY_new()))
+                goto error;
+        if (!(EVP_PKEY_assign_RSA(pkey_sign, rsa_sign)))
+                goto error;
+        rsa_sign = NULL;
+
         if (!(x509 = X509_new()))
                 goto error;
         if (!(X509_set_version(x509, 2)))
                 goto error;
         if (!(ASN1_INTEGER_set(X509_get_serialNumber(x509),0L)))
                 goto error;
-        if (!(name = X509_NAME_new()))
-                goto error;
 
-#define SET_PART(part, val)                                     \
-        if ((nid = OBJ_txt2nid(part)) == NID_undef) goto error; \
-        if (!X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,\
+#define SET_PART(n, part, val)                                   \
+        if ((nid = OBJ_txt2nid(part)) == NID_undef) goto error;  \
+        if (!X509_NAME_add_entry_by_NID(n, nid, MBSTRING_ASC,    \
                                         val, -1, -1, 0)) goto error;
 
-        SET_PART("countryName", "US");
-        SET_PART("organizationName", "Mixminion network");
-        SET_PART("commonName", cn);
+        if (!(name = X509_NAME_new()))
+                goto error;
+        SET_PART(name, "countryName", "US");
+        SET_PART(name, "organizationName", "Mixminion network");
+        SET_PART(name, "commonName", cn);
 
-        if (!(X509_set_issuer_name(x509, name)))
+        if (!(name_issuer = X509_NAME_new()))
+                goto error;
+        SET_PART(name_issuer, "countryName", "US");
+        SET_PART(name_issuer, "organizationName", "Mixminion network");
+        SET_PART(name_issuer, "commonName", cn_issuer);
+
+        if (!(X509_set_issuer_name(x509, name_issuer)))
+                goto error;
+        if (!(X509_set_subject_name(x509, name)))
                 goto error;
 
         time = (time_t) start_time;
@@ -1033,7 +1056,7 @@
                 goto error;
         if (!(X509_set_pubkey(x509, pkey)))
                 goto error;
-        if (!(X509_sign(x509, pkey, EVP_md5())))
+        if (!(X509_sign(x509, pkey_sign, EVP_sha1())))
                 goto error;
 
         if (!(out = BIO_new_file(filename, "w")))
@@ -1053,12 +1076,18 @@
                 BIO_free(out);
         if (name)
                 X509_NAME_free(name);
+        if (name_issuer)
+                X509_NAME_free(name_issuer);
         if (x509)
                 X509_free(x509);
         if (rsa)
                 RSA_free(rsa);
+        if (rsa_sign)
+                RSA_free(rsa_sign);
         if (pkey)
                 EVP_PKEY_free(pkey);
+        if (pkey_sign)
+                EVP_PKEY_free(pkey_sign);
 
         return retval;
 }

Index: tls.c
===================================================================
RCS file: /home/minion/cvsroot/src/minion/src/tls.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- tls.c	20 Feb 2003 16:57:40 -0000	1.18
+++ tls.c	28 Mar 2003 15:36:23 -0000	1.19
@@ -2,6 +2,9 @@
 /* $Id$ */
 #include "_minionlib.h"
 
+/* XXXX REMOVE*/
+#include <stdio.h>
+
 #ifndef TRUNCATED_OPENSSL_INCLUDES
 #include <openssl/ssl.h>
 #include <openssl/tls1.h>
@@ -33,6 +36,9 @@
 /* Convenience macro to set a type error with a given string. */
 #define TYPE_ERR(s) PyErr_SetString(PyExc_TypeError, s)
 
+/* Convenience macro to set a tls error with a given string. */
+#define MM_TLS_ERR(s) PyErr_SetString(mm_TLSError, s)
+
 /* Convenience macro to set an error and quit if a 0-argument function
    was called with arguments.  (We can't just use 'METH_NOARGS', since
    that wasn't available in Python 2.0.) */
@@ -142,7 +148,7 @@
                                        TLS1_TXT_DHE_RSA_WITH_AES_128_SHA))
                 err = 1;
         if (!err && certfile &&
-            !SSL_CTX_use_certificate_file(ctx,certfile,SSL_FILETYPE_PEM))
+            !SSL_CTX_use_certificate_chain_file(ctx,certfile))
                 err = 1;
         if (!err && rsa) {
                 if (!(_rsa = RSAPrivateKey_dup(rsa->rsa)) ||
@@ -154,8 +160,13 @@
                         err = 1;
                 if (pkey)
                         EVP_PKEY_free(pkey);
+                if (!err && certfile) {
+                        if (!SSL_CTX_check_private_key(ctx))
+                                err = 1;
+                }
         }
 
+
         if (!err && dhfile) {
                 if ( !(bio = BIO_new_file(dhfile, "r")))
                         err = 1;
@@ -544,6 +555,66 @@
         return (PyObject*) result;
 }
 
+static char mm_TLSSock_verify_cert_and_get_identity_pk__doc__[] = 
+    "DOCDOC";
+
+static PyObject*
+mm_TLSSock_verify_cert_and_get_identity_pk(
+                        PyObject *self, PyObject *args, PyObject *kwargs)
+{
+        STACK_OF(X509) *chain = NULL;
+        X509 *cert = NULL;
+        X509 *id_cert = NULL;
+        SSL *ssl = NULL;
+        RSA *rsa = NULL;
+        EVP_PKEY *pkey = NULL;
+        mm_RSA *result;
+        int i;
+
+        assert(mm_TLSSock_Check(self));
+        FAIL_IF_ARGS();
+        
+        ssl = ((mm_TLSSock*)self)->ssl;
+        if (!(chain = SSL_get_peer_cert_chain(ssl))) {
+                mm_SSL_ERR(0); return NULL;
+        }
+        if (!(cert = SSL_get_peer_certificate(ssl))) {
+                mm_SSL_ERR(0); return NULL;
+        }
+        if (sk_X509_num(chain) != 2) {
+                MM_TLS_ERR("Wrong number of certificates in peer chain.");
+                return NULL;
+        }
+        for (i = 0; i < 2; ++i) {
+                id_cert = sk_X509_value(chain, i);
+                assert(id_cert);
+                if (X509_cmp(id_cert, cert) != 0)
+                        break;
+        }
+        if (!id_cert) {
+                MM_TLS_ERR("No distinct identity certificate found.");
+                return NULL;
+        }
+        if (!(pkey = X509_get_pubkey(id_cert))) {
+                mm_SSL_ERR(0); return NULL;
+        }
+        /* Is the signature correct? */
+        if (X509_verify(cert, pkey) <= 0) {
+                EVP_PKEY_free(pkey); mm_SSL_ERR(0); return NULL;
+        }
+        rsa = EVP_PKEY_get1_RSA(pkey);
+        EVP_PKEY_free(pkey);
+        if (!rsa) {
+                mm_SSL_ERR(0); return NULL;
+        }
+        if (!(result = PyObject_New(mm_RSA, &mm_RSA_Type))) {
+                RSA_free(rsa); PyErr_NoMemory(); return NULL;
+        }
+        result->rsa = rsa;
+
+        return (PyObject*) result;
+}
+
 static char mm_TLSSock_renegotiate__doc__[] =
     "tlssock.renegotate()\n\n"
     "Mark this connection as requiring renegotiation.  No renegotiation is\n"
@@ -624,6 +695,7 @@
         METHOD(mm_TLSSock, write),
         METHOD(mm_TLSSock, shutdown),
         METHOD(mm_TLSSock, get_peer_cert_pk),
+        METHOD(mm_TLSSock, verify_cert_and_get_identity_pk),
         METHOD(mm_TLSSock, fileno),
         METHOD(mm_TLSSock, do_handshake),
         METHOD(mm_TLSSock, renegotiate),