LTKCPP-- LLRP Toolkit C Plus Plus Library
asn1t.h
00001 /* asn1t.h */
00002 /*
00003  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
00004  * 2000.
00005  */
00006 /* ====================================================================
00007  * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  *
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  *
00016  * 2. Redistributions in binary form must reproduce the above copyright
00017  *    notice, this list of conditions and the following disclaimer in
00018  *    the documentation and/or other materials provided with the
00019  *    distribution.
00020  *
00021  * 3. All advertising materials mentioning features or use of this
00022  *    software must display the following acknowledgment:
00023  *    "This product includes software developed by the OpenSSL Project
00024  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
00025  *
00026  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
00027  *    endorse or promote products derived from this software without
00028  *    prior written permission. For written permission, please contact
00029  *    licensing@OpenSSL.org.
00030  *
00031  * 5. Products derived from this software may not be called "OpenSSL"
00032  *    nor may "OpenSSL" appear in their names without prior written
00033  *    permission of the OpenSSL Project.
00034  *
00035  * 6. Redistributions of any form whatsoever must retain the following
00036  *    acknowledgment:
00037  *    "This product includes software developed by the OpenSSL Project
00038  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
00039  *
00040  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
00041  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00042  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00043  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
00044  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00045  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00046  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00047  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00048  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00049  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00050  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00051  * OF THE POSSIBILITY OF SUCH DAMAGE.
00052  * ====================================================================
00053  *
00054  * This product includes cryptographic software written by Eric Young
00055  * (eay@cryptsoft.com).  This product includes software written by Tim
00056  * Hudson (tjh@cryptsoft.com).
00057  *
00058  */
00059 #ifndef HEADER_ASN1T_H
00060 # define HEADER_ASN1T_H
00061 
00062 # include <stddef.h>
00063 # include <openssl/e_os2.h>
00064 # include <openssl/asn1.h>
00065 
00066 # ifdef OPENSSL_BUILD_SHLIBCRYPTO
00067 #  undef OPENSSL_EXTERN
00068 #  define OPENSSL_EXTERN OPENSSL_EXPORT
00069 # endif
00070 
00071 /* ASN1 template defines, structures and functions */
00072 
00073 #ifdef  __cplusplus
00074 extern "C" {
00075 #endif
00076 
00077 # ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
00078 
00079 /* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
00080 #  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
00081 
00082 /* Macros for start and end of ASN1_ITEM definition */
00083 
00084 #  define ASN1_ITEM_start(itname) \
00085         OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
00086 
00087 #  define ASN1_ITEM_end(itname) \
00088                 };
00089 
00090 # else
00091 
00092 /* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
00093 #  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
00094 
00095 /* Macros for start and end of ASN1_ITEM definition */
00096 
00097 #  define ASN1_ITEM_start(itname) \
00098         const ASN1_ITEM * itname##_it(void) \
00099         { \
00100                 static const ASN1_ITEM local_it = {
00101 
00102 #  define ASN1_ITEM_end(itname) \
00103                 }; \
00104         return &local_it; \
00105         }
00106 
00107 # endif
00108 
00109 /* Macros to aid ASN1 template writing */
00110 
00111 # define ASN1_ITEM_TEMPLATE(tname) \
00112         static const ASN1_TEMPLATE tname##_item_tt
00113 
00114 # define ASN1_ITEM_TEMPLATE_END(tname) \
00115         ;\
00116         ASN1_ITEM_start(tname) \
00117                 ASN1_ITYPE_PRIMITIVE,\
00118                 -1,\
00119                 &tname##_item_tt,\
00120                 0,\
00121                 NULL,\
00122                 0,\
00123                 #tname \
00124         ASN1_ITEM_end(tname)
00125 
00126 /* This is a ASN1 type which just embeds a template */
00127 
00128 /*-
00129  * This pair helps declare a SEQUENCE. We can do:
00130  *
00131  *      ASN1_SEQUENCE(stname) = {
00132  *              ... SEQUENCE components ...
00133  *      } ASN1_SEQUENCE_END(stname)
00134  *
00135  *      This will produce an ASN1_ITEM called stname_it
00136  *      for a structure called stname.
00137  *
00138  *      If you want the same structure but a different
00139  *      name then use:
00140  *
00141  *      ASN1_SEQUENCE(itname) = {
00142  *              ... SEQUENCE components ...
00143  *      } ASN1_SEQUENCE_END_name(stname, itname)
00144  *
00145  *      This will create an item called itname_it using
00146  *      a structure called stname.
00147  */
00148 
00149 # define ASN1_SEQUENCE(tname) \
00150         static const ASN1_TEMPLATE tname##_seq_tt[]
00151 
00152 # define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
00153 
00154 # define ASN1_SEQUENCE_END_name(stname, tname) \
00155         ;\
00156         ASN1_ITEM_start(tname) \
00157                 ASN1_ITYPE_SEQUENCE,\
00158                 V_ASN1_SEQUENCE,\
00159                 tname##_seq_tt,\
00160                 sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
00161                 NULL,\
00162                 sizeof(stname),\
00163                 #stname \
00164         ASN1_ITEM_end(tname)
00165 
00166 # define ASN1_NDEF_SEQUENCE(tname) \
00167         ASN1_SEQUENCE(tname)
00168 
00169 # define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
00170         ASN1_SEQUENCE_cb(tname, cb)
00171 
00172 # define ASN1_SEQUENCE_cb(tname, cb) \
00173         static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
00174         ASN1_SEQUENCE(tname)
00175 
00176 # define ASN1_BROKEN_SEQUENCE(tname) \
00177         static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
00178         ASN1_SEQUENCE(tname)
00179 
00180 # define ASN1_SEQUENCE_ref(tname, cb, lck) \
00181         static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
00182         ASN1_SEQUENCE(tname)
00183 
00184 # define ASN1_SEQUENCE_enc(tname, enc, cb) \
00185         static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
00186         ASN1_SEQUENCE(tname)
00187 
00188 # define ASN1_NDEF_SEQUENCE_END(tname) \
00189         ;\
00190         ASN1_ITEM_start(tname) \
00191                 ASN1_ITYPE_NDEF_SEQUENCE,\
00192                 V_ASN1_SEQUENCE,\
00193                 tname##_seq_tt,\
00194                 sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
00195                 NULL,\
00196                 sizeof(tname),\
00197                 #tname \
00198         ASN1_ITEM_end(tname)
00199 
00200 # define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
00201 
00202 # define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
00203 
00204 # define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
00205 
00206 # define ASN1_SEQUENCE_END_ref(stname, tname) \
00207         ;\
00208         ASN1_ITEM_start(tname) \
00209                 ASN1_ITYPE_SEQUENCE,\
00210                 V_ASN1_SEQUENCE,\
00211                 tname##_seq_tt,\
00212                 sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
00213                 &tname##_aux,\
00214                 sizeof(stname),\
00215                 #stname \
00216         ASN1_ITEM_end(tname)
00217 
00218 # define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
00219         ;\
00220         ASN1_ITEM_start(tname) \
00221                 ASN1_ITYPE_NDEF_SEQUENCE,\
00222                 V_ASN1_SEQUENCE,\
00223                 tname##_seq_tt,\
00224                 sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
00225                 &tname##_aux,\
00226                 sizeof(stname),\
00227                 #stname \
00228         ASN1_ITEM_end(tname)
00229 
00230 /*-
00231  * This pair helps declare a CHOICE type. We can do:
00232  *
00233  *      ASN1_CHOICE(chname) = {
00234  *              ... CHOICE options ...
00235  *      ASN1_CHOICE_END(chname)
00236  *
00237  *      This will produce an ASN1_ITEM called chname_it
00238  *      for a structure called chname. The structure
00239  *      definition must look like this:
00240  *      typedef struct {
00241  *              int type;
00242  *              union {
00243  *                      ASN1_SOMETHING *opt1;
00244  *                      ASN1_SOMEOTHER *opt2;
00245  *              } value;
00246  *      } chname;
00247  *
00248  *      the name of the selector must be 'type'.
00249  *      to use an alternative selector name use the
00250  *      ASN1_CHOICE_END_selector() version.
00251  */
00252 
00253 # define ASN1_CHOICE(tname) \
00254         static const ASN1_TEMPLATE tname##_ch_tt[]
00255 
00256 # define ASN1_CHOICE_cb(tname, cb) \
00257         static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
00258         ASN1_CHOICE(tname)
00259 
00260 # define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
00261 
00262 # define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
00263 
00264 # define ASN1_CHOICE_END_selector(stname, tname, selname) \
00265         ;\
00266         ASN1_ITEM_start(tname) \
00267                 ASN1_ITYPE_CHOICE,\
00268                 offsetof(stname,selname) ,\
00269                 tname##_ch_tt,\
00270                 sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
00271                 NULL,\
00272                 sizeof(stname),\
00273                 #stname \
00274         ASN1_ITEM_end(tname)
00275 
00276 # define ASN1_CHOICE_END_cb(stname, tname, selname) \
00277         ;\
00278         ASN1_ITEM_start(tname) \
00279                 ASN1_ITYPE_CHOICE,\
00280                 offsetof(stname,selname) ,\
00281                 tname##_ch_tt,\
00282                 sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
00283                 &tname##_aux,\
00284                 sizeof(stname),\
00285                 #stname \
00286         ASN1_ITEM_end(tname)
00287 
00288 /* This helps with the template wrapper form of ASN1_ITEM */
00289 
00290 # define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
00291         (flags), (tag), 0,\
00292         #name, ASN1_ITEM_ref(type) }
00293 
00294 /* These help with SEQUENCE or CHOICE components */
00295 
00296 /* used to declare other types */
00297 
00298 # define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
00299         (flags), (tag), offsetof(stname, field),\
00300         #field, ASN1_ITEM_ref(type) }
00301 
00302 /* used when the structure is combined with the parent */
00303 
00304 # define ASN1_EX_COMBINE(flags, tag, type) { \
00305         (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
00306 
00307 /* implicit and explicit helper macros */
00308 
00309 # define ASN1_IMP_EX(stname, field, type, tag, ex) \
00310                 ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
00311 
00312 # define ASN1_EXP_EX(stname, field, type, tag, ex) \
00313                 ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
00314 
00315 /* Any defined by macros: the field used is in the table itself */
00316 
00317 # ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
00318 #  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
00319 #  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
00320 # else
00321 #  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
00322 #  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
00323 # endif
00324 /* Plain simple type */
00325 # define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
00326 
00327 /* OPTIONAL simple type */
00328 # define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
00329 
00330 /* IMPLICIT tagged simple type */
00331 # define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
00332 
00333 /* IMPLICIT tagged OPTIONAL simple type */
00334 # define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
00335 
00336 /* Same as above but EXPLICIT */
00337 
00338 # define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
00339 # define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
00340 
00341 /* SEQUENCE OF type */
00342 # define ASN1_SEQUENCE_OF(stname, field, type) \
00343                 ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
00344 
00345 /* OPTIONAL SEQUENCE OF */
00346 # define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
00347                 ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
00348 
00349 /* Same as above but for SET OF */
00350 
00351 # define ASN1_SET_OF(stname, field, type) \
00352                 ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
00353 
00354 # define ASN1_SET_OF_OPT(stname, field, type) \
00355                 ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
00356 
00357 /* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
00358 
00359 # define ASN1_IMP_SET_OF(stname, field, type, tag) \
00360                         ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
00361 
00362 # define ASN1_EXP_SET_OF(stname, field, type, tag) \
00363                         ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
00364 
00365 # define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
00366                         ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
00367 
00368 # define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
00369                         ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
00370 
00371 # define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
00372                         ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
00373 
00374 # define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
00375                         ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
00376 
00377 # define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
00378                         ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
00379 
00380 # define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
00381                         ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
00382 
00383 /* EXPLICIT using indefinite length constructed form */
00384 # define ASN1_NDEF_EXP(stname, field, type, tag) \
00385                         ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
00386 
00387 /* EXPLICIT OPTIONAL using indefinite length constructed form */
00388 # define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
00389                         ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
00390 
00391 /* Macros for the ASN1_ADB structure */
00392 
00393 # define ASN1_ADB(name) \
00394         static const ASN1_ADB_TABLE name##_adbtbl[]
00395 
00396 # ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
00397 
00398 #  define ASN1_ADB_END(name, flags, field, app_table, def, none) \
00399         ;\
00400         static const ASN1_ADB name##_adb = {\
00401                 flags,\
00402                 offsetof(name, field),\
00403                 app_table,\
00404                 name##_adbtbl,\
00405                 sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
00406                 def,\
00407                 none\
00408         }
00409 
00410 # else
00411 
00412 #  define ASN1_ADB_END(name, flags, field, app_table, def, none) \
00413         ;\
00414         static const ASN1_ITEM *name##_adb(void) \
00415         { \
00416         static const ASN1_ADB internal_adb = \
00417                 {\
00418                 flags,\
00419                 offsetof(name, field),\
00420                 app_table,\
00421                 name##_adbtbl,\
00422                 sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
00423                 def,\
00424                 none\
00425                 }; \
00426                 return (const ASN1_ITEM *) &internal_adb; \
00427         } \
00428         void dummy_function(void)
00429 
00430 # endif
00431 
00432 # define ADB_ENTRY(val, template) {val, template}
00433 
00434 # define ASN1_ADB_TEMPLATE(name) \
00435         static const ASN1_TEMPLATE name##_tt
00436 
00437 /*
00438  * This is the ASN1 template structure that defines a wrapper round the
00439  * actual type. It determines the actual position of the field in the value
00440  * structure, various flags such as OPTIONAL and the field name.
00441  */
00442 
00443 struct ASN1_TEMPLATE_st {
00444     unsigned long flags;        /* Various flags */
00445     long tag;                   /* tag, not used if no tagging */
00446     unsigned long offset;       /* Offset of this field in structure */
00447 # ifndef NO_ASN1_FIELD_NAMES
00448     const char *field_name;     /* Field name */
00449 # endif
00450     ASN1_ITEM_EXP *item;        /* Relevant ASN1_ITEM or ASN1_ADB */
00451 };
00452 
00453 /* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
00454 
00455 # define ASN1_TEMPLATE_item(t) (t->item_ptr)
00456 # define ASN1_TEMPLATE_adb(t) (t->item_ptr)
00457 
00458 typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
00459 typedef struct ASN1_ADB_st ASN1_ADB;
00460 
00461 struct ASN1_ADB_st {
00462     unsigned long flags;        /* Various flags */
00463     unsigned long offset;       /* Offset of selector field */
00464     STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
00465     const ASN1_ADB_TABLE *tbl;  /* Table of possible types */
00466     long tblcount;              /* Number of entries in tbl */
00467     const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
00468     const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
00469 };
00470 
00471 struct ASN1_ADB_TABLE_st {
00472     long value;                 /* NID for an object or value for an int */
00473     const ASN1_TEMPLATE tt;     /* item for this value */
00474 };
00475 
00476 /* template flags */
00477 
00478 /* Field is optional */
00479 # define ASN1_TFLG_OPTIONAL      (0x1)
00480 
00481 /* Field is a SET OF */
00482 # define ASN1_TFLG_SET_OF        (0x1 << 1)
00483 
00484 /* Field is a SEQUENCE OF */
00485 # define ASN1_TFLG_SEQUENCE_OF   (0x2 << 1)
00486 
00487 /*
00488  * Special case: this refers to a SET OF that will be sorted into DER order
00489  * when encoded *and* the corresponding STACK will be modified to match the
00490  * new order.
00491  */
00492 # define ASN1_TFLG_SET_ORDER     (0x3 << 1)
00493 
00494 /* Mask for SET OF or SEQUENCE OF */
00495 # define ASN1_TFLG_SK_MASK       (0x3 << 1)
00496 
00497 /*
00498  * These flags mean the tag should be taken from the tag field. If EXPLICIT
00499  * then the underlying type is used for the inner tag.
00500  */
00501 
00502 /* IMPLICIT tagging */
00503 # define ASN1_TFLG_IMPTAG        (0x1 << 3)
00504 
00505 /* EXPLICIT tagging, inner tag from underlying type */
00506 # define ASN1_TFLG_EXPTAG        (0x2 << 3)
00507 
00508 # define ASN1_TFLG_TAG_MASK      (0x3 << 3)
00509 
00510 /* context specific IMPLICIT */
00511 # define ASN1_TFLG_IMPLICIT      ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
00512 
00513 /* context specific EXPLICIT */
00514 # define ASN1_TFLG_EXPLICIT      ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
00515 
00516 /*
00517  * If tagging is in force these determine the type of tag to use. Otherwise
00518  * the tag is determined by the underlying type. These values reflect the
00519  * actual octet format.
00520  */
00521 
00522 /* Universal tag */
00523 # define ASN1_TFLG_UNIVERSAL     (0x0<<6)
00524 /* Application tag */
00525 # define ASN1_TFLG_APPLICATION   (0x1<<6)
00526 /* Context specific tag */
00527 # define ASN1_TFLG_CONTEXT       (0x2<<6)
00528 /* Private tag */
00529 # define ASN1_TFLG_PRIVATE       (0x3<<6)
00530 
00531 # define ASN1_TFLG_TAG_CLASS     (0x3<<6)
00532 
00533 /*
00534  * These are for ANY DEFINED BY type. In this case the 'item' field points to
00535  * an ASN1_ADB structure which contains a table of values to decode the
00536  * relevant type
00537  */
00538 
00539 # define ASN1_TFLG_ADB_MASK      (0x3<<8)
00540 
00541 # define ASN1_TFLG_ADB_OID       (0x1<<8)
00542 
00543 # define ASN1_TFLG_ADB_INT       (0x1<<9)
00544 
00545 /*
00546  * This flag means a parent structure is passed instead of the field: this is
00547  * useful is a SEQUENCE is being combined with a CHOICE for example. Since
00548  * this means the structure and item name will differ we need to use the
00549  * ASN1_CHOICE_END_name() macro for example.
00550  */
00551 
00552 # define ASN1_TFLG_COMBINE       (0x1<<10)
00553 
00554 /*
00555  * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes
00556  * indefinite length constructed encoding to be used if required.
00557  */
00558 
00559 # define ASN1_TFLG_NDEF          (0x1<<11)
00560 
00561 /* This is the actual ASN1 item itself */
00562 
00563 struct ASN1_ITEM_st {
00564     char itype;                 /* The item type, primitive, SEQUENCE, CHOICE
00565                                  * or extern */
00566     long utype;                 /* underlying type */
00567     const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains
00568                                      * the contents */
00569     long tcount;                /* Number of templates if SEQUENCE or CHOICE */
00570     const void *funcs;          /* functions that handle this type */
00571     long size;                  /* Structure size (usually) */
00572 # ifndef NO_ASN1_FIELD_NAMES
00573     const char *sname;          /* Structure name */
00574 # endif
00575 };
00576 
00577 /*-
00578  * These are values for the itype field and
00579  * determine how the type is interpreted.
00580  *
00581  * For PRIMITIVE types the underlying type
00582  * determines the behaviour if items is NULL.
00583  *
00584  * Otherwise templates must contain a single
00585  * template and the type is treated in the
00586  * same way as the type specified in the template.
00587  *
00588  * For SEQUENCE types the templates field points
00589  * to the members, the size field is the
00590  * structure size.
00591  *
00592  * For CHOICE types the templates field points
00593  * to each possible member (typically a union)
00594  * and the 'size' field is the offset of the
00595  * selector.
00596  *
00597  * The 'funcs' field is used for application
00598  * specific functions.
00599  *
00600  * For COMPAT types the funcs field gives a
00601  * set of functions that handle this type, this
00602  * supports the old d2i, i2d convention.
00603  *
00604  * The EXTERN type uses a new style d2i/i2d.
00605  * The new style should be used where possible
00606  * because it avoids things like the d2i IMPLICIT
00607  * hack.
00608  *
00609  * MSTRING is a multiple string type, it is used
00610  * for a CHOICE of character strings where the
00611  * actual strings all occupy an ASN1_STRING
00612  * structure. In this case the 'utype' field
00613  * has a special meaning, it is used as a mask
00614  * of acceptable types using the B_ASN1 constants.
00615  *
00616  * NDEF_SEQUENCE is the same as SEQUENCE except
00617  * that it will use indefinite length constructed
00618  * encoding if requested.
00619  *
00620  */
00621 
00622 # define ASN1_ITYPE_PRIMITIVE            0x0
00623 
00624 # define ASN1_ITYPE_SEQUENCE             0x1
00625 
00626 # define ASN1_ITYPE_CHOICE               0x2
00627 
00628 # define ASN1_ITYPE_COMPAT               0x3
00629 
00630 # define ASN1_ITYPE_EXTERN               0x4
00631 
00632 # define ASN1_ITYPE_MSTRING              0x5
00633 
00634 # define ASN1_ITYPE_NDEF_SEQUENCE        0x6
00635 
00636 /*
00637  * Cache for ASN1 tag and length, so we don't keep re-reading it for things
00638  * like CHOICE
00639  */
00640 
00641 struct ASN1_TLC_st {
00642     char valid;                 /* Values below are valid */
00643     int ret;                    /* return value */
00644     long plen;                  /* length */
00645     int ptag;                   /* class value */
00646     int pclass;                 /* class value */
00647     int hdrlen;                 /* header length */
00648 };
00649 
00650 /* Typedefs for ASN1 function pointers */
00651 
00652 typedef ASN1_VALUE *ASN1_new_func(void);
00653 typedef void ASN1_free_func(ASN1_VALUE *a);
00654 typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in,
00655                                   long length);
00656 typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in);
00657 
00658 typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
00659                         const ASN1_ITEM *it, int tag, int aclass, char opt,
00660                         ASN1_TLC *ctx);
00661 
00662 typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
00663                         const ASN1_ITEM *it, int tag, int aclass);
00664 typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
00665 typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
00666 
00667 typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
00668                                int indent, const char *fname,
00669                                const ASN1_PCTX *pctx);
00670 
00671 typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont,
00672                                int *putype, const ASN1_ITEM *it);
00673 typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont,
00674                                int len, int utype, char *free_cont,
00675                                const ASN1_ITEM *it);
00676 typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval,
00677                                  const ASN1_ITEM *it, int indent,
00678                                  const ASN1_PCTX *pctx);
00679 
00680 typedef struct ASN1_COMPAT_FUNCS_st {
00681     ASN1_new_func *asn1_new;
00682     ASN1_free_func *asn1_free;
00683     ASN1_d2i_func *asn1_d2i;
00684     ASN1_i2d_func *asn1_i2d;
00685 } ASN1_COMPAT_FUNCS;
00686 
00687 typedef struct ASN1_EXTERN_FUNCS_st {
00688     void *app_data;
00689     ASN1_ex_new_func *asn1_ex_new;
00690     ASN1_ex_free_func *asn1_ex_free;
00691     ASN1_ex_free_func *asn1_ex_clear;
00692     ASN1_ex_d2i *asn1_ex_d2i;
00693     ASN1_ex_i2d *asn1_ex_i2d;
00694     ASN1_ex_print_func *asn1_ex_print;
00695 } ASN1_EXTERN_FUNCS;
00696 
00697 typedef struct ASN1_PRIMITIVE_FUNCS_st {
00698     void *app_data;
00699     unsigned long flags;
00700     ASN1_ex_new_func *prim_new;
00701     ASN1_ex_free_func *prim_free;
00702     ASN1_ex_free_func *prim_clear;
00703     ASN1_primitive_c2i *prim_c2i;
00704     ASN1_primitive_i2c *prim_i2c;
00705     ASN1_primitive_print *prim_print;
00706 } ASN1_PRIMITIVE_FUNCS;
00707 
00708 /*
00709  * This is the ASN1_AUX structure: it handles various miscellaneous
00710  * requirements. For example the use of reference counts and an informational
00711  * callback. The "informational callback" is called at various points during
00712  * the ASN1 encoding and decoding. It can be used to provide minor
00713  * customisation of the structures used. This is most useful where the
00714  * supplied routines *almost* do the right thing but need some extra help at
00715  * a few points. If the callback returns zero then it is assumed a fatal
00716  * error has occurred and the main operation should be abandoned. If major
00717  * changes in the default behaviour are required then an external type is
00718  * more appropriate.
00719  */
00720 
00721 typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
00722                         void *exarg);
00723 
00724 typedef struct ASN1_AUX_st {
00725     void *app_data;
00726     int flags;
00727     int ref_offset;             /* Offset of reference value */
00728     int ref_lock;               /* Lock type to use */
00729     ASN1_aux_cb *asn1_cb;
00730     int enc_offset;             /* Offset of ASN1_ENCODING structure */
00731 } ASN1_AUX;
00732 
00733 /* For print related callbacks exarg points to this structure */
00734 typedef struct ASN1_PRINT_ARG_st {
00735     BIO *out;
00736     int indent;
00737     const ASN1_PCTX *pctx;
00738 } ASN1_PRINT_ARG;
00739 
00740 /* For streaming related callbacks exarg points to this structure */
00741 typedef struct ASN1_STREAM_ARG_st {
00742     /* BIO to stream through */
00743     BIO *out;
00744     /* BIO with filters appended */
00745     BIO *ndef_bio;
00746     /* Streaming I/O boundary */
00747     unsigned char **boundary;
00748 } ASN1_STREAM_ARG;
00749 
00750 /* Flags in ASN1_AUX */
00751 
00752 /* Use a reference count */
00753 # define ASN1_AFLG_REFCOUNT      1
00754 /* Save the encoding of structure (useful for signatures) */
00755 # define ASN1_AFLG_ENCODING      2
00756 /* The Sequence length is invalid */
00757 # define ASN1_AFLG_BROKEN        4
00758 
00759 /* operation values for asn1_cb */
00760 
00761 # define ASN1_OP_NEW_PRE         0
00762 # define ASN1_OP_NEW_POST        1
00763 # define ASN1_OP_FREE_PRE        2
00764 # define ASN1_OP_FREE_POST       3
00765 # define ASN1_OP_D2I_PRE         4
00766 # define ASN1_OP_D2I_POST        5
00767 # define ASN1_OP_I2D_PRE         6
00768 # define ASN1_OP_I2D_POST        7
00769 # define ASN1_OP_PRINT_PRE       8
00770 # define ASN1_OP_PRINT_POST      9
00771 # define ASN1_OP_STREAM_PRE      10
00772 # define ASN1_OP_STREAM_POST     11
00773 # define ASN1_OP_DETACHED_PRE    12
00774 # define ASN1_OP_DETACHED_POST   13
00775 
00776 /* Macro to implement a primitive type */
00777 # define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
00778 # define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
00779                                 ASN1_ITEM_start(itname) \
00780                                         ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
00781                                 ASN1_ITEM_end(itname)
00782 
00783 /* Macro to implement a multi string type */
00784 # define IMPLEMENT_ASN1_MSTRING(itname, mask) \
00785                                 ASN1_ITEM_start(itname) \
00786                                         ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
00787                                 ASN1_ITEM_end(itname)
00788 
00789 /* Macro to implement an ASN1_ITEM in terms of old style funcs */
00790 
00791 # define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
00792 
00793 # define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
00794         static const ASN1_COMPAT_FUNCS sname##_ff = { \
00795                 (ASN1_new_func *)sname##_new, \
00796                 (ASN1_free_func *)sname##_free, \
00797                 (ASN1_d2i_func *)d2i_##sname, \
00798                 (ASN1_i2d_func *)i2d_##sname, \
00799         }; \
00800         ASN1_ITEM_start(sname) \
00801                 ASN1_ITYPE_COMPAT, \
00802                 tag, \
00803                 NULL, \
00804                 0, \
00805                 &sname##_ff, \
00806                 0, \
00807                 #sname \
00808         ASN1_ITEM_end(sname)
00809 
00810 # define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
00811         ASN1_ITEM_start(sname) \
00812                 ASN1_ITYPE_EXTERN, \
00813                 tag, \
00814                 NULL, \
00815                 0, \
00816                 &fptrs, \
00817                 0, \
00818                 #sname \
00819         ASN1_ITEM_end(sname)
00820 
00821 /* Macro to implement standard functions in terms of ASN1_ITEM structures */
00822 
00823 # define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
00824 
00825 # define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
00826 
00827 # define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
00828                         IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
00829 
00830 # define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
00831                 IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
00832 
00833 # define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
00834                 IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
00835 
00836 # define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
00837         pre stname *fname##_new(void) \
00838         { \
00839                 return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
00840         } \
00841         pre void fname##_free(stname *a) \
00842         { \
00843                 ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
00844         }
00845 
00846 # define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
00847         stname *fname##_new(void) \
00848         { \
00849                 return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
00850         } \
00851         void fname##_free(stname *a) \
00852         { \
00853                 ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
00854         }
00855 
00856 # define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
00857         IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
00858         IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
00859 
00860 # define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
00861         stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
00862         { \
00863                 return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
00864         } \
00865         int i2d_##fname(stname *a, unsigned char **out) \
00866         { \
00867                 return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
00868         }
00869 
00870 # define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
00871         int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
00872         { \
00873                 return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
00874         }
00875 
00876 /*
00877  * This includes evil casts to remove const: they will go away when full ASN1
00878  * constification is done.
00879  */
00880 # define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
00881         stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
00882         { \
00883                 return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
00884         } \
00885         int i2d_##fname(const stname *a, unsigned char **out) \
00886         { \
00887                 return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
00888         }
00889 
00890 # define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
00891         stname * stname##_dup(stname *x) \
00892         { \
00893         return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
00894         }
00895 
00896 # define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
00897         IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
00898 
00899 # define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
00900         int fname##_print_ctx(BIO *out, stname *x, int indent, \
00901                                                 const ASN1_PCTX *pctx) \
00902         { \
00903                 return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
00904                         ASN1_ITEM_rptr(itname), pctx); \
00905         }
00906 
00907 # define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
00908                 IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
00909 
00910 # define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
00911         IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
00912         IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
00913 
00914 /* external definitions for primitive types */
00915 
00916 DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
00917 DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
00918 DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
00919 DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
00920 DECLARE_ASN1_ITEM(CBIGNUM)
00921 DECLARE_ASN1_ITEM(BIGNUM)
00922 DECLARE_ASN1_ITEM(LONG)
00923 DECLARE_ASN1_ITEM(ZLONG)
00924 
00925 DECLARE_STACK_OF(ASN1_VALUE)
00926 
00927 /* Functions used internally by the ASN1 code */
00928 
00929 int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
00930 void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
00931 int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
00932 int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
00933 
00934 void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
00935 int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
00936                       const ASN1_TEMPLATE *tt);
00937 int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
00938                      const ASN1_ITEM *it, int tag, int aclass, char opt,
00939                      ASN1_TLC *ctx);
00940 
00941 int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
00942                      const ASN1_ITEM *it, int tag, int aclass);
00943 int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
00944                       const ASN1_TEMPLATE *tt);
00945 void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
00946 
00947 int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
00948                 const ASN1_ITEM *it);
00949 int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
00950                 int utype, char *free_cont, const ASN1_ITEM *it);
00951 
00952 int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
00953 int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
00954                              const ASN1_ITEM *it);
00955 
00956 ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
00957 
00958 const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
00959                                  int nullerr);
00960 
00961 int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
00962 
00963 void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
00964 void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
00965 int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
00966                      const ASN1_ITEM *it);
00967 int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
00968                   const ASN1_ITEM *it);
00969 
00970 #ifdef  __cplusplus
00971 }
00972 #endif
00973 #endif