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