예제 #1
0
파일: context.c 프로젝트: acasajus/pyGSI
/*
 * Globally defined verify callback
 *
 * Arguments: ok       - True everything is OK "so far", false otherwise
 *            x509_ctx - Contains the certificate being checked, the current
 *                       error number and depth, and the Connection we're
 *                       dealing with
 * Returns:   True if everything is okay, false otherwise
 */
static int global_verify_callback( int ok, X509_STORE_CTX * x509_ctx )
{
	PyObject *argv, *ret;

	SSL *ssl;

	ssl_ConnectionObj *conn;

	crypto_X509Obj *cert;

	X509 *x509;

	int errnum = X509_STORE_CTX_get_error(x509_ctx);

	int errdepth = X509_STORE_CTX_get_error_depth(x509_ctx);

#ifdef GSI_HANDSHAKE_DEBUG
	logMsg( 0, "GVC %d errnum %d errdepth", errnum, errdepth );
#endif

	ssl = (SSL *) X509_STORE_CTX_get_app_data(x509_ctx);
	conn = (ssl_ConnectionObj *) SSL_get_app_data(ssl);
	OBJ_END_THREADS( conn );
	Py_INCREF( conn );

	if ( conn->context->verify_callback != Py_None )
	{
		x509 = X509_STORE_CTX_get_current_cert(x509_ctx);

		cert = crypto_X509_New(x509, 0);
		argv = Py_BuildValue("(OOiii)", (PyObject *) conn, (PyObject *) cert,
				errnum, errdepth, ok);
		Py_DECREF(cert);
		/* We need to get back our thread state before calling the callback */
		ret = PyEval_CallObject(conn->context->verify_callback, argv);
		Py_DECREF(argv);

		if ( ret == NULL )
		{
			ok = 0;
		}
		else
		{
			if ( PyObject_IsTrue(ret) )
			{
				X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
				ok = 1;
			}
			else
				ok = 0;

			Py_DECREF(ret);
		}
	}

	//Set the remove verification flag in the end
	if ( errdepth == 0 && ok )
	{
		conn->remoteCertVerified = 1;
	}

	Py_DECREF( conn );
	OBJ_BEGIN_THREADS( conn );

	return ok;
}
예제 #2
0
파일: pkcs12.c 프로젝트: 15580056814/hue
/*
 * Constructor for PKCS12 objects, never called by Python code directly.
 * The strategy for this object is to create all the Python objects
 * corresponding to the cert/key/CA certs right away
 *
 * Arguments: p12        - A "real" PKCS12 object or NULL
 *            passphrase - Passphrase to use when decrypting the PKCS12 object
 * Returns:   The newly created PKCS12 object
 */
crypto_PKCS12Obj *
crypto_PKCS12_New(PKCS12 *p12, char *passphrase) {
    crypto_PKCS12Obj *self = NULL;
    PyObject *cacertobj = NULL;

    unsigned char *alias_str;
    int alias_len;

    X509 *cert = NULL;
    EVP_PKEY *pkey = NULL;
    STACK_OF(X509) *cacerts = NULL;

    int i, cacert_count = 0;

    /* allocate space for the CA cert stack */
    if((cacerts = sk_X509_new_null()) == NULL) {
        goto error;   /* out of memory? */
    }

    /* parse the PKCS12 lump */
    if (p12) {
        if (!PKCS12_parse(p12, passphrase, &pkey, &cert, &cacerts)) {
	    /*
             * If PKCS12_parse fails, and it allocated cacerts, it seems to
             * free cacerts, but not re-NULL the pointer.  Zounds!  Make sure
             * it is re-set to NULL here, else we'll have a double-free below.
             */
            cacerts = NULL;
            exception_from_error_queue(crypto_Error);
            goto error;
        } else {
	  /*
	   * OpenSSL 1.0.0 sometimes leaves an X509_check_private_key error in
	   * the queue for no particular reason.  This error isn't interesting
	   * to anyone outside this function.  It's not even interesting to
	   * us.  Get rid of it.
	   */
	  flush_error_queue();
	}
    }

    if (!(self = PyObject_GC_New(crypto_PKCS12Obj, &crypto_PKCS12_Type))) {
        goto error;
    }

    /* client certificate and friendlyName */
    if (cert == NULL) {
        Py_INCREF(Py_None);
        self->cert = Py_None;
        Py_INCREF(Py_None);
        self->friendlyname = Py_None;
    } else {
        if ((self->cert = (PyObject *)crypto_X509_New(cert, 1)) == NULL) {
            goto error;
        }

        /*  Now we need to extract the friendlyName of the PKCS12
         *  that was stored by PKCS_parse() in the alias of the
         *  certificate. */
        alias_str = X509_alias_get0(cert, &alias_len);
        if (alias_str) {
            self->friendlyname = Py_BuildValue(BYTESTRING_FMT "#", alias_str, alias_len);
            if (!self->friendlyname) {
                /*
                 * XXX Untested
                 */
                goto error;
            }
            /* success */
        } else {
            Py_INCREF(Py_None);
            self->friendlyname = Py_None;
        }
    }

    /* private key */
    if (pkey == NULL) {
        Py_INCREF(Py_None);
        self->key = Py_None;
    } else {
        if ((self->key = (PyObject *)crypto_PKey_New(pkey, 1)) == NULL)
            goto error;
    }

    /* CA certs */
    cacert_count = sk_X509_num(cacerts);
    if (cacert_count <= 0) {
        Py_INCREF(Py_None);
        self->cacerts = Py_None;
    } else {
        if ((self->cacerts = PyTuple_New(cacert_count)) == NULL) {
            goto error;
        }

        for (i = 0; i < cacert_count; i++) {
            cert = sk_X509_value(cacerts, i);
            if ((cacertobj = (PyObject *)crypto_X509_New(cert, 1)) == NULL) {
                goto error;
            }
            PyTuple_SET_ITEM(self->cacerts, i, cacertobj);
        }
    }

    sk_X509_free(cacerts); /* Don't free the certs, just the container. */
    PyObject_GC_Track(self);

    return self;

error:
    sk_X509_free(cacerts); /* NULL safe. Free just the container. */
    if (self) {
        crypto_PKCS12_clear(self);
        PyObject_GC_Del(self);
    }
    return NULL;
}