Обновлён m2crypto для работы calculate-utils

rasdark
parent 0138452a0c
commit 6de2ef7cbc

@ -1 +1,2 @@
DIST M2Crypto-0.22.3.tar.gz 74795 SHA256 6071bfc817d94723e9b458a010d565365104f84aa73f7fe11919871f7562ff72 SHA512 c179d3cf03ced77aed24285ca3f1527d5e05bbfe091a1522bff94a940fd390213fbb9b83d7ccd43ceae49626b427ae8790782cf93ead85be1e063bc4121c62e0 WHIRLPOOL 66a9a6e7c9b195814048a1bcecf6ef71a269bebb9dbda73801c88b3ba27330b555a46d05c53bbd0778f9c1e1bb5f9c6e7e860de443bf16baffc2072ee5996e31
DIST M2Crypto-0.24.0.tar.gz 184457 SHA256 80a56441a1d2c0cf27e725be7554c92598b938fc8767ee2c71fdbc2fdc055ee8 SHA512 c23ae0f8ac790d4ef108a217a44e994341f6bbe4e12a7fef2518d8def82331246a145e19a2504b82b790a3ad4b467d2facc8a73bb7f1190b56441d8482c66aca WHIRLPOOL 47a437ee1207b4cca8d67aa4bdec95b9194030e3fc7146ace8d071caa9be829f3e9516ff9399e695615acdf930a90040deb0f1175d81994465ed0853688e3b37

@ -0,0 +1,245 @@
diff --git M2Crypto/X509.py M2Crypto/X509.py
index 62096f3..500f740 100644
--- M2Crypto/X509.py
+++ M2Crypto/X509.py
@@ -29,9 +29,11 @@ def new_extension(name, value, critical=0, _pyfree=1):
"""
Create new X509_Extension instance.
"""
- if name == 'subjectKeyIdentifier' and \
- value.strip('0123456789abcdefABCDEF:') is not '':
- raise ValueError('value must be precomputed hash')
+ if X509_Extension_Proxy.must_proxy(name, value):
+ # Maybe all extensions should be proxies?
+ # XXX Either all proxies (might solve other problems too), or at
+ # XXX least at least need to refactor to avoid code duplication
+ return X509_Extension_Proxy(name, value, critical, _pyfree)
lhash = m2.x509v3_lhash()
ctx = m2.x509v3_set_conf_lhash(lhash)
x509_ext_ptr = m2.x509v3_ext_conf(lhash, ctx, name, value)
@@ -40,6 +42,96 @@ def new_extension(name, value, critical=0, _pyfree=1):
return x509_ext
+class X509_Extension_Proxy:
+ """
+ A holder object for X509 Extensions that need to be created with
+ certificate based calculated values.
+ """
+ def __init__ (self, name, value, critical=0, _pyfree=1):
+ self.name = name
+ self.value = value
+ self.critical = critical
+ self._pyfree = _pyfree
+
+ @staticmethod
+ def must_proxy (name, value):
+ """
+ Checks if this extension name and value define a calculated extension,
+ i.e. one that needs the certificate to render a valid value.
+ """
+ # XXX Are these the only cases where we must proxy?
+ # XXX Even if they are now, it does not seem this is future proof...
+ # XXX any other way around this?
+ return (name == 'subjectKeyIdentifier' and value == 'hash') or \
+ (name == 'authorityKeyIdentifier')
+
+ def set_critical(self, critical=1):
+ """
+ Mark this extension critical or noncritical. By default an
+ extension is not critical.
+
+ @type critical: int
+ @param critical: Nonzero sets this extension as critical.
+ Calling this method without arguments will
+ set this extension to critical.
+ """
+ self.critical = critical
+ return self.critical
+
+ def get_critical(self):
+ """
+ Return whether or not this is a critical extension.
+
+ @rtype: int
+ @return: Nonzero if this is a critical extension.
+ """
+ return self.critical
+
+ def get_name(self):
+ """
+ Get the extension name, for example 'subjectAltName'.
+ """
+ return self.name
+
+ def get_value(self, flag=0, indent=0):
+ """
+ Get the extension value, for example 'DNS:www.example.com'.
+
+ @param flag: Flag to control what and how to print.
+ Ignored in this proxy.
+ @param indent: How many spaces to print before actual value.
+ """
+ # XXX It is a problem that this method can give different output
+ # XXX compared to the real object.
+ return (" " * indent) + self.value
+
+ def __call__ (self, cert=None):
+ """
+ Create new X509_Extension instance.
+ """
+ # XXX Why is this __call__, wouldn't it be clearer to have an explicit
+ # XXX name for this? Or is there some usage I am missing...?
+ lhash = m2.x509v3_lhash()
+ ctx = m2.x509v3_set_conf_lhash(lhash)
+ if cert:
+ if isinstance(cert, X509) and m2.x509_type_check(cert.x509):
+ m2.x509v3_set_ctx_subject(ctx, cert.x509)
+ if cert.issuer and m2.x509_type_check(cert.issuer.x509):
+ m2.x509v3_set_ctx_issuer(ctx, cert.issuer.x509)
+ else:
+ m2.x509v3_set_ctx_issuer(ctx, cert.x509)
+ elif isinstance(cert, Request) and cert.req:
+ m2.x509v3_set_ctx_request(ctx, cert.req)
+ else:
+ if self.name == 'subjectKeyIdentifier' and self.value == 'hash':
+ raise ValueError('value must be precomputed hash if no context is given')
+
+ x509_ext_ptr = m2.x509v3_ext_conf(lhash, ctx, self.name, self.value)
+ x509_ext = X509_Extension(x509_ext_ptr, self._pyfree)
+ x509_ext.set_critical(self.critical)
+ return x509_ext
+
+
class X509_Extension: # noqa
"""
X509 Extension
@@ -123,6 +215,7 @@ class X509_Extension_Stack: # noqa
self.stack = m2.sk_x509_extension_new_null()
self._pyfree = 1
self.pystack = [] # This must be kept in sync with self.stack
+ self.proxies = []
def __del__(self):
if getattr(self, '_pyfree', 0):
@@ -149,6 +242,9 @@ class X509_Extension_Stack: # noqa
@param x509_ext: X509_Extension object to be pushed onto the stack.
@return: The number of extensions on the stack.
"""
+ if isinstance(x509_ext, X509_Extension_Proxy):
+ self.proxies.append(x509_ext)
+ return len(self.proxies)
self.pystack.append(x509_ext)
ret = m2.sk_x509_extension_push(self.stack, x509_ext._ptr())
assert ret == len(self.pystack)
@@ -166,6 +262,14 @@ class X509_Extension_Stack: # noqa
return None
return self.pystack.pop()
+ def process_proxies(self, cert):
+ """
+ Create extensions from stored proxies, now that we have a context to work with.
+ """
+ for p in self.proxies:
+ self.push(p(cert))
+ self.proxies = []
+
class X509_Name_Entry: # noqa
"""
@@ -350,6 +454,7 @@ class X509:
else:
self.x509 = m2.x509_new()
self._pyfree = 1
+ self.issuer = None
def __del__(self):
if getattr(self, '_pyfree', 0):
@@ -488,15 +593,18 @@ class X509:
assert m2.x509_type_check(self.x509), "'x509' type error"
return X509_Name(m2.x509_get_issuer_name(self.x509))
- def set_issuer(self, name):
+ def set_issuer(self, issuer):
"""
- Set issuer name.
+ Set issuer object (and set issuer name). The object will be used in extension contexts if needed.
- @type name: X509_Name
- @param name: subjectName field.
+ @type name: X509_Name or X509
+ @param name: subjectName field or issuer object.
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
- return m2.x509_set_issuer_name(self.x509, name.x509_name)
+ if isinstance(issuer, X509):
+ self.issuer = issuer
+ issuer = X509_Name(m2.x509_get_subject_name(issuer.x509))
+ return m2.x509_set_issuer_name(self.x509, issuer.x509_name)
def get_subject(self):
assert m2.x509_type_check(self.x509), "'x509' type error"
@@ -519,6 +627,9 @@ class X509:
@type ext: X509_Extension
@param ext: Extension
"""
+ if isinstance(ext, X509_Extension_Proxy):
+ ext = ext(self)
+
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_add_ext(self.x509, ext.x509_ext, -1)
@@ -1003,6 +1114,7 @@ class Request:
@type ext_stack: X509_Extension_Stack
@param ext_stack: Stack of extensions to add.
"""
+ ext_stack.process_proxies(self)
return m2.x509_req_add_extensions(self.req, ext_stack._ptr())
def verify(self, pkey):
diff --git SWIG/_x509.i SWIG/_x509.i
index be3099a..0ab1c78 100644
--- SWIG/_x509.i
+++ SWIG/_x509.i
@@ -531,6 +531,10 @@ x509v3_set_conf_lhash(LHASH * lhash) {
PyErr_SetString(PyExc_MemoryError, "x509v3_set_conf_lhash");
return NULL;
}
+ /* XXX Why is this needed? */
+ /* Make sure the structure members are nulled */
+ X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, 0);
+
X509V3_set_conf_lhash(ctx, lhash);
return ctx;
}
@@ -659,6 +663,30 @@ get_der_encoding_stack(STACK_OF(X509) *stack){
return encodedString;
}
+/* XXX Are these simple pointers in the context, or should they be refcounted? */
+
+/* XXX Since these are really only used in one method, should these instead be
+ * XXX made into a single function, which can be called with NULL for
+ * XXX optional fields? Otherwise, what is there stopping calling
+ * XXX set_ctx_subject without having set ctx first? */
+
+void x509v3_set_ctx_issuer(X509V3_CTX *ctx, X509 *issuer) {
+ ctx->issuer_cert = issuer;
+}
+
+void x509v3_set_ctx_subject(X509V3_CTX *ctx, X509 *subject) {
+ ctx->subject_cert = subject;
+}
+
+void x509v3_set_ctx_request(X509V3_CTX *ctx, X509_REQ *request) {
+ ctx->subject_req = request;
+}
+
+/* XXX This does not seem to be used, why is it here? */
+void x509v3_set_ctx_crl(X509V3_CTX *ctx, X509_CRL *crl) {
+ ctx->crl = crl;
+}
+
%}
/* Free malloc'ed return value for x509_name_oneline */

@ -0,0 +1,43 @@
# Copyright 1999-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$
EAPI=5
PYTHON_COMPAT=( python2_7 )
PYTHON_REQ_USE="threads(+)"
inherit distutils-r1
MY_PN="M2Crypto"
DESCRIPTION="M2Crypto: A Python crypto and SSL toolkit"
HOMEPAGE="https://gitlab.com/m2crypto/m2crypto https://pypi.python.org/pypi/M2Crypto"
SRC_URI="mirror://pypi/${MY_PN:0:1}/${MY_PN}/${MY_PN}-${PV}.tar.gz"
LICENSE="BSD"
SLOT="0"
KEYWORDS="alpha amd64 ~arm ~arm64 hppa ~ia64 ~mips ~ppc ppc64 ~s390 ~sh ~sparc x86 ~amd64-fbsd ~x86-fbsd ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos"
IUSE="libressl"
RDEPEND="
!libressl? ( >=dev-libs/openssl-0.9.8:0= )
libressl? ( dev-libs/libressl:= )
"
DEPEND="${RDEPEND}
>=dev-lang/swig-1.3.28:0
dev-python/setuptools[${PYTHON_USEDEP}]
"
S="${WORKDIR}/${MY_PN}-${PV}"
# Tests access network, and fail randomly. Bug #431458.
RESTRICT=test
PATCHES=(
"${FILESDIR}"/m2crypto-extension-work-0.24.0.patch
)
python_test() {
esetup.py test
}

@ -151,7 +151,8 @@ RDEPEND="
net-libs/dslib[python_targets_python2_7]
>=dev-python/pyopenssl-0.14[python_targets_python2_7]
dev-libs/openssl
=dev-python/m2crypto-0.22.3-r9[python_targets_python2_7]
|| ( =dev-python/m2crypto-0.22.3-r9[python_targets_python2_7]
=dev-python/m2crypto-0.24.0-r9[python_targets_python2_7] )
dev-python/cherrypy[python_targets_python2_7]
dev-python/pytz[python_targets_python2_7]
)

Loading…
Cancel
Save