diff options
-rw-r--r-- | pow/POW-0.7/POW.c | 117 |
1 files changed, 69 insertions, 48 deletions
diff --git a/pow/POW-0.7/POW.c b/pow/POW-0.7/POW.c index 7bcfdc33..b9c61e4e 100644 --- a/pow/POW-0.7/POW.c +++ b/pow/POW-0.7/POW.c @@ -325,13 +325,13 @@ typedef struct { #define lose_openssl_error(_msg_) \ do { \ - set_openssl_pyerror((_msg_)); \ + set_openssl_exception(ErrorObject, (_msg_)); \ goto error; \ } while (0) #define lose_ssl_error(_self_, _code_) \ do { \ - set_openssl_sslerror(_self_, _code_); \ + set_openssl_ssl_exception(_self_, _code_); \ goto error; \ } while (0) @@ -437,9 +437,55 @@ evp_cipher_factory(int cipher_type) } } +/* + * Raise an exception with data pulled from the OpenSSL error stack. + * Exception value is a tuple with some internal structure. If a + * string error message is supplied, that string is the first element + * of the exception value tuple. Remainder of exception value tuple + * is zero or more tuples, each representing one error from the stack. + * Each error tuple contains six slots: + * - the numeric error code + * - string translation of numeric error code ("reason") + * - name of library in which error occurred + * - name of function in which error occurred + * - name of file in which error occurred + * - line number in file where error occurred + */ static void -set_openssl_sslerror(const ssl_object *self, const int code) +set_openssl_exception(PyObject *error_class, const char *msg) +{ + PyObject *errors; + unsigned long err; + const char *file; + int line; + + errors = PyList_New(0); + + if (msg) { + PyObject *s = Py_BuildValue("s", msg); + PyList_Append(errors, s); + Py_DECREF(s); + } + + while ((err = ERR_get_error_line(&file, &line)) != 0) { + PyObject *t = Py_BuildValue("(issssi)", + err, + ERR_reason_error_string(err), + ERR_lib_error_string(err), + ERR_func_error_string(err), + file, + line); + PyList_Append(errors, t); + Py_DECREF(t); + } + + PyErr_SetObject(error_class, PyList_AsTuple(errors)); + Py_DECREF(errors); +} + +static void +set_openssl_ssl_exception(const ssl_object *self, const int code) { int err = SSL_get_error(self->ssl, code); const char *s = NULL; @@ -461,15 +507,23 @@ set_openssl_sslerror(const ssl_object *self, const int code) break; /* - * These two might need special handling later, to examine errno - * or OpenSSL error stack; for now, treat like other SSL errors. + * Generic OpenSSL error, or system call error. What a mess. */ case SSL_ERROR_SYSCALL: - s = "SSL_ERROR_SYSCALL"; + if (ERR_peek_error()) + set_openssl_exception(SSLErrorObject, NULL); + else + PyErr_SetFromErrno(SSLErrorObject); break; + + /* + * Generic OpenSSL error that occurred during an SSL call. + * I think. + */ + case SSL_ERROR_SSL: - s = "SSL_ERROR_SSL"; + set_openssl_exception(SSLErrorObject, NULL); break; /* @@ -645,39 +699,6 @@ X509_object_helper_get_name(X509_NAME *name, int format) return NULL; } -static void -set_openssl_pyerror(const char *msg) -{ - char *buf = NULL; - BIO *bio = NULL; - int len; - - if ((bio = BIO_new(BIO_s_mem())) == NULL) - goto error; - - BIO_puts(bio, msg); - BIO_puts(bio, ":\n"); - ERR_print_errors(bio); - - if ((len = BIO_ctrl_pending(bio)) == 0) - goto error; - if ((buf = malloc(len + 1)) == NULL) - goto error; - if (BIO_read(bio, buf, len) != len) - goto error; - buf[len] = '\0'; - - PyErr_SetString(ErrorObject, buf); - - /* fall through */ - error: - - if (bio) - BIO_free(bio); - if (buf) - free(buf); -} - static STACK_OF(X509) * x509_helper_sequence_to_stack(PyObject *x509_sequence) { @@ -3918,7 +3939,7 @@ ssl_object_add_certificate(ssl_object *self, PyObject *args) lose("could not duplicate X509 object"); if (!SSL_CTX_add_extra_chain_cert(self->ctx, x)) - lose_openssl_error("could not add certificate"); + lose_openssl_error("Could not add certificate"); x = NULL; @@ -6553,7 +6574,7 @@ CMS_object_sign(cms_object *self, PyObject *args) assert_no_unhandled_openssl_errors(); if ((pkey = EVP_PKEY_new()) == NULL) - lose_openssl_error("could not allocate memory"); + lose_openssl_error("Could not allocate memory"); assert_no_unhandled_openssl_errors(); @@ -6568,12 +6589,12 @@ CMS_object_sign(cms_object *self, PyObject *args) assert_no_unhandled_openssl_errors(); if (oid && (econtent_type = OBJ_txt2obj(oid, 0)) == NULL) - lose_openssl_error("could not parse OID"); + lose_openssl_error("Could not parse OID"); assert_no_unhandled_openssl_errors(); if ((cms = CMS_sign(NULL, NULL, x509_stack, bio, flags)) == NULL) - lose_openssl_error("could not create CMS message"); + lose_openssl_error("Could not create CMS message"); assert_no_unhandled_openssl_errors(); @@ -6583,7 +6604,7 @@ CMS_object_sign(cms_object *self, PyObject *args) assert_no_unhandled_openssl_errors(); if (!CMS_add1_signer(cms, signcert->x509, pkey, EVP_sha256(), flags)) - lose_openssl_error("could not sign CMS message"); + lose_openssl_error("Could not sign CMS message"); pkey = NULL; /* CMS_add1_signer() now owns pkey */ @@ -6608,7 +6629,7 @@ CMS_object_sign(cms_object *self, PyObject *args) lose("CRL object with null crl field!"); if (!CMS_add1_crl(cms, crlobj->crl)) - lose_openssl_error("could not add CRL to CMS"); + lose_openssl_error("Could not add CRL to CMS"); assert_no_unhandled_openssl_errors(); @@ -6618,7 +6639,7 @@ CMS_object_sign(cms_object *self, PyObject *args) } if (!CMS_final(cms, bio, NULL, flags)) - lose_openssl_error("could not finalize CMS signatures"); + lose_openssl_error("Could not finalize CMS signatures"); assert_no_unhandled_openssl_errors(); @@ -6706,7 +6727,7 @@ CMS_object_verify(cms_object *self, PyObject *args) assert_no_unhandled_openssl_errors(); if (CMS_verify(self->cms, certs_stack, store->store, NULL, bio, flags) <= 0) - lose_openssl_error("could not verify CMS message"); + lose_openssl_error("Could not verify CMS message"); assert_no_unhandled_openssl_errors(); |