1

libeay32.dllPythonで OpenSLL の小さなラッパーを書いています。ほとんどの関数は、次のようにインポートできます。

self.Function_Name = self._dll.Function_Name
self.Function_Name.restype = ctypes.c_int #for example
self.Function_Name.argtypes = [list of ctypes arguments]

残念ながら、この方法でマクロをインポートすることはできません:

X509_get_notAfterX509_get_notBeforeなど_

アイデアはありますctypesか?

4

2 に答える 2

2

マクロをインポートすることはできません。インポートしているのは、DLL の関数です。マクロは DLL からエクスポートされないため、インポートするものはありません。

幸いなことに、ほとんどのマクロは非常に単純であるため、Python で再実装するだけで済みます。

または、代わりに、各マクロの関数を定義するラッパー DLL を C で作成し、それをコンパイルしてリンクし、.wp でラッパー関数をインポートしますctypes

Cythonまたは、 の代わりに またはその他のテクノロジを使用することもできますctypes。それらが一般的に機能する方法は、C ライブラリをラップし、Python の型と関数をエクスポートする C コードを生成してコンパイルすることです。一般に、C マクロを Python 関数としてエクスポートするのは、C 関数をエクスポートするのと同じくらい簡単です。

または、最も単純なことですが、PyOpenSSLはすでに必要なものをすべてラップしていますか?

于 2013-02-28T01:10:40.907 に答える
0

いくつかの調査の後、私は自分の質問に答えることにしました。X509_get_notAfter のマクロは次のようになります。

#define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)

x - notAfter へのポインターを含む X509_VAL 構造を含む X509_CINF 構造を含む X509 構造です:)

したがって、私の計画は、Python コード内に X509、X509_CINF、および X509_VAL 構造全体を実装することです。

Cではこんな感じ

struct x509_st
{
X509_CINF *cert_info;
X509_ALGOR *sig_alg;
ASN1_BIT_STRING *signature;
int valid;
int references;
char *name;
CRYPTO_EX_DATA ex_data;
/* These contain copies of various extension values */
long ex_pathlen;
long ex_pcpathlen;
unsigned long ex_flags;
unsigned long ex_kusage;
unsigned long ex_xkusage;
unsigned long ex_nscert;
ASN1_OCTET_STRING *skid;
AUTHORITY_KEYID *akid;
X509_POLICY_CACHE *policy_cache;
STACK_OF(DIST_POINT) *crldp;
STACK_OF(GENERAL_NAME) *altname;
NAME_CONSTRAINTS *nc;
#ifndef OPENSSL_NO_RFC3779
STACK_OF(IPAddressFamily) *rfc3779_addr;
struct ASIdentifiers_st *rfc3779_asid;
#endif
#ifndef OPENSSL_NO_SHA
unsigned char sha1_hash[SHA_DIGEST_LENGTH];
#endif
X509_CERT_AUX *aux;
} /* X509 */;

X509_CINF は次のようになります。

typedef struct x509_cinf_st
{
ASN1_INTEGER *version;      /* [ 0 ] default of v1 */
ASN1_INTEGER *serialNumber;
X509_ALGOR *signature;
X509_NAME *issuer;
X509_VAL *validity;
X509_NAME *subject;
X509_PUBKEY *key;
ASN1_BIT_STRING *issuerUID;     /* [ 1 ] optional in v2 */
ASN1_BIT_STRING *subjectUID;        /* [ 2 ] optional in v2 */
STACK_OF(X509_EXTENSION) *extensions;   /* [ 3 ] optional in v3 */
ASN1_ENCODING enc;
} X509_CINF;

X509_VAL は次のとおりです。

typedef struct X509_val_st
{
ASN1_TIME *notBefore;
ASN1_TIME *notAfter;
} X509_VAL;

タスク全体を簡単にするために、アクセスしたくない構造体へのすべてのポインターを ctypes.c_void_p に置き換えることにしました。

したがって、私の python コードは次のようになります。

class X509_val_st(ctypes.Structure):

_fields_ = [('notBefore',       ctypes.c_void_p),
            ('notAfter',        ctypes.c_void_p)]


class X509_cinf_st(ctypes.Structure):

_fields_ = [('version',         ctypes.c_void_p),
            ('serialNumber',    ctypes.c_void_p),
            ('signature',       ctypes.c_void_p),
            ('issuer',          ctypes.c_void_p),
            ('validity',        X509_val_st),
            ('subject',         ctypes.c_void_p),
            ('key',             ctypes.c_void_p),
            ('issuerUID',       ctypes.c_void_p),
            ('subjectUID',      ctypes.c_void_p),
            ('extensions',      ctypes.c_void_p),
            ('enc',             ctypes.c_uint)]


class X509_st(ctypes.Structure):

_fields_ = [('cert_info',     X509_cinf_st),
            ('sig_alg',       ctypes.c_void_p),
            ('signature',     ctypes.c_void_p),
            ('valid',         ctypes.c_int),
            ('references',    ctypes.c_int),
            ('name',          ctypes.c_void_p),
            ('ex_data',       ctypes.c_int),
            ('ex_pathlen',    ctypes.c_long),
            ('ex_pcpathlen',  ctypes.c_long),
            ('ex_flags',      ctypes.c_ulong),
            ('ex_kusage',     ctypes.c_ulong),
            ('ex_xkusage',    ctypes.c_ulong),
            ('ex_nscert',     ctypes.c_ulong),
            ('skid',          ctypes.c_void_p),
            ('akid',          ctypes.c_void_p),
            ('policy_cache',  ctypes.c_void_p),
            ('crldp',         ctypes.c_void_p),
            ('altname',       ctypes.c_void_p),
            ('nc',            ctypes.c_void_p),
            ('rfc3779_addr',  ctypes.c_void_p),
            ('rfc3779_asid',  ctypes.c_void_p),
            ('sha1_hash',     ctypes.c_char),
            ('aux',           ctypes.c_void_p)]

そして最後のステップ: 関数 X509_new() から受け取ったポインタに構造体を割り当てます:

self.X509_new = self._lib.X509_new
self.X509_new.restype = ctypes.POINTER(X509_st)
self.X509_new.argtypes = []

したがって、OpenSSL マクロ X509_get_notBefore の Python 関数は次のようになります。

def X509_get_notBefore(self):
    return self.X509[0].cert_info.validity.notBefore
于 2013-03-01T17:49:38.683 に答える