~myers-1/pyopenssl/npn

« back to all changes in this revision

Viewing changes to src/ssl/context.c

  • Committer: Jean-Paul Calderone
  • Date: 2010-01-25 22:55:30 UTC
  • mfrom: (126 trunk)
  • mto: This revision was merged to the branch mainline in revision 129.
  • Revision ID: exarkun@divmod.com-20100125225530-5e9nsb6bzoesoz42
merge trunk and resolve simple conflict

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
 
14
14
#if PY_VERSION_HEX >= 0x02050000
15
15
# define PYARG_PARSETUPLE_FORMAT const char
 
16
# define PYOBJECT_GETATTRSTRING_TYPE const char*
16
17
#else
17
18
# define PYARG_PARSETUPLE_FORMAT char
 
19
# define PYOBJECT_GETATTRSTRING_TYPE char*
18
20
#endif
19
21
 
20
22
#ifndef MS_WINDOWS
335
337
    return Py_None;
336
338
}
337
339
 
 
340
static PyTypeObject *
 
341
type_modified_error(const char *name) {
 
342
    PyErr_Format(PyExc_RuntimeError,
 
343
                 "OpenSSL.crypto's '%s' attribute has been modified",
 
344
                 name);
 
345
    return NULL;
 
346
}
 
347
 
 
348
static PyTypeObject *
 
349
import_crypto_type(const char *name, size_t objsize) {
 
350
    PyObject *module, *type, *name_attr;
 
351
    PyTypeObject *res;
 
352
    int right_name;
 
353
 
 
354
    module = PyImport_ImportModule("OpenSSL.crypto");
 
355
    if (module == NULL) {
 
356
        return NULL;
 
357
    }
 
358
    type = PyObject_GetAttrString(module, (PYOBJECT_GETATTRSTRING_TYPE)name);
 
359
    Py_DECREF(module);
 
360
    if (type == NULL) {
 
361
        return NULL;
 
362
    }
 
363
    if (!(PyType_Check(type))) {
 
364
        Py_DECREF(type);
 
365
        return type_modified_error(name);
 
366
    }
 
367
    name_attr = PyObject_GetAttrString(type, "__name__");
 
368
    if (name_attr == NULL) {
 
369
        Py_DECREF(type);
 
370
        return NULL;
 
371
    }
 
372
    right_name = (PyString_CheckExact(name_attr) &&
 
373
                  strcmp(name, PyString_AsString(name_attr)) == 0);
 
374
    Py_DECREF(name_attr);
 
375
    res = (PyTypeObject *)type;
 
376
    if (!right_name || res->tp_basicsize != objsize) {
 
377
        Py_DECREF(type);
 
378
        return type_modified_error(name);
 
379
    }
 
380
    return res;
 
381
}
 
382
 
338
383
static crypto_X509Obj *
339
 
parse_certificate_argument(const char* format1, const char* format2, PyObject* args)
340
 
{
 
384
parse_certificate_argument(const char* format, PyObject* args) {
341
385
    static PyTypeObject *crypto_X509_type = NULL;
342
386
    crypto_X509Obj *cert;
343
387
 
344
 
    /* We need to check that cert really is an X509 object before
345
 
       we deal with it. The problem is we can't just quickly verify
346
 
       the type (since that comes from another module). This should
347
 
       do the trick (reasonably well at least): Once we have one
348
 
       verified object, we use it's type object for future
349
 
       comparisons. */
350
 
 
351
 
    if (!crypto_X509_type)
352
 
    {
353
 
        if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format1, &cert))
354
 
            return NULL;
355
 
 
356
 
        if (strcmp(cert->ob_type->tp_name, "X509") != 0 || 
357
 
            cert->ob_type->tp_basicsize != sizeof(crypto_X509Obj))
358
 
        {
359
 
            PyErr_SetString(PyExc_TypeError, "Expected an X509 object");
360
 
            return NULL;
361
 
        }
362
 
 
363
 
        crypto_X509_type = cert->ob_type;
364
 
    }
365
 
    else
366
 
        if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format2, crypto_X509_type,
367
 
                              &cert))
368
 
            return NULL;
 
388
    if (!crypto_X509_type) {
 
389
        crypto_X509_type = import_crypto_type("X509", sizeof(crypto_X509Obj));
 
390
        if (!crypto_X509_type) {
 
391
            return NULL;
 
392
        }
 
393
    }
 
394
    if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format,
 
395
                          crypto_X509_type, &cert)) {
 
396
        return NULL;
 
397
    }
369
398
    return cert;
370
399
}
371
400
 
381
410
{
382
411
    X509* cert_original;
383
412
    crypto_X509Obj *cert = parse_certificate_argument(
384
 
        "O:add_extra_chain_cert", "O!:add_extra_chain_cert", args);
 
413
        "O!:add_extra_chain_cert", args);
385
414
    if (cert == NULL)
386
415
    {
387
416
        return NULL;
471
500
ssl_Context_use_certificate(ssl_ContextObj *self, PyObject *args)
472
501
{
473
502
    crypto_X509Obj *cert = parse_certificate_argument(
474
 
        "O:use_certificate", "O!:use_certificate", args);
 
503
        "O!:use_certificate", args);
475
504
    if (cert == NULL) {
476
505
        return NULL;
477
506
    }
533
562
@return: None\n\
534
563
";
535
564
static PyObject *
536
 
ssl_Context_use_privatekey(ssl_ContextObj *self, PyObject *args)
537
 
{
 
565
ssl_Context_use_privatekey(ssl_ContextObj *self, PyObject *args) {
538
566
    static PyTypeObject *crypto_PKey_type = NULL;
539
567
    crypto_PKeyObj *pkey;
540
568
 
541
 
    /* We need to check that cert really is a PKey object before
542
 
       we deal with it. The problem is we can't just quickly verify
543
 
       the type (since that comes from another module). This should
544
 
       do the trick (reasonably well at least): Once we have one
545
 
       verified object, we use it's type object for future
546
 
       comparisons. */
547
 
 
548
 
    if (!crypto_PKey_type)
549
 
    {
550
 
        if (!PyArg_ParseTuple(args, "O:use_privatekey", &pkey))
551
 
            return NULL;
552
 
 
553
 
        if (strcmp(pkey->ob_type->tp_name, "OpenSSL.crypto.PKey") != 0 ||
554
 
            pkey->ob_type->tp_basicsize != sizeof(crypto_PKeyObj))
555
 
        {
556
 
            PyErr_SetString(PyExc_TypeError, "Expected a PKey object");
557
 
            return NULL;
558
 
        }
559
 
 
560
 
        crypto_PKey_type = pkey->ob_type;
 
569
    if (!crypto_PKey_type) {
 
570
        crypto_PKey_type = import_crypto_type("PKey", sizeof(crypto_PKeyObj));
 
571
        if (!crypto_PKey_type) {
 
572
            return NULL;
 
573
        }
561
574
    }
562
 
    else
563
 
    if (!PyArg_ParseTuple(args, "O!:use_privatekey", crypto_PKey_type, &pkey))
 
575
    if (!PyArg_ParseTuple(args, "O!:use_privatekey", crypto_PKey_type, &pkey)) {
564
576
        return NULL;
 
577
    }
565
578
 
566
 
    if (!SSL_CTX_use_PrivateKey(self->ctx, pkey->pkey))
567
 
    {
 
579
    if (!SSL_CTX_use_PrivateKey(self->ctx, pkey->pkey)) {
568
580
        exception_from_error_queue(ssl_Error);
569
581
        return NULL;
570
 
    }
571
 
    else
572
 
    {
 
582
    } else {
573
583
        Py_INCREF(Py_None);
574
584
        return Py_None;
575
585
    }
789
799
    }
790
800
}
791
801
 
 
802
static char ssl_Context_set_client_ca_list_doc[] = "\n\
 
803
Set the list of preferred client certificate signers for this server context.\n\
 
804
\n\
 
805
This list of certificate authorities will be sent to the client when the\n\
 
806
server requests a client certificate.\n\
 
807
\n\
 
808
@param certificate_authorities: a sequence of X509Names.\n\
 
809
@return: None\n\
 
810
";
 
811
 
 
812
static PyObject *
 
813
ssl_Context_set_client_ca_list(ssl_ContextObj *self, PyObject *args)
 
814
{
 
815
    static PyTypeObject *X509NameType;
 
816
    PyObject *sequence, *tuple, *item;
 
817
    crypto_X509NameObj *name;
 
818
    X509_NAME *sslname;
 
819
    STACK_OF(X509_NAME) *CANames;
 
820
    Py_ssize_t length;
 
821
    int i;
 
822
 
 
823
    if (X509NameType == NULL) {
 
824
        X509NameType = import_crypto_type("X509Name", sizeof(crypto_X509NameObj));
 
825
        if (X509NameType == NULL) {
 
826
            return NULL;
 
827
        }
 
828
    }
 
829
    if (!PyArg_ParseTuple(args, "O:set_client_ca_list", &sequence)) {
 
830
        return NULL;
 
831
    }
 
832
    tuple = PySequence_Tuple(sequence);
 
833
    if (tuple == NULL) {
 
834
        return NULL;
 
835
    }
 
836
    length = PyTuple_Size(tuple);
 
837
    if (length >= INT_MAX) {
 
838
        PyErr_SetString(PyExc_ValueError, "client CA list is too long");
 
839
        Py_DECREF(tuple);
 
840
        return NULL;
 
841
    }
 
842
    CANames = sk_X509_NAME_new_null();
 
843
    if (CANames == NULL) {
 
844
        Py_DECREF(tuple);
 
845
        exception_from_error_queue(ssl_Error);
 
846
        return NULL;
 
847
    }
 
848
    for (i = 0; i < length; i++) {
 
849
        item = PyTuple_GetItem(tuple, i);
 
850
        if (item->ob_type != X509NameType) {
 
851
            PyErr_Format(PyExc_TypeError,
 
852
                         "client CAs must be X509Name objects, not %s objects",
 
853
                         item->ob_type->tp_name);
 
854
            sk_X509_NAME_free(CANames);
 
855
            Py_DECREF(tuple);
 
856
            return NULL;
 
857
        }
 
858
        name = (crypto_X509NameObj *)item;
 
859
        sslname = X509_NAME_dup(name->x509_name);
 
860
        if (sslname == NULL) {
 
861
            sk_X509_NAME_free(CANames);
 
862
            Py_DECREF(tuple);
 
863
            exception_from_error_queue(ssl_Error);
 
864
            return NULL;
 
865
        }
 
866
        if (!sk_X509_NAME_push(CANames, sslname)) {
 
867
            X509_NAME_free(sslname);
 
868
            sk_X509_NAME_free(CANames);
 
869
            Py_DECREF(tuple);
 
870
            exception_from_error_queue(ssl_Error);
 
871
            return NULL;
 
872
        }
 
873
    }
 
874
    Py_DECREF(tuple);
 
875
    SSL_CTX_set_client_CA_list(self->ctx, CANames);
 
876
    Py_INCREF(Py_None);
 
877
    return Py_None;
 
878
}
 
879
 
 
880
static char ssl_Context_add_client_ca_doc[] = "\n\
 
881
Add the CA certificate to the list of preferred signers for this context.\n\
 
882
\n\
 
883
The list of certificate authorities will be sent to the client when the\n\
 
884
server requests a client certificate.\n\
 
885
\n\
 
886
@param certificate_authority: certificate authority's X509 certificate.\n\
 
887
@return: None\n\
 
888
";
 
889
 
 
890
static PyObject *
 
891
ssl_Context_add_client_ca(ssl_ContextObj *self, PyObject *args)
 
892
{
 
893
    crypto_X509Obj *cert;
 
894
 
 
895
    cert = parse_certificate_argument("O!:add_client_ca", args);
 
896
    if (cert == NULL) {
 
897
        return NULL;
 
898
    }
 
899
    if (!SSL_CTX_add_client_CA(self->ctx, cert->x509)) {
 
900
        exception_from_error_queue(ssl_Error);
 
901
        return NULL;
 
902
    }
 
903
    Py_INCREF(Py_None);
 
904
    return Py_None;
 
905
}
 
906
 
792
907
static char ssl_Context_set_timeout_doc[] = "\n\
793
908
Set session timeout\n\
794
909
\n\
960
1075
    ADD_METHOD(get_verify_depth),
961
1076
    ADD_METHOD(load_tmp_dh),
962
1077
    ADD_METHOD(set_cipher_list),
 
1078
    ADD_METHOD(set_client_ca_list),
 
1079
    ADD_METHOD(add_client_ca),
963
1080
    ADD_METHOD(set_timeout),
964
1081
    ADD_METHOD(get_timeout),
965
1082
    ADD_METHOD(set_info_callback),