expand support for digests (hashes)
add support for symmetric cipher encryption/decryption add test code for above some minor clean up in other areas git-svn-id: svn://10.0.0.236/trunk@258418 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -8,6 +8,8 @@ doc/ChangeLog
|
||||
doc/examples/httplib_example.py
|
||||
doc/examples/ssl_example.py
|
||||
lib/httplib.py
|
||||
test/cipher_test.py
|
||||
test/digest_test.py
|
||||
src/NSPRerrs.h
|
||||
src/SECerrs.h
|
||||
src/SSLerrs.h
|
||||
@@ -21,3 +23,4 @@ src/py_nss.c
|
||||
src/py_nss.h
|
||||
src/py_ssl.c
|
||||
src/py_ssl.h
|
||||
|
||||
|
||||
@@ -1,3 +1,31 @@
|
||||
2009-09-18 John Dennis <jdennis@redhat.com> 0.7
|
||||
* add support for symmetric encryption/decryption
|
||||
more support for digests (hashes)
|
||||
|
||||
The following classes were added:
|
||||
PK11SymKey PK11Context
|
||||
|
||||
The following methods and functions were added:
|
||||
get_best_wrap_mechanism get_best_key_length
|
||||
key_gen derive
|
||||
get_key_length digest_key
|
||||
clone_context digest_begin
|
||||
digest_op cipher_op
|
||||
finalize digest_final
|
||||
read_hex hash_buf
|
||||
sec_oid_tag_str sec_oid_tag_name
|
||||
sec_oid_tag_from_name key_mechanism_type_name
|
||||
key_mechanism_type_from_name pk11_attribute_type_name
|
||||
pk11_attribute_type_from_name get_best_slot
|
||||
get_internal_key_slot create_context_by_sym_key
|
||||
import_sym_key create_digest_context
|
||||
param_from_iv param_from_algid
|
||||
generate_new_param algtag_to_mechanism
|
||||
mechanism_to_algtag
|
||||
|
||||
The following files were added:
|
||||
test/cipher_test.py test/digest_test.py
|
||||
|
||||
2009-07-08 John Dennis <jdennis@redhat.com> 0.6
|
||||
* fix bug #510343 client_auth_data_callback seg faults if False
|
||||
is returned from callback
|
||||
@@ -5,17 +33,16 @@
|
||||
2009-07-01 John Dennis <jdennis@redhat.com> 0.5
|
||||
* restore ssl.nss_init and ssl.nss_shutdown but make them deprecated
|
||||
add __version__ string to nss module
|
||||
|
||||
|
||||
2009-06-30 John Dennis <jdennis@redhat.com> 0.4
|
||||
* add binding for NSS_NoDB_Init(), bug #509002
|
||||
move nss_init and nss_shutdown from ssl module to nss module
|
||||
|
||||
|
||||
2009-06-04 John Dennis <jdennis@redhat.com> 0.3
|
||||
|
||||
* import to Mozilla CVS, tweak directory layout
|
||||
|
||||
2009-05-21 John Dennis <jdennis@redhat.com> 0.2
|
||||
|
||||
* apply patch from bug #472805, (Miloslav Trmač)
|
||||
Don't allow closing a socket twice, that causes crashes.
|
||||
New function nss.io.Socket.new_socket_pair()
|
||||
@@ -24,5 +51,5 @@
|
||||
New method nss.nss.Certificate.get_subject_common_name()
|
||||
New function nss.nss.generate_random()
|
||||
Fix return value creation in SSLSocket.get_security_status
|
||||
New function nss.ssl.SSLSocket.import_tcp_socket()
|
||||
New function nss.ssl.SSLSocket.import_tcp_socket()
|
||||
Convert licensing to MPL tri-license
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
@@ -14,8 +15,8 @@
|
||||
# The Original Code is a Python binding for Network Security Services (NSS).
|
||||
#
|
||||
# The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
# (Author: John Dennis <jdennis@redhat.com>)
|
||||
#
|
||||
# (Author: John Dennis <jdennis@redhat.com>)
|
||||
#
|
||||
# Portions created by the Initial Developer are Copyright (C) 2008,2009
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
@@ -49,7 +50,7 @@ from distutils.util import subst_vars, change_root
|
||||
from distutils.command.build_py import build_py as _build_py
|
||||
from distutils.command.sdist import sdist as _sdist
|
||||
|
||||
version = "0.6"
|
||||
version = "0.7"
|
||||
|
||||
def update_version():
|
||||
"""If the version string in __init__.py doesn't match the current
|
||||
@@ -88,7 +89,7 @@ class BuildPy(_build_py):
|
||||
def run(self):
|
||||
update_version()
|
||||
_build_py.run(self)
|
||||
|
||||
|
||||
|
||||
class SDist(_sdist):
|
||||
"""Specialized Python source builder."""
|
||||
@@ -96,7 +97,7 @@ class SDist(_sdist):
|
||||
def run(self):
|
||||
update_version()
|
||||
_sdist.run(self)
|
||||
|
||||
|
||||
|
||||
class BuildDoc(Command):
|
||||
description = 'generate documentation'
|
||||
@@ -123,7 +124,7 @@ class BuildDoc(Command):
|
||||
('build_lib', 'build_lib'))
|
||||
if self.docdir is None:
|
||||
self.docdir = change_root(self.build_base, 'doc')
|
||||
|
||||
|
||||
def run(self):
|
||||
self.run_command('build')
|
||||
for cmd_name in self.get_sub_commands():
|
||||
@@ -190,7 +191,7 @@ class InstallDoc(Command):
|
||||
|
||||
if self.docdir is None:
|
||||
self.docdir = change_root(self.build_base, 'doc')
|
||||
|
||||
|
||||
def run(self):
|
||||
if not self.skip_build:
|
||||
self.run_command('build_doc')
|
||||
@@ -211,7 +212,7 @@ class InstallDoc(Command):
|
||||
install_spec. A sequence of install_spec's allows one to build
|
||||
up the destrination tree in any structure desired.
|
||||
|
||||
Each install_spec consists of 3 components
|
||||
Each install_spec consists of 3 components
|
||||
(manifest_template, dst_xforms, dst_dir):
|
||||
|
||||
The manifest_template is a sequence where each item is identical
|
||||
|
||||
@@ -296,4 +296,4 @@ FAQ
|
||||
To be added
|
||||
|
||||
"""
|
||||
__version__ = '0.6'
|
||||
__version__ = '0.7'
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* The Original Code is a Python binding for Network Security Services (NSS).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008,2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
@@ -113,3 +113,4 @@ typedef int Py_ssize_t;
|
||||
#define TraceObjNewEnter(_name, _tp)
|
||||
#define TraceObjNewLeave(_name, _obj)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* The Original Code is a Python binding for Network Security Services (NSS).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008,2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
@@ -35,10 +35,11 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
#include "structmember.h"
|
||||
|
||||
#define NSPR_ERROR_MODULE
|
||||
#define NSS_ERROR_MODULE
|
||||
#include "py_nspr_error.h"
|
||||
|
||||
|
||||
@@ -95,12 +96,12 @@ init_nspr_errors(void) {
|
||||
err_num = nspr_errors[i].num;
|
||||
if (err_num <= last_num) {
|
||||
result = SECFailure;
|
||||
fprintf(stderr,
|
||||
fprintf(stderr,
|
||||
"sequence error in error strings at item %d\n"
|
||||
"error %d (%s)\n"
|
||||
"should come after \n"
|
||||
"error %d (%s)\n",
|
||||
i, last_num, nspr_errors[i-1].string,
|
||||
i, last_num, nspr_errors[i-1].string,
|
||||
err_num, nspr_errors[i].string);
|
||||
}
|
||||
last_num = err_num;
|
||||
@@ -123,7 +124,7 @@ lookup_nspr_error(PRErrorCode num) {
|
||||
return &nspr_errors[i];
|
||||
if (num < err_num)
|
||||
high = i;
|
||||
else
|
||||
else
|
||||
low = i;
|
||||
}
|
||||
if (num == nspr_errors[low].num)
|
||||
@@ -247,7 +248,7 @@ init_py_nspr_errors(PyObject *module)
|
||||
|
||||
/* ============================== Module Exports ============================= */
|
||||
|
||||
static PyNSPR_ERROR_C_API_Type nspr_error_c_api =
|
||||
static PyNSPR_ERROR_C_API_Type nspr_error_c_api =
|
||||
{
|
||||
NULL, /* nspr_exception */
|
||||
set_nspr_error, /* set_nspr_error */
|
||||
@@ -261,7 +262,7 @@ manipulate them.\n\
|
||||
");
|
||||
|
||||
PyMODINIT_FUNC
|
||||
initerror(void)
|
||||
initerror(void)
|
||||
{
|
||||
PyObject *m;
|
||||
PyObject *py_error_doc = NULL;
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* The Original Code is a Python binding for Network Security Services (NSS).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008,2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
@@ -45,9 +45,9 @@ typedef struct {
|
||||
PyObject *(*set_nspr_error)(const char *format, ...);
|
||||
} PyNSPR_ERROR_C_API_Type;
|
||||
|
||||
#ifdef NSPR_ERROR_MODULE
|
||||
#ifdef NSS_ERROR_MODULE
|
||||
|
||||
#else /* not NSPR_ERROR_MODULE */
|
||||
#else /* not NSS_ERROR_MODULE */
|
||||
|
||||
static PyNSPR_ERROR_C_API_Type nspr_error_c_api;
|
||||
|
||||
@@ -67,7 +67,7 @@ import_nspr_error_c_api(void)
|
||||
Py_DECREF(module);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!(PyCObject_Check(c_api_object))) {
|
||||
Py_DECREF(c_api_object);
|
||||
Py_DECREF(module);
|
||||
@@ -86,4 +86,4 @@ import_nspr_error_c_api(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* NSPR_ERROR_MODULE */
|
||||
#endif /* NSS_ERROR_MODULE */
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* The Original Code is a Python binding for Network Security Services (NSS).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008,2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
@@ -41,11 +41,12 @@
|
||||
// FIXME: change where class initializers appear in the file, should be first so class methods can use them
|
||||
// or just add prototypes for everything (maybe better solution).
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
#include "structmember.h"
|
||||
|
||||
#include "py_nspr_common.h"
|
||||
#define NSPR_IO_MODULE
|
||||
#define NSS_IO_MODULE
|
||||
#include "py_nspr_io.h"
|
||||
#include "py_nspr_error.h"
|
||||
|
||||
@@ -213,12 +214,12 @@ NetworkAddress_set_port(NetworkAddress *self, PyObject *value, void *closure)
|
||||
PyErr_SetString(PyExc_TypeError, "Cannot delete the port attribute");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!PyInt_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "The port attribute value must be an integer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
port = PyInt_AsLong(value);
|
||||
if (PR_InitializeNetAddr(PR_IpAddrNull, port, &self->addr) != PR_SUCCESS) {
|
||||
set_nspr_error(NULL);
|
||||
@@ -394,8 +395,8 @@ NetworkAddress_init(NetworkAddress *self, PyObject *args, PyObject *kwds)
|
||||
TraceMethodEnter("NetworkAddress_init", self);
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi", kwlist, &addr, &port))
|
||||
return -1;
|
||||
|
||||
return -1;
|
||||
|
||||
if (addr && !(PyInt_Check(addr) || PyString_Check(addr))) {
|
||||
PyErr_SetString(PyExc_ValueError, "addr must be an int or a string");
|
||||
return -1;
|
||||
@@ -714,7 +715,7 @@ HostEntry_init(HostEntry *self, PyObject *args)
|
||||
TraceMethodEnter("HostEntry_init", self);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O", &addr))
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
if (PyString_Check(addr)) {
|
||||
if (PR_GetHostByName(PyString_AsString(addr), self->buffer, sizeof(self->buffer), &self->entry) != PR_SUCCESS) {
|
||||
@@ -1465,7 +1466,7 @@ Socket_accept_read(Socket *self, PyObject *args, PyObject *kwds)
|
||||
&requested_amount, &timeout))
|
||||
return NULL;
|
||||
|
||||
if ((buf = PyString_FromStringAndSize((char *) 0, requested_amount)) == NULL)
|
||||
if ((buf = PyString_FromStringAndSize(NULL, requested_amount)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((amount_read = PR_AcceptRead(self->pr_socket, &pr_socket, &pr_netaddr,
|
||||
@@ -1661,7 +1662,7 @@ Socket_readline(Socket *self, PyObject *args, PyObject *kwds)
|
||||
long size = 0;
|
||||
long read_len, space_available, amount_read, line_len;
|
||||
PyObject *line = NULL;
|
||||
|
||||
|
||||
TraceMethodEnter("Socket_readline", self);
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|l:readline", kwlist, &size))
|
||||
@@ -1750,7 +1751,7 @@ Socket_recv(Socket *self, PyObject *args, PyObject *kwds)
|
||||
PyObject *buf = NULL;
|
||||
long read_len, amount_read, result_len;
|
||||
char *dst = NULL;
|
||||
|
||||
|
||||
TraceMethodEnter("Socket_recv", self);
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i|I:recv", kwlist,
|
||||
@@ -1802,7 +1803,6 @@ Socket_recv(Socket *self, PyObject *args, PyObject *kwds)
|
||||
|
||||
if (result_len != requested_amount) {
|
||||
if (_PyString_Resize(&buf, result_len) < 0) {
|
||||
Py_DECREF(buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -1829,7 +1829,7 @@ Socket_read(Socket *self, PyObject *args, PyObject *kwds)
|
||||
unsigned int timeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
PyObject *buf = NULL;
|
||||
long read_len, space_available, amount_read;
|
||||
|
||||
|
||||
TraceMethodEnter("Socket_read", self);
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|l:read", kwlist, &requested_amount))
|
||||
@@ -1894,7 +1894,7 @@ Socket_recv_from(Socket *self, PyObject *args, PyObject *kwds)
|
||||
unsigned int timeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
int amount_read;
|
||||
PyObject *buf = NULL;
|
||||
|
||||
|
||||
/* FIXME: for consistency should use readahead buffering, but since this is the first read
|
||||
* the readahead would be empty anyway */
|
||||
|
||||
@@ -1921,7 +1921,6 @@ Socket_recv_from(Socket *self, PyObject *args, PyObject *kwds)
|
||||
|
||||
if (amount_read != requested_amount) {
|
||||
if (_PyString_Resize(&buf, amount_read) < 0) {
|
||||
Py_DECREF(buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -1949,10 +1948,10 @@ Socket_send(Socket *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"buf", "timeout", NULL};
|
||||
char *buf = NULL;
|
||||
int len = 0;
|
||||
Py_ssize_t len = 0;
|
||||
unsigned int timeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
int amount;
|
||||
|
||||
|
||||
TraceMethodEnter("Socket_send", self);
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#|I:send", kwlist,
|
||||
@@ -1991,7 +1990,7 @@ Socket_send_to(Socket *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"buf", "addr", "timeout", NULL};
|
||||
char *buf = NULL;
|
||||
int len = 0;
|
||||
Py_ssize_t len = 0;
|
||||
NetworkAddress *py_netaddr = NULL;
|
||||
unsigned int timeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
int amount;
|
||||
@@ -2405,9 +2404,9 @@ Socket_init(Socket *self, PyObject *args, PyObject *kwds)
|
||||
|
||||
TraceMethodEnter("Socket_init", self);
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwlist,
|
||||
&family, &desc_type))
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
/* If reinitializing, first close down previous socket */
|
||||
if (self->pr_socket) {
|
||||
@@ -2420,7 +2419,7 @@ Socket_init(Socket *self, PyObject *args, PyObject *kwds)
|
||||
self->pr_socket = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch (desc_type) {
|
||||
case PR_DESC_SOCKET_TCP:
|
||||
if ((pr_socket = PR_OpenTCPSocket(family)) == NULL) {
|
||||
@@ -2793,7 +2792,7 @@ module_methods[] = {
|
||||
|
||||
/* ============================== Module Exports ============================= */
|
||||
|
||||
static PyNSPR_IO_C_API_Type nspr_io_c_api =
|
||||
static PyNSPR_IO_C_API_Type nspr_io_c_api =
|
||||
{
|
||||
&NetworkAddressType, /* network_address_type */
|
||||
&HostEntryType, /* host_entry_type */
|
||||
@@ -2809,7 +2808,7 @@ PyDoc_STRVAR(module_doc,
|
||||
");
|
||||
|
||||
PyMODINIT_FUNC
|
||||
initio(void)
|
||||
initio(void)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* The Original Code is a Python binding for Network Security Services (NSS).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008,2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
@@ -113,12 +113,12 @@ typedef struct {
|
||||
void (*Socket_init_from_prfiledesc)(Socket *py_socket, PRFileDesc *pr_socket, int family);
|
||||
} PyNSPR_IO_C_API_Type;
|
||||
|
||||
#ifdef NSPR_IO_MODULE
|
||||
#ifdef NSS_IO_MODULE
|
||||
|
||||
static PyObject *
|
||||
HostEntry_new_from_prnetaddr(PRNetAddr *pr_netaddr);
|
||||
|
||||
#else /* not NSPR_IO_MODULE */
|
||||
#else /* not NSS_IO_MODULE */
|
||||
|
||||
static PyNSPR_IO_C_API_Type nspr_io_c_api;
|
||||
|
||||
@@ -142,7 +142,7 @@ import_nspr_io_c_api(void)
|
||||
Py_DECREF(module);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!(PyCObject_Check(c_api_object))) {
|
||||
Py_DECREF(c_api_object);
|
||||
Py_DECREF(module);
|
||||
@@ -161,4 +161,4 @@ import_nspr_io_c_api(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* NSPR_IO_MODULE */
|
||||
#endif /* NSS_IO_MODULE */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,8 +14,8 @@
|
||||
* The Original Code is a Python binding for Network Security Services (NSS).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008,2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
@@ -94,17 +94,19 @@ typedef struct {
|
||||
|
||||
typedef enum SECItemKindEnum {
|
||||
SECITEM_unknown,
|
||||
SECITEM_buffer,
|
||||
SECITEM_dist_name,
|
||||
SECITEM_session_id,
|
||||
SECITEM_signed_data,
|
||||
SECITEM_signature,
|
||||
SECITEM_algorithm,
|
||||
SECITEM_iv_param,
|
||||
} SECItemKind;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
SECItem item;
|
||||
SECItemKind kind;
|
||||
SECItemKind kind;
|
||||
} SecItem;
|
||||
|
||||
/* ========================================================================== */
|
||||
@@ -186,6 +188,26 @@ typedef struct {
|
||||
PyObject *py_public_key;
|
||||
} SubjectPublicKeyInfo;
|
||||
|
||||
/* ========================================================================== */
|
||||
/* ============================= PK11SymKey Class =========================== */
|
||||
/* ========================================================================== */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PK11SymKey *pk11_sym_key;
|
||||
} PyPK11SymKey;
|
||||
|
||||
/* ========================================================================== */
|
||||
/* ============================= PK11Context Class ========================== */
|
||||
/* ========================================================================== */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PK11Context *pk11_context;
|
||||
} PyPK11Context;
|
||||
|
||||
/* ========================================================================== */
|
||||
|
||||
typedef struct {
|
||||
PyTypeObject *pk11slot_type;
|
||||
PyTypeObject *certdb_type;
|
||||
@@ -199,18 +221,19 @@ typedef struct {
|
||||
CERTDistNames *(*cert_distnames_as_CERTDistNames)(PyObject *py_distnames);
|
||||
} PyNSPR_NSS_C_API_Type;
|
||||
|
||||
#ifdef NSPR_NSS_MODULE
|
||||
#ifdef NSS_NSS_MODULE
|
||||
|
||||
#define PyPK11Slot_Check(op) PyObject_TypeCheck(op, &PK11SlotType)
|
||||
#define PyCertDB_Check(op) PyObject_TypeCheck(op, &CertDBType)
|
||||
#define PyCertificate_Check(op) PyObject_TypeCheck(op, &CertificateType)
|
||||
#define PyPrivateKey_Check(op) PyObject_TypeCheck(op, &PrivateKeyType)
|
||||
#define PySecItem_Check(op) PyObject_TypeCheck(op, &SecItemType)
|
||||
#define PySymKey_Check(op) PyObject_TypeCheck(op, &PK11SymKeyType)
|
||||
|
||||
PyObject *
|
||||
PK11Slot_new_from_slotinfo(PK11SlotInfo *slot);
|
||||
|
||||
#else /* not NSPR_NSS_MODULE */
|
||||
#else /* not NSS_NSS_MODULE */
|
||||
|
||||
#define CertDBType (*nspr_nss_c_api.certdb_type)
|
||||
#define CertificateType (*nspr_nss_c_api.certificate_type)
|
||||
@@ -245,7 +268,7 @@ import_nspr_nss_c_api(void)
|
||||
Py_DECREF(module);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!(PyCObject_Check(c_api_object))) {
|
||||
Py_DECREF(c_api_object);
|
||||
Py_DECREF(module);
|
||||
@@ -264,4 +287,4 @@ import_nspr_nss_c_api(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* NSPR_NSS_MODULE */
|
||||
#endif /* NSS_NSS_MODULE */
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* The Original Code is a Python binding for Network Security Services (NSS).
|
||||
*
|
||||
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* (Author: John Dennis <jdennis@redhat.com>)
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008,2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
@@ -39,6 +39,7 @@
|
||||
// FIXME: PyIntObjects represent their value as a long, but in many places we declared their C representation as
|
||||
// as int, we should change it to long, and at the same time match the parameters used in the NSPR/NSS API
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
#include "structmember.h"
|
||||
|
||||
@@ -439,7 +440,7 @@ ssl_auth_certificate(void *arg, PRFileDesc *pr_socket, PRBool check_sig, PRBool
|
||||
Py_DECREF(args);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
sec_status = PyObject_IsTrue(result) ? SECSuccess : SECFailure;
|
||||
|
||||
Py_DECREF(args);
|
||||
@@ -620,7 +621,7 @@ get_client_auth_data(void *arg, PRFileDesc *fd, CERTDistNames *caNames, CERTCert
|
||||
PyErr_Print();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
if (PyBool_Check(return_args)) {
|
||||
if (return_args == Py_False) {
|
||||
goto fail; // callback returned failure, boolean == false
|
||||
@@ -830,7 +831,7 @@ ssl_handshake_callback(PRFileDesc *fd, void *arg)
|
||||
Py_DECREF(args);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Py_DECREF(args);
|
||||
}
|
||||
|
||||
@@ -977,7 +978,7 @@ SSLSocket_config_secure_server(SSLSocket *self, PyObject *args)
|
||||
Certificate *py_cert = NULL;
|
||||
PrivateKey *py_priv_key = NULL;
|
||||
int kea = 0;
|
||||
|
||||
|
||||
TraceMethodEnter("SSLSocket_config_secure_server", self);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!O!i:config_secure_server",
|
||||
@@ -988,7 +989,7 @@ SSLSocket_config_secure_server(SSLSocket *self, PyObject *args)
|
||||
|
||||
if (SSL_ConfigSecureServer(self->pr_socket, py_cert->cert, py_priv_key->private_key, kea) != SECSuccess)
|
||||
return set_nspr_error(NULL);
|
||||
|
||||
|
||||
Py_RETURN_NONE;
|
||||
|
||||
}
|
||||
@@ -1326,7 +1327,7 @@ SSLSocket_get_cipher_pref(SSLSocket *self, PyObject *args)
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(SSLSocket_set_hostname_doc,
|
||||
"set_hostname(url)\n\
|
||||
\n\
|
||||
@@ -1360,7 +1361,7 @@ SSLSocket_set_hostname(SSLSocket *self, PyObject *args)
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(SSLSocket_get_hostname_doc,
|
||||
"get_hostname()\n\
|
||||
\n\
|
||||
@@ -1385,7 +1386,7 @@ SSLSocket_get_hostname(SSLSocket *self, PyObject *args)
|
||||
PR_Free(url);
|
||||
return py_hostname;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(SSLSocket_set_certificate_db_doc,
|
||||
"set_certificate_db(certdb)\n\
|
||||
\n\
|
||||
@@ -1440,7 +1441,7 @@ static PyObject *
|
||||
SSLSocket_reset_handshake(SSLSocket *self, PyObject *args)
|
||||
{
|
||||
int as_server = 0;
|
||||
|
||||
|
||||
TraceMethodEnter("SSLSocket_reset_handshake", self);
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i:reset_handshake", &as_server))
|
||||
@@ -1448,7 +1449,7 @@ SSLSocket_reset_handshake(SSLSocket *self, PyObject *args)
|
||||
|
||||
if (SSL_ResetHandshake(self->pr_socket, as_server) != SECSuccess)
|
||||
return set_nspr_error(NULL);
|
||||
|
||||
|
||||
Py_RETURN_NONE;
|
||||
|
||||
}
|
||||
@@ -1515,7 +1516,7 @@ static PyObject *
|
||||
SSLSocket_force_handshake_timeout(SSLSocket *self, PyObject *args)
|
||||
{
|
||||
unsigned int timeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
|
||||
|
||||
if (!PyArg_ParseTuple(args, "I:force_handshake_timeout", &timeout))
|
||||
return NULL;
|
||||
|
||||
@@ -1591,7 +1592,7 @@ SSLSocket_rehandshake_timeout(SSLSocket *self, PyObject *args)
|
||||
{
|
||||
int flush_cache;
|
||||
unsigned int timeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iI:rehandshake_timeout", &flush_cache, &timeout))
|
||||
return NULL;
|
||||
|
||||
@@ -1810,7 +1811,7 @@ PyTypeObject SSLSocketType = {
|
||||
|
||||
|
||||
/*
|
||||
* WARNING: nssinit(), nss_init(), nss_shutdown() were deprecated in June 2009,
|
||||
* WARNING: nssinit(), nss_init(), nss_shutdown() were deprecated in June 2009,
|
||||
* they should be removed after a suitible grace period. Each of these will
|
||||
* emit a deprecation warning upon use.
|
||||
*/
|
||||
@@ -2014,7 +2015,7 @@ SSL_get_default_cipher_pref(PyObject *self, PyObject *args)
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(SSL_set_cipher_policy_doc,
|
||||
"set_cipher_pref(cipher, enabled)\n\
|
||||
\n\
|
||||
@@ -2079,7 +2080,7 @@ SSL_get_cipher_policy(PyObject *self, PyObject *args)
|
||||
else
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
|
||||
PyDoc_STRVAR(SSL_config_server_session_id_cache_doc,
|
||||
"config_server_session_id_cache([max_cache_entries=0, ssl2_timeout=0, ssl3_timeout=0, directory=None])\n\
|
||||
\n\
|
||||
@@ -2242,7 +2243,7 @@ PyDoc_STRVAR(module_doc,
|
||||
"This module implements the SSL functionality in NSS");
|
||||
|
||||
PyMODINIT_FUNC
|
||||
initssl(void)
|
||||
initssl(void)
|
||||
{
|
||||
PyObject *m;
|
||||
int i;
|
||||
@@ -2334,7 +2335,7 @@ initssl(void)
|
||||
AddIntConstant(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA);
|
||||
AddIntConstant(SSL_RSA_WITH_DES_CBC_SHA);
|
||||
AddIntConstant(SSL_RSA_WITH_3DES_EDE_CBC_SHA);
|
||||
|
||||
|
||||
AddIntConstant(SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA);
|
||||
AddIntConstant(SSL_RSA_FIPS_WITH_DES_CBC_SHA);
|
||||
|
||||
@@ -2344,14 +2345,14 @@ initssl(void)
|
||||
AddIntConstant(SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA);
|
||||
AddIntConstant(SSL_DH_RSA_WITH_DES_CBC_SHA);
|
||||
AddIntConstant(SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA);
|
||||
|
||||
|
||||
AddIntConstant(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA);
|
||||
AddIntConstant(SSL_DHE_DSS_WITH_DES_CBC_SHA);
|
||||
AddIntConstant(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA);
|
||||
AddIntConstant(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA);
|
||||
AddIntConstant(SSL_DHE_RSA_WITH_DES_CBC_SHA);
|
||||
AddIntConstant(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA);
|
||||
|
||||
|
||||
AddIntConstant(SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5);
|
||||
AddIntConstant(SSL_DH_ANON_WITH_RC4_128_MD5);
|
||||
AddIntConstant(SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA);
|
||||
|
||||
235
mozilla/security/python/nss/test/cipher_test.py
Executable file
235
mozilla/security/python/nss/test/cipher_test.py
Executable file
@@ -0,0 +1,235 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# used for local testing
|
||||
#from test_util import insert_build_dir_into_path
|
||||
#insert_build_dir_into_path()
|
||||
|
||||
import sys
|
||||
import os
|
||||
import getopt
|
||||
import nss.nss as nss
|
||||
|
||||
verbose = 0
|
||||
|
||||
def setup_contexts(mechanism, key, iv):
|
||||
# Get a PK11 slot based on the cipher
|
||||
slot = nss.get_best_slot(mechanism)
|
||||
|
||||
# If key was supplied use it, otherwise generate one
|
||||
if key:
|
||||
if verbose:
|
||||
print "using supplied key data"
|
||||
print "key:\n%s" % (key)
|
||||
key_si = nss.SecItem(nss.read_hex(key))
|
||||
sym_key = nss.import_sym_key(slot, mechanism, nss.PK11_OriginUnwrap,
|
||||
nss.CKA_ENCRYPT, key_si)
|
||||
else:
|
||||
if verbose:
|
||||
print "generating key data"
|
||||
sym_key = slot.key_gen(mechanism, None, slot.get_best_key_length(mechanism))
|
||||
|
||||
# If initial value was supplied use it, otherwise set it to None
|
||||
if iv:
|
||||
if verbose:
|
||||
print "iv:\n%s" % (iv)
|
||||
iv_si = nss.SecItem(nss.read_hex(iv))
|
||||
iv_param = nss.param_from_iv(mechanism, iv_si)
|
||||
else:
|
||||
iv_param = None
|
||||
|
||||
# Create an encoding context
|
||||
encoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT,
|
||||
sym_key, iv_param)
|
||||
|
||||
# Create a decoding context
|
||||
decoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT,
|
||||
sym_key, iv_param)
|
||||
|
||||
return encoding_ctx, decoding_ctx
|
||||
|
||||
def simple_test(encoding_ctx, decoding_ctx, plain_text):
|
||||
result = 0
|
||||
|
||||
if verbose:
|
||||
print "Plain Text:\n%s" % (plain_text)
|
||||
|
||||
# Encode the plain text by feeding it to cipher_op getting cipher text back.
|
||||
# Append the final bit of cipher text by calling digest_final
|
||||
cipher_text = encoding_ctx.cipher_op(plain_text)
|
||||
cipher_text += encoding_ctx.digest_final()
|
||||
|
||||
if verbose:
|
||||
print "Cipher Text:\n%s" % (nss.data_to_hex(cipher_text, separator=":"))
|
||||
|
||||
# Decode the cipher text by feeding it to cipher_op getting plain text back.
|
||||
# Append the final bit of plain text by calling digest_final
|
||||
decoded_text = decoding_ctx.cipher_op(cipher_text)
|
||||
decoded_text += decoding_ctx.digest_final()
|
||||
|
||||
if verbose:
|
||||
print "Decoded Text:\n%s" % (decoded_text)
|
||||
|
||||
# Validate the encryption/decryption by comparing the decoded text with
|
||||
# the original plain text, they should match.
|
||||
if decoded_text != plain_text:
|
||||
result = 1
|
||||
print "FAILED! decoded_text != plain_text"
|
||||
|
||||
if cipher_text == plain_text:
|
||||
result = 1
|
||||
print "FAILED! cipher_text == plain_text"
|
||||
|
||||
return result
|
||||
|
||||
def file_test(encoding_ctx, decoding_ctx, in_filename, chunk_size):
|
||||
result = 0
|
||||
|
||||
encrypted_filename = os.path.basename(in_filename) + ".encrypted"
|
||||
decrypted_filename = os.path.basename(in_filename) + ".decrypted"
|
||||
|
||||
in_file = open(in_filename, "r")
|
||||
encrypted_file = open(encrypted_filename, "w")
|
||||
|
||||
if verbose:
|
||||
print "Encrypting file \"%s\" to \"%s\"" % (in_filename, encrypted_filename)
|
||||
|
||||
# Encode the data read from a file in chunks
|
||||
while True:
|
||||
# Read a chunk of data until EOF, encrypt it and write the encrypted data
|
||||
in_data = in_file.read(chunk_size)
|
||||
if len(in_data) == 0: # EOF
|
||||
break
|
||||
encrypted_data = encoding_ctx.cipher_op(in_data)
|
||||
encrypted_file.write(encrypted_data)
|
||||
# Done encoding the input, get the final encoded data, write it, close files
|
||||
encrypted_data = encoding_ctx.digest_final()
|
||||
encrypted_file.write(encrypted_data)
|
||||
in_file.close()
|
||||
encrypted_file.close()
|
||||
|
||||
# Decode the encoded file in a similar fashion
|
||||
if verbose:
|
||||
print "Decrypting file \"%s\" to \"%s\"" % (encrypted_filename, decrypted_filename)
|
||||
|
||||
encrypted_file = open(encrypted_filename, "r")
|
||||
decrypted_file = open(decrypted_filename, "w")
|
||||
while True:
|
||||
# Read a chunk of data until EOF, encrypt it and write the encrypted data
|
||||
in_data = encrypted_file.read(chunk_size)
|
||||
if len(in_data) == 0: # EOF
|
||||
break
|
||||
decrypted_data = decoding_ctx.cipher_op(in_data)
|
||||
decrypted_file.write(decrypted_data)
|
||||
# Done encoding the input, get the final encoded data, write it, close files
|
||||
decrypted_data = decoding_ctx.digest_final()
|
||||
decrypted_file.write(decrypted_data)
|
||||
encrypted_file.close()
|
||||
decrypted_file.close()
|
||||
|
||||
# Validate the encryption/decryption by comparing the decoded text with
|
||||
# the original plain text, they should match.
|
||||
in_data = open(in_filename).read()
|
||||
encrypted_data = open(encrypted_filename).read()
|
||||
decrypted_data = open(decrypted_filename).read()
|
||||
if decrypted_data != in_data:
|
||||
result = 1
|
||||
print "FAILED! decrypted_data != in_data"
|
||||
|
||||
if encrypted_data == in_data:
|
||||
result = 1
|
||||
print "FAILED! encrypted_data == in_data"
|
||||
|
||||
# clean up
|
||||
os.unlink(encrypted_filename)
|
||||
os.unlink(decrypted_filename)
|
||||
|
||||
return result
|
||||
|
||||
def usage():
|
||||
print '''\
|
||||
digest_test [-v -h] filename
|
||||
filename file to be used as test data
|
||||
-v --verbose turn on verbose output
|
||||
-h --help print usage
|
||||
-s --size number of octets processed in one iteration
|
||||
-m --mech encryption mechanism name (e.g. CKM_*)
|
||||
name is case insensitive, CKM_ prefix is optional
|
||||
-t --text plain text
|
||||
-k --key key (in hexadecimal format)
|
||||
-i --iv parameter initial value (in hexadecimal format)
|
||||
'''
|
||||
|
||||
def main():
|
||||
global verbose
|
||||
mechanism = nss.CKM_DES_CBC_PAD
|
||||
plain_text = "Encrypt me!"
|
||||
key = "e8:a7:7c:e2:05:63:6a:31"
|
||||
iv = "e4:bb:3b:d3:c3:71:2e:58"
|
||||
in_filename = None
|
||||
chunk_size = 128
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hvs:m:t:k:i:",
|
||||
["help", "verbose", "size=", "mechanism=", "text=",
|
||||
"key=", "iv="])
|
||||
except getopt.GetoptError, err:
|
||||
print str(err) # will print something like "option -a not recognized"
|
||||
usage()
|
||||
sys.exit(2)
|
||||
verbose = False
|
||||
for o, a in opts:
|
||||
if o in ("-s", "--size"):
|
||||
chunk_size = int(a)
|
||||
elif o in ("-m", "--mech"):
|
||||
try:
|
||||
mechanism = nss.key_mechanism_type_from_name(a)
|
||||
except Exception, e:
|
||||
print "error with mech argument (%s)" % (e)
|
||||
sys.exit(2)
|
||||
elif o in ("-t", "--text"):
|
||||
plain_text = a
|
||||
elif o in ("-k", "--key"):
|
||||
key = a
|
||||
elif o in ("-i", "--iv"):
|
||||
iv = a
|
||||
elif o in ("-v", "--verbose"):
|
||||
verbose += 1
|
||||
elif o in ("-h", "--help"):
|
||||
usage()
|
||||
sys.exit(0)
|
||||
else:
|
||||
assert False, "unhandled option"
|
||||
|
||||
if (len(args) > 1):
|
||||
print "expected single file name"
|
||||
usage()
|
||||
sys.exit(2)
|
||||
elif (len(args) == 1):
|
||||
in_filename = args[0]
|
||||
|
||||
nss.nss_init_nodb()
|
||||
|
||||
result = 0
|
||||
encoding_ctx, decoding_ctx = setup_contexts(mechanism, key, iv)
|
||||
result += simple_test(encoding_ctx, decoding_ctx, plain_text)
|
||||
if in_filename:
|
||||
# In theory we should be able to reuse a context by calling finalize()
|
||||
# on it, however at the time of this writing it only works for
|
||||
# digest contexts, not encryption/decryption contexts
|
||||
# so as a workaround we just create the contexts again
|
||||
#
|
||||
#encoding_ctx.finalize()
|
||||
#decoding_ctx.finalize()
|
||||
encoding_ctx, decoding_ctx = setup_contexts(mechanism, key, iv)
|
||||
result += file_test(encoding_ctx, decoding_ctx, in_filename, chunk_size)
|
||||
|
||||
if result == 0:
|
||||
print "SUCCESS"
|
||||
else:
|
||||
print "FAILED %d tests" % (result)
|
||||
|
||||
sys.exit(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
177
mozilla/security/python/nss/test/digest_test.py
Executable file
177
mozilla/security/python/nss/test/digest_test.py
Executable file
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# used for local testing
|
||||
#from test_util import insert_build_dir_into_path
|
||||
#insert_build_dir_into_path()
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import getopt
|
||||
import nss.nss as nss
|
||||
|
||||
verbose = False
|
||||
|
||||
tests = [
|
||||
{"name" : "md5",
|
||||
"ref_cmd" : "md5sum",
|
||||
"nss_digest_func" : nss.md5_digest,
|
||||
"hash_oid" : nss.SEC_OID_MD5},
|
||||
{"name" : "sha1",
|
||||
"ref_cmd" : "sha1sum",
|
||||
"nss_digest_func" : nss.sha1_digest,
|
||||
"hash_oid" : nss.SEC_OID_SHA1},
|
||||
{"name" : "sha256",
|
||||
"ref_cmd" : "sha256sum",
|
||||
"nss_digest_func" : nss.sha256_digest,
|
||||
"hash_oid" : nss.SEC_OID_SHA256},
|
||||
{"name" : "sha512",
|
||||
"ref_cmd" : "sha512sum",
|
||||
"nss_digest_func" : nss.sha512_digest,
|
||||
"hash_oid" : nss.SEC_OID_SHA512},
|
||||
]
|
||||
|
||||
|
||||
def do_test(name, ref_cmd, nss_digest_func, hash_oid, in_filename, chunk_size):
|
||||
result = 0
|
||||
|
||||
hash_oid_name = nss.sec_oid_tag_str(hash_oid)
|
||||
|
||||
print "running test %s: nss_digest_func=%s hash_oid=%s" % \
|
||||
(name, nss_digest_func.__name__, hash_oid_name)
|
||||
|
||||
print nss.sec_oid_tag_from_name("sha512")
|
||||
print "%s = %d" % (nss.sec_oid_tag_name(hash_oid), nss.sec_oid_tag_from_name(nss.sec_oid_tag_name(hash_oid)))
|
||||
|
||||
# read the data in from the file
|
||||
ref_data = open(in_filename).read()
|
||||
|
||||
# Run the system hash function to get a reference result.
|
||||
# Since we're testing the python-nss binding we assume
|
||||
# the system command is entirely independent and correct.
|
||||
#
|
||||
# Because our digest routines return raw data (e.g. a buffer of octets)
|
||||
# and the system hash command returns a hex string which we need to compare agains,
|
||||
# and because we sometimes want to print the result of our digest functions
|
||||
# always convert our results to a hex string via nss.data_to_hex()
|
||||
proc = subprocess.Popen([ref_cmd, in_filename], stdout=subprocess.PIPE)
|
||||
status = proc.wait();
|
||||
reference_digest = proc.stdout.read().split()[0]
|
||||
if verbose:
|
||||
print "reference_digest\n%s" % (reference_digest)
|
||||
else:
|
||||
print reference_digest
|
||||
|
||||
# Run the test with convenience digest function (e.g. nss.sha256_digest, etc.).
|
||||
test_digest = nss.data_to_hex(nss_digest_func(ref_data))
|
||||
if verbose: print "nss %s\n%s" % (nss_digest_func.__name__, test_digest)
|
||||
|
||||
if test_digest != reference_digest:
|
||||
result += 1
|
||||
print "nss %s test failed" % (nss_digest_func.__name__)
|
||||
print "reference = %s" % (reference_digest)
|
||||
print "test = %s" % (test_digest)
|
||||
|
||||
# Run the test using the generic hash_buf function specifying the hash algorithm.
|
||||
test_digest = nss.data_to_hex(nss.hash_buf(hash_oid, ref_data))
|
||||
if verbose: print "nss.hash_buf %s\n%s" % (hash_oid_name, test_digest)
|
||||
|
||||
if test_digest != reference_digest:
|
||||
result += 1
|
||||
print "nss.hash_buf %s test failed" % (hash_oid_name)
|
||||
print "reference = %s" % (reference_digest)
|
||||
print "test = %s" % (test_digest)
|
||||
|
||||
# Run the test using the lowest level hashing functions by specifying the hash algorithm.
|
||||
# The entire input data is supplied all at once in a single call.
|
||||
context = nss.create_digest_context(hash_oid)
|
||||
context.digest_begin()
|
||||
context.digest_op(ref_data)
|
||||
test_digest = nss.data_to_hex(context.digest_final())
|
||||
if verbose: print "nss.digest_context %s\n%s" % (hash_oid_name, test_digest)
|
||||
|
||||
if test_digest != reference_digest:
|
||||
result += 1
|
||||
print "nss.digest_context %s test failed" % (hash_oid_name)
|
||||
print "reference = %s" % (reference_digest)
|
||||
print "test = %s" % (test_digest)
|
||||
|
||||
# Run the test using the lowest level hashing functions by specifying the hash algorithm
|
||||
# and feeding "chunks" of data one at a time to be consumed.
|
||||
in_file = open(in_filename, "r")
|
||||
context = nss.create_digest_context(hash_oid)
|
||||
context.digest_begin()
|
||||
while True:
|
||||
in_data = in_file.read(chunk_size)
|
||||
if len(in_data) == 0:
|
||||
break
|
||||
context.digest_op(in_data)
|
||||
|
||||
test_digest = nss.data_to_hex(context.digest_final())
|
||||
if verbose: print "chunked nss.digest_context %s\n%s" % (hash_oid_name, test_digest)
|
||||
|
||||
if test_digest != reference_digest:
|
||||
result += 1
|
||||
print "chunked nss.digest_context %s test failed" % (hash_oid_name)
|
||||
print "reference = %s" % (reference_digest)
|
||||
print "test = %s" % (test_digest)
|
||||
|
||||
return result
|
||||
|
||||
def usage():
|
||||
print '''\
|
||||
digest_test [-v -h] filename
|
||||
filename file to be used as test data
|
||||
-v --verbose turn on verbose output
|
||||
-h --help print usage
|
||||
-s --size number of octets processed in one iteration
|
||||
'''
|
||||
|
||||
def main():
|
||||
global verbose
|
||||
in_filename=''
|
||||
chunk_size = 128
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hvs:",
|
||||
["help", "verbose", "size="])
|
||||
except getopt.GetoptError, err:
|
||||
print str(err) # will print something like "option -a not recognized"
|
||||
usage()
|
||||
sys.exit(2)
|
||||
verbose = False
|
||||
for o, a in opts:
|
||||
if o in ("-s", "--size"):
|
||||
chunk_size = int(a)
|
||||
elif o in ("-v", "--verbose"):
|
||||
verbose = True
|
||||
elif o in ("-h", "--help"):
|
||||
usage()
|
||||
sys.exit(0)
|
||||
else:
|
||||
assert False, "unhandled option"
|
||||
|
||||
if (len(args) != 1):
|
||||
print "expected single file name"
|
||||
usage()
|
||||
sys.exit(2)
|
||||
|
||||
in_filename = args[0]
|
||||
|
||||
nss.nss_init_nodb()
|
||||
|
||||
result = 0
|
||||
for test in tests:
|
||||
result += do_test(test["name"], test["ref_cmd"], test["nss_digest_func"],
|
||||
test["hash_oid"], in_filename, chunk_size)
|
||||
|
||||
if result == 0:
|
||||
print "SUCCESS"
|
||||
else:
|
||||
print "FAILED %d tests" % (result)
|
||||
|
||||
sys.exit(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user