[Commits] (heikki) Certificate extensions,
memory leak fixes and other cleanup.
commits at osafoundation.org
commits at osafoundation.org
Thu Mar 11 21:17:26 PST 2004
Commit by: heikki
Modified files:
osaf/chandler/m2crypto/M2Crypto/X509.py 1.4 1.5
osaf/chandler/m2crypto/M2Crypto/__init__.py 1.1.1.1 1.2
osaf/chandler/m2crypto/SWIG/_x509.i 1.5 1.6
osaf/chandler/m2crypto/demo/x509/ca.py 1.5 1.6
Log message:
Certificate extensions, memory leak fixes and other cleanup.
ViewCVS links:
http://cvs.osafoundation.org/index.cgi/osaf/chandler/m2crypto/M2Crypto/X509.py.diff?r1=text&tr1=1.4&r2=text&tr2=1.5
http://cvs.osafoundation.org/index.cgi/osaf/chandler/m2crypto/M2Crypto/__init__.py.diff?r1=text&tr1=1.1.1.1&r2=text&tr2=1.2
http://cvs.osafoundation.org/index.cgi/osaf/chandler/m2crypto/SWIG/_x509.i.diff?r1=text&tr1=1.5&r2=text&tr2=1.6
http://cvs.osafoundation.org/index.cgi/osaf/chandler/m2crypto/demo/x509/ca.py.diff?r1=text&tr1=1.5&r2=text&tr2=1.6
Index: osaf/chandler/m2crypto/demo/x509/ca.py
diff -u osaf/chandler/m2crypto/demo/x509/ca.py:1.5 osaf/chandler/m2crypto/demo/x509/ca.py:1.6
--- osaf/chandler/m2crypto/demo/x509/ca.py:1.5 Mon Mar 8 20:23:42 2004
+++ osaf/chandler/m2crypto/demo/x509/ca.py Thu Mar 11 21:16:55 2004
@@ -32,7 +32,12 @@
name = X509.X509_Name()
name.CN = 'My CA, Inc.'
req.set_subject(name)
- # XXX Extensions
+ ext1 = X509.X509_Extension('subjectAltName', 'DNS:foobar.example.com')
+ ext2 = X509.X509_Extension('nsComment', 'Hello there')
+ extstack = X509.X509_Extension_Stack()
+ extstack.push(ext1)
+ extstack.push(ext2)
+ req.add_extensions(extstack)
req.sign(pkey, 'sha1')
return req
@@ -65,7 +70,11 @@
m2.x509_gmtime_adj(notBefore, 0)
days = 30
m2.x509_gmtime_adj(notAfter, 60*60*24*days)
- # XXX extensions
+ cert.add_ext(
+ X509.X509_Extension('subjectAltName', 'DNS:foobar.example.com'))
+ ext = X509.X509_Extension('nsComment', 'M2Crypto generated certificate')
+ ext.set_critical(0)# Defaults to non-critical, but we can also set it
+ cert.add_ext(ext)
cert.sign(caPkey, 'sha1')
return cert
Index: osaf/chandler/m2crypto/M2Crypto/__init__.py
diff -u osaf/chandler/m2crypto/M2Crypto/__init__.py:1.1.1.1 osaf/chandler/m2crypto/M2Crypto/__init__.py:1.2
--- osaf/chandler/m2crypto/M2Crypto/__init__.py:1.1.1.1 Mon Mar 1 11:43:40 2004
+++ osaf/chandler/m2crypto/M2Crypto/__init__.py Thu Mar 11 21:16:53 2004
@@ -1,8 +1,12 @@
"""M2Crypto = Python + OpenSSL + SWIG
-Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved."""
+Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
-RCS_id='$Id: __init__.py,v 1.1.1.1 2004/03/01 19:43:40 heikki Exp $'
+Portions created by Open Source Applications Foundation (OSAF) are
+Copyright (C) 2004 OSAF. All Rights Reserved.
+"""
+
+RCS_id='$Id: __init__.py,v 1.2 2004/03/12 05:16:53 heikki Exp $'
import __m2crypto
import BIO
Index: osaf/chandler/m2crypto/M2Crypto/X509.py
diff -u osaf/chandler/m2crypto/M2Crypto/X509.py:1.4 osaf/chandler/m2crypto/M2Crypto/X509.py:1.5
--- osaf/chandler/m2crypto/M2Crypto/X509.py:1.4 Mon Mar 8 20:23:37 2004
+++ osaf/chandler/m2crypto/M2Crypto/X509.py Thu Mar 11 21:16:53 2004
@@ -7,15 +7,15 @@
Copyright (c) 1999-2003 Ng Pheng Siong. All rights reserved.
Open Source Applications Foundation (OSAF) has extended the functionality
-to make it possible to create and verify certificates programmatically.
+to make it possible to create certificates programmatically.
-Epydoc comments also by OSAF.
+Epydoc comments started by OSAF.
OSAF Changes copyright (c) 2004 Open Source Applications Foundation.
Author: Heikki Toivonen
"""
-RCS_id='$Id: X509.py,v 1.4 2004/03/09 04:23:37 heikki Exp $'
+RCS_id='$Id: X509.py,v 1.5 2004/03/12 05:16:53 heikki Exp $'
# M2Crypto
import ASN1, BIO, Err
@@ -27,6 +27,81 @@
V_OK = m2.X509_V_OK
+
+class X509_Extension:
+ """
+ X509 extension.
+
+ XXX Does not allow copying from existing extension.
+ """
+ def __init__(self, name, value, critical=0):
+ self.x509_ext = m2.x509v3_ext_conf(None, None, name, value)
+ self.set_critical(critical)
+
+ def __del__(self):
+ m2.x509_extension_free(self.x509_ext)
+
+ def _ptr(self):
+ return self.x509_ext
+
+ def set_critical(self, critical=1):
+ """
+ Mark this extension critical or noncritical. By default an
+ extension is not critical.
+
+ @type critical: integer
+ @param critical: Nonzero sets this extension as critical. Calling
+ this method without arguments will set this extension
+ to critical.
+ """
+ return m2.x509_extension_set_critical(self.x509_ext, critical)
+
+ def get_critical(self):
+ """
+ Return whether or not this is a critical extension.
+
+ @rtype: integer
+ @return: Nonzero if this is a critical extension.
+ """
+ return m2.x509_extension_get_critical(self.x509_ext)
+
+
+class X509_Extension_Stack:
+ def __init__(self, stack=None, _pyfree=0):
+ if stack is not None:
+ self.stack = stack
+ self._pyfree = _pyfree
+ else:
+ self.stack = m2.sk_x509_extension_new_null()
+ self._pyfree = 1
+ self._refkeeper = {}
+
+ def __del__(self):
+ if self._pyfree:
+ m2.sk_x509_extension_free(self.stack)
+
+ def __len__(self):
+ return m2.sk_x509_extension_num(self.stack)
+
+ # XXX How do I get the actual X509_EXTENSION from the stack?
+ #def __getitem__(self, idx):
+ # if idx < 0 or idx >= m2.sk_x509_extension_num(self.stack):
+ # raise IndexError, 'index out of range'
+ # v=m2.sk_x509_extension_value(self.stack, idx)
+ # return X509_Extension(v)
+
+ def _ptr(self):
+ return self.stack
+
+ def push(self, x509_ext):
+ self._refkeeper[x509_ext._ptr()] = x509_ext
+ return m2.sk_x509_extension_push(self.stack, x509_ext._ptr())
+
+ def pop(self):
+ x509__ext_ptr = m2.sk_x509_extension_pop(self.stack)
+ del self._refkeeper[x509_ext_ptr]
+
+
class X509_Store_Context:
def __init__(self, x509_store_ctx, _pyfree=0):
self.ctx = x509_store_ctx
@@ -52,9 +127,10 @@
if x509_name is not None:
assert m2.x509_name_type_check(x509_name), "'x509_name' type error"
self.x509_name = x509_name
+ self._pyfree = _pyfree
else:
self.x509_name = m2.x509_name_new()
- self._pyfree = _pyfree
+ self._pyfree = 1
def __del__(self):
try:
@@ -92,9 +168,10 @@
if x509 is not None:
assert m2.x509_type_check(x509), "'x509' type error"
self.x509 = x509
+ self._pyfree = _pyfree
else:
self.x509 = m2.x509_new()
- self._pyfree = _pyfree
+ self._pyfree = 1
def __del__(self):
try:
@@ -148,8 +225,6 @@
@type serial: integer
@param serial: Serial number.
- @rtype: XXX
- @return: XXX
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
# This "magically" changes serial since asn1_integer is C pointer
@@ -181,8 +256,6 @@
@type pkey: EVP_PKEY
@param pkey: Public key
- @rtype: XXX
- @return: XXX
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_set_pubkey(self.x509, pkey.pkey)
@@ -197,8 +270,6 @@
@type name: X509_Name
@param name: subjectName field.
- @rtype: XXX
- @return: XXX
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_set_issuer_name(self.x509, name.x509_name)
@@ -213,12 +284,20 @@
@type name: X509_Name
@param name: subjectName field.
- @rtype: XXX
- @return: XXX
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
return m2.x509_set_subject_name(self.x509, name.x509_name)
+ def add_ext(self, ext):
+ """
+ Add X509 extension to this certificate.
+
+ @type ext: X509_Extension
+ @param ext: Extension
+ """
+ assert m2.x509_type_check(self.x509), "'x509' type error"
+ return m2.x509_add_ext(self.x509, ext.x509_ext, -1)
+
def sign(self, pkey, md):
"""
Sign the certificate.
@@ -228,8 +307,6 @@
@type md: string
@param md: Message digest algorithm to use for signing, for example
'sha1'.
- @rtype: XXX
- @return: XXX
"""
assert m2.x509_type_check(self.x509), "'x509' type error"
mda = getattr(m2, md)
@@ -353,8 +430,6 @@
@type pkey: EVP_PKEY
@param pkey: Public key
- @rtype: XXX
- @return: XXX
"""
return m2.x509_req_set_pubkey(self.req, pkey.pkey)
@@ -367,8 +442,6 @@
@type name: X509_Name
@param name: subjectName field.
- @rtype: XXX
- @return: XXX
"""
return m2.x509_req_set_subject_name(self.req, name.x509_name)
@@ -391,6 +464,15 @@
@return: Returns 0 on failure.
"""
return m2.x509_req_set_version(self.req, version)
+
+ def add_extensions(self, ext_stack):
+ """
+ Add X509 extensions to this request.
+
+ @type ext_stack: X509_Extension_Stack
+ @param ext_stack: Stack of extensions to add.
+ """
+ return m2.x509_req_add_extensions(self.req, ext_stack._ptr())
def verify(self, pkey):
return m2.x509_req_verify(self.req, pkey)
Index: osaf/chandler/m2crypto/SWIG/_x509.i
diff -u osaf/chandler/m2crypto/SWIG/_x509.i:1.5 osaf/chandler/m2crypto/SWIG/_x509.i:1.6
--- osaf/chandler/m2crypto/SWIG/_x509.i:1.5 Mon Mar 8 20:23:40 2004
+++ osaf/chandler/m2crypto/SWIG/_x509.i Thu Mar 11 21:16:54 2004
@@ -1,16 +1,17 @@
/* Copyright (c) 1999 Ng Pheng Siong. All rights reserved. */
/*
-** Open Source Applications Foundation (OSAF) has extended the functionality
-** to make it possible to create and verify certificates programmatically.
+** Open Source Applications Foundation (OSAF) has extended the
+** API to enable creation of certificates programmatically.
**
** OSAF Changes copyright (c) 2004 Open Source Applications Foundation.
** Author: Heikki Toivonen
*/
-/* $Id: _x509.i,v 1.5 2004/03/09 04:23:40 heikki Exp $ */
+/* $Id: _x509.i,v 1.6 2004/03/12 05:16:54 heikki Exp $ */
%{
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
%}
%apply Pointer NONNULL { BIO * };
@@ -40,6 +41,8 @@
%name(x509_get_verify_error) extern const char *X509_verify_cert_error_string(long);
+%name(x509_add_ext) extern int X509_add_ext(X509 *, X509_EXTENSION *, int);
+
%name(x509_req_get_pubkey) extern EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *);
%name(x509_req_set_pubkey) extern int X509_REQ_set_pubkey(X509_REQ *, EVP_PKEY *);
@@ -49,6 +52,9 @@
%name(x509_store_free) extern void X509_STORE_free(X509_STORE *);
%name(x509_store_add_cert) extern int X509_STORE_add_cert(X509_STORE *, X509 *);
+%name(x509_extension_get_critical) extern int X509_EXTENSION_get_critical(X509_EXTENSION *);
+%name(x509_extension_set_critical) extern int X509_EXTENSION_set_critical(X509_EXTENSION *, int);
+
%constant int NID_commonName = 13;
%constant int NID_countryName = 14;
%constant int NID_localityName = 15;
@@ -204,6 +210,45 @@
return sk_X509_pop((STACK_OF(X509) *)stack);
}
+X509_EXTENSION *x509v3_ext_conf(LHASH *conf, X509V3_CTX *ctx, char *name, char *value) {
+ return X509V3_EXT_conf(conf, ctx, name, value);
+}
+
+/* X509_EXTENSION_free() might be a macro, didn't find definition. */
+void x509_extension_free(X509_EXTENSION *ext) {
+ X509_EXTENSION_free(ext);
+}
+
+/* sk_X509_EXTENSION_new_null is a macro. */
+STACK *sk_x509_extension_new_null(void) {
+ return (STACK *)sk_X509_EXTENSION_new_null();
+}
+
+/* sk_X509_EXTENSION_free() is a macro. */
+void sk_x509_extension_free(STACK *stack) {
+ sk_X509_EXTENSION_free((STACK_OF(X509_EXTENSION) *)stack);
+}
+
+/* sk_X509_EXTENSION_push() is a macro. */
+int sk_x509_extension_push(STACK *stack, X509_EXTENSION *x509_ext) {
+ return sk_X509_EXTENSION_push((STACK_OF(X509_EXTENSION) *)stack, x509_ext);
+}
+
+/* sk_X509_EXTENSION_pop() is a macro. */
+X509_EXTENSION *sk_x509_extension_pop(STACK *stack) {
+ return sk_X509_EXTENSION_pop((STACK_OF(X509_EXTENSION) *)stack);
+}
+
+/* sk_X509_EXTENSION_num() is a macro. */
+int sk_x509_extension_num(STACK *stack) {
+ return sk_X509_EXTENSION_num((STACK_OF(X509_EXTENSION) *)stack);
+}
+
+/* sk_X509_EXTENSION_value() is a macro. */
+char *sk_x509_extension_value(STACK *stack, int i) {
+ return sk_X509_EXTENSION_value((STACK_OF(X509_EXTENSION) *)stack, i);
+}
+
int x509_store_load_locations(X509_STORE *store, const char *file) {
return X509_STORE_load_locations(store, file, NULL);
}
@@ -242,6 +287,10 @@
int x509_req_set_version(X509_REQ *x, long version) {
return X509_REQ_set_version(x, version);
+}
+
+int x509_req_add_extensions(X509_REQ *req, STACK *exts) {
+ return X509_REQ_add_extensions(req, (STACK_OF(X509_EXTENSION) *)exts);
}
int x509_req_sign(X509_REQ *x, EVP_PKEY *pkey, EVP_MD *md) {
More information about the Commits
mailing list