summaryrefslogtreecommitdiff
path: root/SWIG/_engine.i
blob: 4ba93f3089e50e612919a386eafc645c7469d262 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*
 * -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: syntax=c sts=4 sw=4
 *
 * ENGINE functions from engine(3SSL).
 * 
 * Pavel Shramov
 * IMEC MSU
 */
%{
#include <openssl/engine.h>
#include <openssl/ui.h>
#include <stdio.h>
%}

%apply Pointer NONNULL { ENGINE * };
%apply Pointer NONNULL { const ENGINE * };
%apply Pointer NONNULL { const char * };

/*
 * Functions to load different engines
 */
%rename(engine_load_builtin_engines) ENGINE_load_builtin_engines;
extern void ENGINE_load_builtin_engines(void);

%rename(engine_load_dynamic) ENGINE_load_dynamic;
extern void ENGINE_load_dynamic(void);

%rename(engine_load_openssl) ENGINE_load_openssl;
extern void ENGINE_load_openssl(void);

%rename(engine_cleanup) ENGINE_cleanup;
extern void ENGINE_cleanup(void);

/*
 * Engine allocation functions
 */
%rename(engine_new) ENGINE_new;
extern ENGINE * ENGINE_new();

%rename(engine_by_id) ENGINE_by_id;
extern ENGINE * ENGINE_by_id(const char *);

%rename(engine_free) ENGINE_free;
extern int ENGINE_free(ENGINE *);

%rename(engine_init) ENGINE_init;
extern int ENGINE_init(ENGINE *);

%rename(engine_finish) ENGINE_finish;
extern int ENGINE_finish(ENGINE *);

/*
 * Engine id/name functions
 */
%rename(engine_get_id) ENGINE_get_id;
extern const char * ENGINE_get_id(const ENGINE *);

%rename(engine_get_name) ENGINE_get_name;
extern const char * ENGINE_get_name(const ENGINE *);

/*
 * Engine control functions
 * Control argument may be NULL (e.g for LOAD command)
 */
%clear const char *;
%rename(engine_ctrl_cmd_string) ENGINE_ctrl_cmd_string;
extern int ENGINE_ctrl_cmd_string(ENGINE *e, const char *NONNULL, 
                const char *arg, int cmd_optional);

%apply Pointer NONNULL { const char * };

/*
 * UI methods. 
 * XXX: UI_OpenSSL method is static and UI_destroy_method is not needed.
 */
%rename(ui_openssl) UI_OpenSSL;
extern UI_METHOD * UI_OpenSSL();

/*
%rename(ui_destroy_method) UI_destroy_method;
extern void UI_destroy_method(UI_METHOD *ui_method);
 */

%clear const char *;
%inline %{

/*
 * Code from engine-pkcs11 1.4.0 in engine-pkcs11.c
 *

99  static char *get_pin(UI_METHOD * ui_method, void *callback_data, char *sc_pin,
100                      int maxlen)
101 {
102         UI *ui;
103         struct {
104                 const void *password;
105                 const char *prompt_info;
106         } *mycb = callback_data;
107 
108         if (mycb->password) {
109                 sc_pin = set_pin(mycb->password);
110                 return sc_pin;
111         }
 
 *
 * So callback_data need to be always provided and have fixed type.
 * UI method still may be NULL.
 *
 * Following functions allocate and free callback data structure with 
 * optional password set.
 */

typedef struct {
    char * password;
    char * prompt;
} _cbd_t;

void * engine_pkcs11_data_new(const char *pin) {
    _cbd_t * cb = (_cbd_t *) PyMem_Malloc(sizeof(_cbd_t));
    if (!cb) {
        PyErr_SetString(PyExc_MemoryError, "engine_pkcs11_data_new");
        return NULL;
    }
    cb->password = NULL;
    if (pin) {
        size_t size = strlen(pin);
        cb->password = (char *) PyMem_Malloc(size + 1);
        if (!cb->password) {
            PyErr_SetString(PyExc_MemoryError, "engine_pkcs11_data_new");
            PyMem_Free(cb);
            return NULL;
        }
        memcpy(cb->password, pin, size + 1);
    }
    cb->prompt = NULL;
    return cb;
}

void engine_pkcs11_data_free(void * vcb) {
    _cbd_t * cb = (_cbd_t *) vcb;
    if (!cb)
        return;
    if (cb->password)
        PyMem_Free(cb->password);
    PyMem_Free(cb);
}

%}
%apply Pointer NONNULL { const char * };

/*
 * Engine key/cert load functions.
 * See above notice about callback_data.
 */
%rename(engine_load_private_key) ENGINE_load_private_key;
extern EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
                    UI_METHOD *ui_method, void *callback_data);
%rename(engine_load_public_key) ENGINE_load_public_key;
extern EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
                    UI_METHOD *ui_method, void *callback_data);

/*
 * This function may be not implemented in engine.
 * pkcs11 engine has this control.
 */
%warnfilter(454) _engine_err;
%inline %{
static PyObject *_engine_err;

void engine_init_error(PyObject *engine_err) {
    Py_INCREF(engine_err);
    _engine_err = engine_err;
}

X509 * engine_load_certificate(ENGINE *e, const char * slot) {
    struct {
        const char * slot;
        X509 * cert;
    } cbd;
    cbd.slot = slot;
    cbd.cert = NULL;
    if (!ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, &cbd, NULL, 0)) {
        PyErr_SetString(_engine_err, "cannot load certificate");
        return NULL;
    }
    return cbd.cert;
}
%}

/* These flags are used to control combinations of algorithm (methods)
 * by bitwise "OR"ing. */
%constant int ENGINE_METHOD_RSA = 0x0001;
%constant int ENGINE_METHOD_DSA = 0x0002;
%constant int ENGINE_METHOD_DH = 0x0004;
%constant int ENGINE_METHOD_RAND = 0x0008;
%constant int ENGINE_METHOD_ECDH = 0x0010;
%constant int ENGINE_METHOD_ECDSA = 0x0020;
%constant int ENGINE_METHOD_CIPHERS = 0x0040;
%constant int ENGINE_METHOD_DIGESTS = 0x0080;
%constant int ENGINE_METHOD_STORE = 0x0100;
/* Obvious all-or-nothing cases. */
%constant int ENGINE_METHOD_ALL = 0xFFFF;
%constant int ENGINE_METHOD_NONE = 0x0000;

%rename(engine_set_default) ENGINE_set_default;
extern int ENGINE_set_default(ENGINE *e, unsigned int flags);