~ubuntu-branches/ubuntu/maverick/openssl/maverick

« back to all changes in this revision

Viewing changes to crypto/asn1/tasn_utl.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2005-12-13 21:37:42 UTC
  • mto: (11.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20051213213742-d0ydaylf80l16bj1
Tags: upstream-0.9.8a
ImportĀ upstreamĀ versionĀ 0.9.8a

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 * project 2000.
4
4
 */
5
5
/* ====================================================================
6
 
 * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
 
6
 * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
7
7
 *
8
8
 * Redistribution and use in source and binary forms, with or without
9
9
 * modification, are permitted provided that the following conditions
74
74
 */
75
75
 
76
76
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
77
 
{
 
77
        {
78
78
        int *sel = offset2ptr(*pval, it->utype);
79
79
        return *sel;
80
 
}
 
80
        }
81
81
 
82
82
/* Given an ASN1_ITEM CHOICE type set
83
83
 * the selector value, return old value.
84
84
 */
85
85
 
86
86
int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it)
87
 
{       
 
87
        {       
88
88
        int *sel, ret;
89
89
        sel = offset2ptr(*pval, it->utype);
90
90
        ret = *sel;
91
91
        *sel = value;
92
92
        return ret;
93
 
}
 
93
        }
94
94
 
95
95
/* Do reference counting. The value 'op' decides what to do. 
96
96
 * if it is +1 then the count is incremented. If op is 0 count is
99
99
 */
100
100
 
101
101
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
102
 
{
 
102
        {
103
103
        const ASN1_AUX *aux;
104
104
        int *lck, ret;
105
 
        if(it->itype != ASN1_ITYPE_SEQUENCE) return 0;
 
105
        if ((it->itype != ASN1_ITYPE_SEQUENCE)
 
106
           && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
 
107
                return 0;
106
108
        aux = it->funcs;
107
 
        if(!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) return 0;
 
109
        if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
 
110
                return 0;
108
111
        lck = offset2ptr(*pval, aux->ref_offset);
109
 
        if(op == 0) {
 
112
        if (op == 0)
 
113
                {
110
114
                *lck = 1;
111
115
                return 1;
112
 
        }
 
116
                }
113
117
        ret = CRYPTO_add(lck, op, aux->ref_lock);
114
118
#ifdef REF_PRINT
115
119
        fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck);
116
120
#endif
117
121
#ifdef REF_CHECK
118
 
        if(ret < 0) 
 
122
        if (ret < 0) 
119
123
                fprintf(stderr, "%s, bad reference count\n", it->sname);
120
124
#endif
121
125
        return ret;
122
 
}
 
126
        }
123
127
 
124
128
static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
125
 
{
 
129
        {
126
130
        const ASN1_AUX *aux;
127
 
        if(!pval || !*pval) return NULL;
 
131
        if (!pval || !*pval)
 
132
                return NULL;
128
133
        aux = it->funcs;
129
 
        if(!aux || !(aux->flags & ASN1_AFLG_ENCODING)) return NULL;
 
134
        if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
 
135
                return NULL;
130
136
        return offset2ptr(*pval, aux->enc_offset);
131
 
}
 
137
        }
132
138
 
133
139
void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
134
 
{
 
140
        {
135
141
        ASN1_ENCODING *enc;
136
142
        enc = asn1_get_enc_ptr(pval, it);
137
 
        if(enc) {
 
143
        if (enc)
 
144
                {
138
145
                enc->enc = NULL;
139
146
                enc->len = 0;
140
147
                enc->modified = 1;
 
148
                }
141
149
        }
142
 
}
143
150
 
144
151
void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
145
 
{
 
152
        {
146
153
        ASN1_ENCODING *enc;
147
154
        enc = asn1_get_enc_ptr(pval, it);
148
 
        if(enc) {
149
 
                if(enc->enc) OPENSSL_free(enc->enc);
 
155
        if (enc)
 
156
                {
 
157
                if (enc->enc)
 
158
                        OPENSSL_free(enc->enc);
150
159
                enc->enc = NULL;
151
160
                enc->len = 0;
152
161
                enc->modified = 1;
 
162
                }
153
163
        }
154
 
}
155
164
 
156
 
int asn1_enc_save(ASN1_VALUE **pval, unsigned char *in, int inlen, const ASN1_ITEM *it)
157
 
{
 
165
int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
 
166
                                                         const ASN1_ITEM *it)
 
167
        {
158
168
        ASN1_ENCODING *enc;
159
169
        enc = asn1_get_enc_ptr(pval, it);
160
 
        if(!enc) return 1;
 
170
        if (!enc)
 
171
                return 1;
161
172
 
162
 
        if(enc->enc) OPENSSL_free(enc->enc);
 
173
        if (enc->enc)
 
174
                OPENSSL_free(enc->enc);
163
175
        enc->enc = OPENSSL_malloc(inlen);
164
 
        if(!enc->enc) return 0;
 
176
        if (!enc->enc)
 
177
                return 0;
165
178
        memcpy(enc->enc, in, inlen);
166
179
        enc->len = inlen;
167
180
        enc->modified = 0;
168
181
 
169
182
        return 1;
170
 
}
 
183
        }
171
184
                
172
 
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it)
173
 
{
 
185
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
 
186
                                                        const ASN1_ITEM *it)
 
187
        {
174
188
        ASN1_ENCODING *enc;
175
189
        enc = asn1_get_enc_ptr(pval, it);
176
 
        if(!enc || enc->modified) return 0;
177
 
        if(out) {
 
190
        if (!enc || enc->modified)
 
191
                return 0;
 
192
        if (out)
 
193
                {
178
194
                memcpy(*out, enc->enc, enc->len);
179
195
                *out += enc->len;
 
196
                }
 
197
        if (len)
 
198
                *len = enc->len;
 
199
        return 1;
180
200
        }
181
 
        if(len) *len = enc->len;
182
 
        return 1;
183
 
}
184
201
 
185
202
/* Given an ASN1_TEMPLATE get a pointer to a field */
186
203
ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
187
 
{
 
204
        {
188
205
        ASN1_VALUE **pvaltmp;
189
 
        if(tt->flags & ASN1_TFLG_COMBINE) return pval;
 
206
        if (tt->flags & ASN1_TFLG_COMBINE)
 
207
                return pval;
190
208
        pvaltmp = offset2ptr(*pval, tt->offset);
191
209
        /* NOTE for BOOLEAN types the field is just a plain
192
210
         * int so we can't return int **, so settle for
193
211
         * (int *).
194
212
         */
195
213
        return pvaltmp;
196
 
}
 
214
        }
197
215
 
198
216
/* Handle ANY DEFINED BY template, find the selector, look up
199
217
 * the relevant ASN1_TEMPLATE in the table and return it.
200
218
 */
201
219
 
202
 
const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr)
203
 
{
 
220
const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
 
221
                                                                int nullerr)
 
222
        {
204
223
        const ASN1_ADB *adb;
205
224
        const ASN1_ADB_TABLE *atbl;
206
225
        long selector;
207
226
        ASN1_VALUE **sfld;
208
227
        int i;
209
 
        if(!(tt->flags & ASN1_TFLG_ADB_MASK)) return tt;
 
228
        if (!(tt->flags & ASN1_TFLG_ADB_MASK))
 
229
                return tt;
210
230
 
211
231
        /* Else ANY DEFINED BY ... get the table */
212
232
        adb = ASN1_ADB_ptr(tt->item);
215
235
        sfld = offset2ptr(*pval, adb->offset);
216
236
 
217
237
        /* Check if NULL */
218
 
        if(!sfld) {
219
 
                if(!adb->null_tt) goto err;
 
238
        if (!sfld)
 
239
                {
 
240
                if (!adb->null_tt)
 
241
                        goto err;
220
242
                return adb->null_tt;
221
 
        }
 
243
                }
222
244
 
223
245
        /* Convert type to a long:
224
246
         * NB: don't check for NID_undef here because it
225
247
         * might be a legitimate value in the table
226
248
         */
227
 
        if(tt->flags & ASN1_TFLG_ADB_OID) 
 
249
        if (tt->flags & ASN1_TFLG_ADB_OID) 
228
250
                selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
229
251
        else 
230
252
                selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
237
259
         * linear search.
238
260
         */
239
261
 
240
 
        for(atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
241
 
                if(atbl->value == selector) return &atbl->tt;
 
262
        for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
 
263
                if (atbl->value == selector)
 
264
                        return &atbl->tt;
242
265
 
243
266
        /* FIXME: need to search application table too */
244
267
 
245
268
        /* No match, return default type */
246
 
        if(!adb->default_tt) goto err;          
 
269
        if (!adb->default_tt)
 
270
                goto err;               
247
271
        return adb->default_tt;
248
272
        
249
273
        err:
250
274
        /* FIXME: should log the value or OID of unsupported type */
251
 
        if(nullerr) ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
 
275
        if (nullerr)
 
276
                ASN1err(ASN1_F_ASN1_DO_ADB,
 
277
                        ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
252
278
        return NULL;
253
 
}
 
279
        }