summaryrefslogtreecommitdiff
path: root/SWIG/_asn1.i
blob: b51b33fd0888f60e1d7b37962f9901a269806b67 (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
209
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* Copyright (c) 1999-2004 Ng Pheng Siong. All rights reserved.  */
/*
** Portions created by Open Source Applications Foundation (OSAF) are
** Copyright (C) 2004 OSAF. All Rights Reserved.
*/
/* $Id$ */

%{
#include <openssl/asn1.h>
%}

%apply Pointer NONNULL { BIO * };
%apply Pointer NONNULL { ASN1_OBJECT * };
%apply Pointer NONNULL { ASN1_STRING * };
%apply Pointer NONNULL { ASN1_INTEGER * };
%apply Pointer NONNULL { ASN1_TIME * };

%rename(asn1_object_new) ASN1_OBJECT_new;
extern ASN1_OBJECT *ASN1_OBJECT_new( void );
%rename(asn1_object_create) ASN1_OBJECT_create;
extern ASN1_OBJECT *ASN1_OBJECT_create( int, unsigned char *, int, const char *, const char *);
%rename(asn1_object_free) ASN1_OBJECT_free;
extern void ASN1_OBJECT_free( ASN1_OBJECT *);
%rename(i2d_asn1_object) i2d_ASN1_OBJECT;
extern int i2d_ASN1_OBJECT( ASN1_OBJECT *, unsigned char **);
%rename(d2i_asn1_object) d2i_ASN1_OBJECT;
extern ASN1_OBJECT *d2i_ASN1_OBJECT( ASN1_OBJECT **, const unsigned char **, long);

%rename(asn1_bit_string_new) ASN1_BIT_STRING_new;
extern ASN1_BIT_STRING *ASN1_BIT_STRING_new( void );

%rename(asn1_string_new) ASN1_STRING_new;
extern ASN1_STRING *ASN1_STRING_new( void );
%rename(asn1_string_free) ASN1_STRING_free;
extern void ASN1_STRING_free( ASN1_STRING *);

%typemap(in) (const void *, int) {
    if (PyBytes_Check($input)) {
        Py_ssize_t len;

        $1 = PyBytes_AsString($input);
        len = PyBytes_Size($input);

        if (len > INT_MAX) {
            PyErr_SetString(PyExc_ValueError, "object too large");
            return NULL;
        }
        $2 = len;
    }
    else {
        PyErr_SetString(PyExc_TypeError, "expected string");
        return NULL;
    }
}

%rename(asn1_string_set) ASN1_STRING_set;
extern int ASN1_STRING_set( ASN1_STRING *, const void *, int);

%typemap(in) (const void *, int);

%rename(asn1_string_print) ASN1_STRING_print;
%threadallow ASN1_STRING_print;
extern int ASN1_STRING_print(BIO *, ASN1_STRING *);
%threadallow ASN1_STRING_print_ex;
%rename(asn1_string_print_ex) ASN1_STRING_print_ex;
extern int ASN1_STRING_print_ex(BIO *, ASN1_STRING *, unsigned long);

%rename(asn1_time_new) ASN1_TIME_new;
extern ASN1_TIME *ASN1_TIME_new( void );
%rename(asn1_time_free) ASN1_TIME_free;
extern void ASN1_TIME_free(ASN1_TIME *);
%rename(asn1_time_check) ASN1_TIME_check;
extern int ASN1_TIME_check(ASN1_TIME *);
%rename(asn1_time_set) ASN1_TIME_set;
extern ASN1_TIME *ASN1_TIME_set(ASN1_TIME *, long);
%rename(asn1_time_set_string) ASN1_TIME_set_string;
extern int ASN1_TIME_set_string(ASN1_TIME *, const char *);
%rename(asn1_time_print) ASN1_TIME_print;
%threadallow ASN1_TIME_print;
extern int ASN1_TIME_print(BIO *, ASN1_TIME *);

%rename(asn1_integer_new) ASN1_INTEGER_new;
extern ASN1_INTEGER *ASN1_INTEGER_new( void );
%rename(asn1_integer_free) ASN1_INTEGER_free;
extern void ASN1_INTEGER_free( ASN1_INTEGER *);
%rename(asn1_integer_cmp) ASN1_INTEGER_cmp;
extern int ASN1_INTEGER_cmp(ASN1_INTEGER *, ASN1_INTEGER *);

%constant int ASN1_STRFLGS_ESC_2253 = 1;
%constant int ASN1_STRFLGS_ESC_CTRL = 2;
%constant int ASN1_STRFLGS_ESC_MSB = 4;
%constant int ASN1_STRFLGS_ESC_QUOTE = 8;
%constant int ASN1_STRFLGS_UTF8_CONVERT = 0x10;
%constant int ASN1_STRFLGS_IGNORE_TYPE = 0x20;
%constant int ASN1_STRFLGS_SHOW_TYPE = 0x40;
%constant int ASN1_STRFLGS_DUMP_ALL = 0x80;
%constant int ASN1_STRFLGS_DUMP_UNKNOWN = 0x100;
%constant int ASN1_STRFLGS_DUMP_DER = 0x200;

%constant int ASN1_STRFLGS_RFC2253 = (ASN1_STRFLGS_ESC_2253 | \
                ASN1_STRFLGS_ESC_CTRL | \
                ASN1_STRFLGS_ESC_MSB | \
                ASN1_STRFLGS_UTF8_CONVERT | \
                ASN1_STRFLGS_DUMP_UNKNOWN | \
                ASN1_STRFLGS_DUMP_DER);

%inline %{
/* ASN1_TIME_set_string () is a macro */
int asn1_time_type_check(ASN1_TIME *ASN1_TIME) {
    return 1;
}

PyObject *asn1_integer_get(ASN1_INTEGER *asn1) {
    BIGNUM *bn;
    PyObject *ret;
    char *hex;

    bn = ASN1_INTEGER_to_BN(asn1, NULL);

    if (!bn){
        m2_PyErr_Msg(PyExc_RuntimeError);
        return NULL;
    }

    hex = BN_bn2hex(bn);

    if (!hex){
        m2_PyErr_Msg(PyExc_RuntimeError);
        BN_free(bn);
        return NULL;
    }

    BN_free(bn);

    ret = PyLong_FromString(hex, NULL, 16);

    OPENSSL_free(hex);

    return ret;
}

int asn1_integer_set(ASN1_INTEGER *asn1, PyObject *value) {
    BIGNUM *bn = NULL;
    PyObject *fmt, *args, *hex;

/* Despite all hopes to the contrary, we cannot survive here with
 * PyLong_AsLong shims as provided in
 * /usr/include/python2.7/longobject.h.
 */
    long val = PyLong_AsLong(value);
    if (val >= 0) {
        return ASN1_INTEGER_set(asn1, val);
    } else {
        PyErr_Clear();
    }

    if (!PyLong_Check(value)){
        PyErr_SetString(PyExc_TypeError, "expected int or long");
        return 0;
    }

    fmt = PyUnicode_FromString("%x");

    if (!fmt)
        return 0;

    args = PyTuple_New(1);

    if (!args){
        Py_DECREF(fmt);
        PyErr_SetString(PyExc_RuntimeError, "PyTuple_New() failed");
        return 0;
    }

    Py_INCREF(value);
    PyTuple_SET_ITEM(args, 0, value);
    hex = PyUnicode_Format(fmt, args);

    if (!hex){
        PyErr_SetString(PyExc_RuntimeError, "PyString_Format() failed");
        Py_DECREF(fmt);
        Py_DECREF(args);
        return 0;
    }

    Py_DECREF(fmt);
    Py_DECREF(args);

    if (BN_hex2bn(&bn, PyUnicode_AsUTF8(hex)) <= 0){
        m2_PyErr_Msg(PyExc_RuntimeError);
        Py_DECREF(hex);
        return 0;
    }

    Py_DECREF(hex);

    if (!BN_to_ASN1_INTEGER(bn, asn1)){
        m2_PyErr_Msg(PyExc_RuntimeError);
        BN_free(bn);
        return 0;
    }

    BN_free(bn);

    return 1;
}

%}