1
/* Copyright (c) 2000 Ng Pheng Siong. All rights reserved. */
2
/* $Id: _pkcs7.i 695 2009-07-24 06:37:01Z heikki $ */
5
#include <openssl/bio.h>
6
#include <openssl/evp.h>
7
#include <openssl/objects.h>
8
#include <openssl/pkcs7.h>
11
%apply Pointer NONNULL { BIO * };
12
%apply Pointer NONNULL { EVP_CIPHER * };
13
%apply Pointer NONNULL { EVP_PKEY * };
14
%apply Pointer NONNULL { PKCS7 * };
15
%apply Pointer NONNULL { STACK * };
16
%apply Pointer NONNULL { X509 * };
18
%rename(pkcs7_new) PKCS7_new;
19
extern PKCS7 *PKCS7_new(void);
20
%rename(pkcs7_free) PKCS7_free;
21
extern void PKCS7_free(PKCS7 *);
22
%rename(pkcs7_add_certificate) PKCS7_add_certificate;
23
extern void PKCS7_add_certificate(PKCS7 *, X509 *);
25
/* S/MIME operation */
26
%constant int PKCS7_TEXT = 0x1;
27
%constant int PKCS7_NOCERTS = 0x2;
28
%constant int PKCS7_NOSIGS = 0x4;
29
%constant int PKCS7_NOCHAIN = 0x8;
30
%constant int PKCS7_NOINTERN = 0x10;
31
%constant int PKCS7_NOVERIFY = 0x20;
32
%constant int PKCS7_DETACHED = 0x40;
33
%constant int PKCS7_BINARY = 0x80;
34
%constant int PKCS7_NOATTR = 0x100;
36
%constant int PKCS7_SIGNED = NID_pkcs7_signed;
37
%constant int PKCS7_ENVELOPED = NID_pkcs7_enveloped;
38
%constant int PKCS7_SIGNED_ENVELOPED = NID_pkcs7_signedAndEnveloped;
39
%constant int PKCS7_DATA = NID_pkcs7_data;
42
static PyObject *_pkcs7_err, *_smime_err;
44
void pkcs7_init(PyObject *pkcs7_err) {
46
_pkcs7_err = pkcs7_err;
49
void smime_init(PyObject *smime_err) {
51
_smime_err = smime_err;
55
%threadallow pkcs7_encrypt;
57
PKCS7 *pkcs7_encrypt(STACK *stack, BIO *bio, EVP_CIPHER *cipher, int flags) {
58
return PKCS7_encrypt((STACK_OF(X509) *)stack, bio, cipher, flags);
61
PyObject *pkcs7_decrypt(PKCS7 *pkcs7, EVP_PKEY *pkey, X509 *cert, int flags) {
67
if (!(bio=BIO_new(BIO_s_mem()))) {
68
PyErr_SetString(PyExc_MemoryError, "pkcs7_decrypt");
71
if (!PKCS7_decrypt(pkcs7, pkey, cert, bio, flags)) {
72
PyErr_SetString(_pkcs7_err, ERR_reason_error_string(ERR_get_error()));
76
outlen = BIO_ctrl_pending(bio);
77
if (!(outbuf=(char *)PyMem_Malloc(outlen))) {
78
PyErr_SetString(PyExc_MemoryError, "pkcs7_decrypt");
82
BIO_read(bio, outbuf, outlen);
83
ret = PyString_FromStringAndSize(outbuf, outlen);
90
%threadallow pkcs7_sign0;
92
PKCS7 *pkcs7_sign0(X509 *x509, EVP_PKEY *pkey, BIO *bio, int flags) {
93
return PKCS7_sign(x509, pkey, NULL, bio, flags);
97
%threadallow pkcs7_sign1;
99
PKCS7 *pkcs7_sign1(X509 *x509, EVP_PKEY *pkey, STACK *stack, BIO *bio, int flags) {
100
return PKCS7_sign(x509, pkey, (STACK_OF(X509) *)stack, bio, flags);
104
%threadallow pkcs7_verify1;
106
PyObject *pkcs7_verify1(PKCS7 *pkcs7, STACK *stack, X509_STORE *store, BIO *data, int flags) {
112
if (!(bio=BIO_new(BIO_s_mem()))) {
113
PyErr_SetString(PyExc_MemoryError, "pkcs7_verify1");
116
if (!PKCS7_verify(pkcs7, (STACK_OF(X509) *)stack, store, data, bio, flags)) {
117
PyErr_SetString(_pkcs7_err, ERR_reason_error_string(ERR_get_error()));
121
outlen = BIO_ctrl_pending(bio);
122
if (!(outbuf=(char *)PyMem_Malloc(outlen))) {
123
PyErr_SetString(PyExc_MemoryError, "pkcs7_verify1");
127
BIO_read(bio, outbuf, outlen);
128
ret = PyString_FromStringAndSize(outbuf, outlen);
134
PyObject *pkcs7_verify0(PKCS7 *pkcs7, STACK *stack, X509_STORE *store, int flags) {
135
return pkcs7_verify1(pkcs7, stack, store, NULL, flags);
139
%threadallow smime_write_pkcs7_multi;
141
int smime_write_pkcs7_multi(BIO *bio, PKCS7 *pkcs7, BIO *data, int flags) {
142
return SMIME_write_PKCS7(bio, pkcs7, data, flags | PKCS7_DETACHED);
146
%threadallow smime_write_pkcs7;
148
int smime_write_pkcs7(BIO *bio, PKCS7 *pkcs7, int flags) {
149
return SMIME_write_PKCS7(bio, pkcs7, NULL, flags);
152
PyObject *smime_read_pkcs7(BIO *bio) {
155
PyObject *tuple, *_p7, *_BIO;
157
if (BIO_method_type(bio) == BIO_TYPE_MEM) {
158
/* OpenSSL FAQ explains that this is needed for mem BIO to return EOF,
159
* like file BIO does. Might need to do this for more mem BIOs but
160
* not sure if that is safe, so starting with just this single place.
162
BIO_set_mem_eof_return(bio, 0);
165
Py_BEGIN_ALLOW_THREADS
166
p7=SMIME_read_PKCS7(bio, &bcont);
169
PyErr_SetString(_smime_err, ERR_reason_error_string(ERR_get_error()));
172
if (!(tuple=PyTuple_New(2))) {
173
PyErr_SetString(PyExc_RuntimeError, "PyTuple_New() fails");
176
_p7 = SWIG_NewPointerObj((void *)p7, SWIGTYPE_p_PKCS7, 0);
177
PyTuple_SET_ITEM(tuple, 0, _p7);
180
PyTuple_SET_ITEM(tuple, 1, Py_None);
182
_BIO = SWIG_NewPointerObj((void *)bcont, SWIGTYPE_p_BIO, 0);
183
PyTuple_SET_ITEM(tuple, 1, _BIO);
189
%threadallow pkcs7_read_bio;
191
PKCS7 *pkcs7_read_bio(BIO *bio) {
192
return PEM_read_bio_PKCS7(bio, NULL, NULL, NULL);
196
%threadallow pkcs7_read_bio_der;
198
PKCS7 *pkcs7_read_bio_der(BIO *bio) {
199
return d2i_PKCS7_bio(bio, NULL);
203
%threadallow pkcs7_write_bio;
205
int pkcs7_write_bio(PKCS7 *pkcs7, BIO* bio) {
206
return PEM_write_bio_PKCS7(bio, pkcs7);
210
%threadallow pkcs7_write_bio_der;
212
int pkcs7_write_bio_der(PKCS7 *pkcs7, BIO *bio) {
213
return i2d_PKCS7_bio(bio, pkcs7);
216
int pkcs7_type_nid(PKCS7 *pkcs7) {
217
return OBJ_obj2nid(pkcs7->type);
220
const char *pkcs7_type_sn(PKCS7 *pkcs7) {
221
return OBJ_nid2sn(OBJ_obj2nid(pkcs7->type));
225
%threadallow smime_crlf_copy;
227
int smime_crlf_copy(BIO *in, BIO *out) {
228
return SMIME_crlf_copy(in, out, PKCS7_TEXT);
231
/* return STACK_OF(X509)* */
232
STACK *pkcs7_get0_signers(PKCS7 *p7, STACK *certs, int flags) {
233
return PKCS7_get0_signers(p7, certs, flags);