Esempio n. 1
0
/*
 * Given a X509_NAME object and a name identifier, set the corresponding
 * attribute to the given string. Used by the setattr function.
 *
 * Arguments: name  - The X509_NAME object
 *            nid   - The name identifier
 *            value - The string to set
 * Returns:   0 for success, -1 on failure
 */
static int
set_name_by_nid(X509_NAME *name, int nid, char *utf8string)
{
    X509_NAME_ENTRY *ne;
    int i, entry_count, temp_nid;

    /* If there's an old entry for this NID, remove it */
    entry_count = X509_NAME_entry_count(name);
    for (i = 0; i < entry_count; i++)
    {
        ne = X509_NAME_get_entry(name, i);
        temp_nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));
        if (temp_nid == nid)
        {
            ne = X509_NAME_delete_entry(name, i);
            X509_NAME_ENTRY_free(ne);
            break;
        }
    }

    /* Add the new entry */
    if (!X509_NAME_add_entry_by_NID(name, nid, MBSTRING_UTF8, 
				    (unsigned char *)utf8string,
				    -1, -1, 0))
    {
        exception_from_error_queue(crypto_Error);
        return -1;
    }
    return 0;
}
Esempio n. 2
0
@return: The public key\n\
";

static PyObject *
crypto_X509_get_pubkey(crypto_X509Obj *self, PyObject *args)
{
    crypto_PKeyObj *crypto_PKey_New(EVP_PKEY *, int);
    EVP_PKEY *pkey;
    crypto_PKeyObj *py_pkey;

    if (!PyArg_ParseTuple(args, ":get_pubkey"))
        return NULL;

    if ((pkey = X509_get_pubkey(self->x509)) == NULL)
    {
        exception_from_error_queue(crypto_Error);
        return NULL;
    }

    py_pkey = crypto_PKey_New(pkey, 1);
    if (py_pkey != NULL) {
        py_pkey->only_public = 1;
    }
    return (PyObject *)py_pkey;
}
Esempio n. 3
0
/*
 * String representation of an X509Name
 *
 * Arguments: self - The X509Name object
 * Returns:   A string representation of the object
 */
static PyObject *
crypto_X509Name_repr(crypto_X509NameObj *self)
{
    char tmpbuf[512] = "";
    char realbuf[512+64];

    if (X509_NAME_oneline(self->x509_name, tmpbuf, 512) == NULL)
    {
        exception_from_error_queue(crypto_Error);
        return NULL;
    }
    else
    {
        /* This is safe because tmpbuf is max 512 characters */
        sprintf(realbuf, "<X509Name object '%s'>", tmpbuf);
        return PyText_FromString(realbuf);
    }
}
Esempio n. 4
0
static PyObject *
ssl_Connection_get_client_ca_list(ssl_ConnectionObj *self, PyObject *args) {
    STACK_OF(X509_NAME) *CANames;
    PyObject *CAList;
    int i, n;

    if (!PyArg_ParseTuple(args, ":get_client_ca_list")) {
        return NULL;
    }
    CANames = SSL_get_client_CA_list(self->ssl);
    if (CANames == NULL) {
        return PyList_New(0);
    }
    n = sk_X509_NAME_num(CANames);
    CAList = PyList_New(n);
    if (CAList == NULL) {
        return NULL;
    }
    for (i = 0; i < n; i++) {
        X509_NAME *CAName;
        PyObject *CA;

        CAName = X509_NAME_dup(sk_X509_NAME_value(CANames, i));
        if (CAName == NULL) {
            Py_DECREF(CAList);
            exception_from_error_queue(ssl_Error);
            return NULL;
        }
        CA = (PyObject *)new_x509name(CAName, 1);
        if (CA == NULL) {
            X509_NAME_free(CAName);
            Py_DECREF(CAList);
            return NULL;
        }
        if (PyList_SetItem(CAList, i, CA)) {
            Py_DECREF(CA);
            Py_DECREF(CAList);
            return NULL;
        }
    }
    return CAList;
}
Esempio n. 5
0
/*
 * Print a nice text representation of the certificate request.
 */
static PyObject *
crypto_X509Extension_str(crypto_X509ExtensionObj *self)
{
    int str_len;
    char *tmp_str;
    PyObject *str;
    BIO *bio = BIO_new(BIO_s_mem());

    if (!X509V3_EXT_print(bio, self->x509_extension, 0, 0))
    {
        BIO_free(bio);
        exception_from_error_queue(crypto_Error);
        return NULL;
    }

    str_len = BIO_get_mem_data(bio, &tmp_str);
    str = PyText_FromStringAndSize(tmp_str, str_len);

    BIO_free(bio);

    return str;
}
Esempio n. 6
0
/*
 * Return a name string given a X509_NAME object and a name identifier. Used
 * by the getattr function.
 *
 * Arguments: name - The X509_NAME object
 *            nid  - The name identifier
 * Returns:   The name as a Python string object
 */
static int
get_name_by_nid(X509_NAME *name, int nid, char **utf8string)
{
    int entry_idx;
    X509_NAME_ENTRY *entry;
    ASN1_STRING *data;
    int len;

    if ((entry_idx = X509_NAME_get_index_by_NID(name, nid, -1)) == -1)
    {
        return 0;
    }
    entry = X509_NAME_get_entry(name, entry_idx);
    data = X509_NAME_ENTRY_get_data(entry);
    if ((len = ASN1_STRING_to_UTF8((unsigned char **)utf8string, data)) < 0)
    {
        exception_from_error_queue(crypto_Error);
        return -1;
    }

    return len;
}
Esempio n. 7
0
@return: modulus\n\
";

static PyObject *
crypto_X509_modulus(crypto_X509Obj *self, PyObject *args)
{
    EVP_PKEY *pkey;
    PyObject *str;
    char *tmp_str;
    int str_len;
    BIO *bio = BIO_new(BIO_s_mem());

    if (!PyArg_ParseTuple(args, ":modulus"))
    {
        BIO_free(bio);
        return NULL;
    }

    if ((pkey = X509_get_pubkey(self->x509)) == NULL)
    {
        BIO_free(bio);
        exception_from_error_queue(crypto_Error);
        return NULL;
    }

    if (pkey->type == EVP_PKEY_RSA)
        BN_print(bio, pkey->pkey.rsa->n);
    else
    if (pkey->type == EVP_PKEY_DSA)
        BN_print(bio, pkey->pkey.dsa->pub_key);

    EVP_PKEY_free(pkey);
    str_len = BIO_get_mem_data(bio, &tmp_str);
    str = PyString_FromStringAndSize(tmp_str, str_len);
    BIO_free(bio);

    return str;
}
Esempio n. 8
0
:return: The digest of the object\n\
";

static PyObject *
crypto_X509_digest(crypto_X509Obj *self, PyObject *args)
{
    unsigned char fp[EVP_MAX_MD_SIZE];
    char *tmp;
    char *digest_name;
    unsigned int len,i;
    PyObject *ret;
    const EVP_MD *digest;

    if (!PyArg_ParseTuple(args, "s:digest", &digest_name))
        return NULL;

    if ((digest = EVP_get_digestbyname(digest_name)) == NULL)
    {
        PyErr_SetString(PyExc_ValueError, "No such digest method");
        return NULL;
    }

    if (!X509_digest(self->x509,digest,fp,&len))
    {
        exception_from_error_queue(crypto_Error);
    }
    tmp = malloc(3*len+1);
    memset(tmp, 0, 3*len+1);
    for (i = 0; i < len; i++) {
        sprintf(tmp+i*3,"%02X:",fp[i]);
    }
    tmp[3*len-1] = 0;
    ret = PyBytes_FromStringAndSize(tmp,3*len-1);
    free(tmp);
    return ret;
}
Esempio n. 9
0
         wait for a ZeroReturnError on a recv() method call\n\
";
static PyObject *
ssl_Connection_shutdown(ssl_ConnectionObj *self, PyObject *args)
{
    int ret;

    if (!PyArg_ParseTuple(args, ":shutdown"))
        return NULL;

    MY_BEGIN_ALLOW_THREADS(self->tstate)
    ret = SSL_shutdown(self->ssl);
    MY_END_ALLOW_THREADS(self->tstate)

    if (PyErr_Occurred())
    {
        flush_error_queue();
        return NULL;
    }

    if (ret < 0)
    {
        exception_from_error_queue(ssl_Error);
        return NULL;
    }
    else if (ret > 0)
    {
        Py_INCREF(Py_True);
        return Py_True;
    }
    else
    {
        Py_INCREF(Py_False);
        return Py_False;
    }
}
Esempio n. 10
0
/*
 * Handle errors raised by BIO functions.
 *
 * Arguments: bio - The BIO object
 *            ret - The return value of the BIO_ function.
 * Returns: None, the calling function should return NULL;
 */
static void
handle_bio_errors(BIO* bio, int ret)
{
    if (BIO_should_retry(bio)) {
        if (BIO_should_read(bio)) {
            PyErr_SetNone(ssl_WantReadError);
        } else if (BIO_should_write(bio)) {
            PyErr_SetNone(ssl_WantWriteError);
        } else if (BIO_should_io_special(bio)) {
            /*
             * It's somewhat unclear what this means.  From the OpenSSL source,
             * it seems like it should not be triggered by the memory BIO, so
             * for the time being, this case shouldn't come up.  The SSL BIO
             * (which I think should be named the socket BIO) may trigger this
             * case if its socket is not yet connected or it is busy doing
             * something related to x509.
             */
            PyErr_SetString(PyExc_ValueError, "BIO_should_io_special");
        } else {
            /*
             * I hope this is dead code.  The BIO documentation suggests that
             * one of the above three checks should always be true.
             */
            PyErr_SetString(PyExc_ValueError, "unknown bio failure");
        }
    } else {
        /*
         * If we aren't to retry, it's really an error, so fall back to the
         * normal error reporting code.  However, the BIO interface does not
         * specify a uniform error reporting mechanism.  We can only hope that
         * the code which triggered the error also kindly pushed something onto
         * the error stack.
         */
        exception_from_error_queue(ssl_Error);
    }
}
Esempio n. 11
0
/*
 * Constructor for X509Extension, never called by Python code directly
 *
 * Arguments: type_name - ???
 *            critical  - ???
 *            value     - ???
 *            subject   - An x509v3 certificate which is the subject for this extension.
 *            issuer    - An x509v3 certificate which is the issuer for this extension.
 * Returns:   The newly created X509Extension object
 */
crypto_X509ExtensionObj *
crypto_X509Extension_New(char *type_name, int critical, char *value,
                         crypto_X509Obj *subject, crypto_X509Obj  *issuer) {
    X509V3_CTX ctx;
    crypto_X509ExtensionObj *self;
    char* value_with_critical = NULL;


    /*
     * A context is necessary for any extension which uses the r2i conversion
     * method.  That is, X509V3_EXT_nconf may segfault if passed a NULL ctx.
     * Start off by initializing most of the fields to NULL.
     */
    X509V3_set_ctx(&ctx, NULL, NULL, NULL, NULL, 0);

    /*
     * We have no configuration database - but perhaps we should (some
     * extensions may require it).
     */
    X509V3_set_ctx_nodb(&ctx);

    /*
     * Initialize the subject and issuer, if appropriate.  ctx is a local, and
     * as far as I can tell none of the X509V3_* APIs invoked here steal any
     * references, so no need to incref subject or issuer.
     */
    if (subject) {
            ctx.subject_cert = subject->x509;
    }

    if (issuer) {
            ctx.issuer_cert = issuer->x509;
    }

    self = PyObject_New(crypto_X509ExtensionObj, &crypto_X509Extension_Type);

    if (self == NULL) {
	    goto error;
    }

    self->dealloc = 0;

    /* There are other OpenSSL APIs which would let us pass in critical
     * separately, but they're harder to use, and since value is already a pile
     * of crappy junk smuggling a ton of utterly important structured data,
     * what's the point of trying to avoid nasty stuff with strings? (However,
     * X509V3_EXT_i2d in particular seems like it would be a better API to
     * invoke.  I do not know where to get the ext_struc it desires for its
     * last parameter, though.) */
    value_with_critical = malloc(strlen("critical,") + strlen(value) + 1);
    if (!value_with_critical) {
	    goto critical_malloc_error;
    }

    if (critical) {
	    strcpy(value_with_critical, "critical,");
	    strcpy(value_with_critical + strlen("critical,"), value);
    } else {
	    strcpy(value_with_critical, value);
    }

    self->x509_extension = X509V3_EXT_nconf(
	    NULL, &ctx, type_name, value_with_critical);

    free(value_with_critical);

    if (!self->x509_extension) {
	    goto nconf_error;
    }

    self->dealloc = 1;
    return self;

  nconf_error:
    exception_from_error_queue(crypto_Error);

  critical_malloc_error:
    Py_XDECREF(self);

  error:
    return NULL;

}
Esempio n. 12
0
/*
 * Handle errors raised by SSL I/O functions. NOTE: Not SSL_shutdown ;)
 *
 * Arguments: ssl - The SSL object
 *            err - The return code from SSL_get_error
 *            ret - The return code from the SSL I/O function
 * Returns:   None, the calling function should return NULL
 */
static void
handle_ssl_errors(SSL *ssl, int err, int ret)
{
    switch (err)
    {
	/*
         * Strange as it may seem, ZeroReturn is not an error per se. It means
         * that the SSL Connection has been closed correctly (note, not the
         * transport layer!), i.e. closure alerts have been exchanged. This is
         * an exception since
         *  + There's an SSL "error" code for it
         *  + You have to deal with it in any case, close the transport layer
         *    etc
         */
        case SSL_ERROR_ZERO_RETURN:
            PyErr_SetNone(ssl_ZeroReturnError);
            break;

        /*
         * The WantXYZ exceptions don't mean that there's an error, just that
         * nothing could be read/written just now, maybe because the transport
         * layer would block on the operation, or that there's not enough data
         * available to fill an entire SSL record.
         */
        case SSL_ERROR_WANT_READ:
            PyErr_SetNone(ssl_WantReadError);
            break;

        case SSL_ERROR_WANT_WRITE:
            PyErr_SetNone(ssl_WantWriteError);
            break;

        case SSL_ERROR_WANT_X509_LOOKUP:
            PyErr_SetNone(ssl_WantX509LookupError);
            break;

        case SSL_ERROR_SYSCALL:
            if (ERR_peek_error() == 0)
            {
                if (ret < 0)
                {
                    syscall_from_errno();
                }
                else
                {
                    PyObject *v;

                    v = Py_BuildValue("(is)", -1, "Unexpected EOF");
                    if (v != NULL)
                    {
                        PyErr_SetObject(ssl_SysCallError, v);
                        Py_DECREF(v);
                    }
                }
                break;
            }

	/* NOTE: Fall-through here, we don't want to duplicate code, right? */

        case SSL_ERROR_SSL:
            ;
        default:
	    exception_from_error_queue(ssl_Error);
            break;
    }
}
Esempio n. 13
0
static PyObject *
crypto_exception_from_error_queue(PyObject *spam, PyObject *eggs) {
    exception_from_error_queue(crypto_Error);
    return NULL;
}
Esempio n. 14
0
/*
 * 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;
}