[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