1 /* asn1t.h */ 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * project 2000. 4 */ 5 /* ==================================================================== 6 * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 module deimos.openssl.asn1t; 59 60 import deimos.openssl._d_util; 61 62 import deimos.openssl.ossl_typ; // Needed for ASN1_BOOLEAN, etc. 63 64 import core.stdc.config; 65 public import deimos.openssl.e_os2; 66 public import deimos.openssl.asn1; 67 68 69 /* ASN1 template defines, structures and functions */ 70 71 extern (C): 72 nothrow: 73 74 /+ FIXME: Not yet ported. 75 #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION 76 77 /* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ 78 #define ASN1_ADB_ptr(iptr) ((const(ASN1_ADB)*)(iptr)) 79 80 81 /* Macros for start and end of ASN1_ITEM definition */ 82 83 #define ASN1_ITEM_start(itname) \ 84 OPENSSL_GLOBAL const ASN1_ITEM itname##_it = { 85 86 #define ASN1_ITEM_end(itname) \ 87 }; 88 89 #else 90 91 /* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ 92 #define ASN1_ADB_ptr(iptr) ((const(ASN1_ADB)*)(iptr())) 93 94 95 /* Macros for start and end of ASN1_ITEM definition */ 96 97 #define ASN1_ITEM_start(itname) \ 98 const(ASN1_ITEM)* itname##_it() \ 99 { \ 100 static const ASN1_ITEM local_it = { 101 102 #define ASN1_ITEM_end(itname) \ 103 }; \ 104 return &local_it; \ 105 } 106 107 #endif 108 109 110 /* Macros to aid ASN1 template writing */ 111 112 #define ASN1_ITEM_TEMPLATE(tname) \ 113 static const ASN1_TEMPLATE tname##_item_tt 114 115 #define ASN1_ITEM_TEMPLATE_END(tname) \ 116 ;\ 117 ASN1_ITEM_start(tname) \ 118 ASN1_ITYPE_PRIMITIVE,\ 119 -1,\ 120 &tname##_item_tt,\ 121 0,\ 122 NULL,\ 123 0,\ 124 #tname \ 125 ASN1_ITEM_end(tname) 126 127 128 /* This is a ASN1 type which just embeds a template */ 129 130 /* This pair helps declare a SEQUENCE. We can do: 131 * 132 * ASN1_SEQUENCE(stname) = { 133 * ... SEQUENCE components ... 134 * } ASN1_SEQUENCE_END(stname) 135 * 136 * This will produce an ASN1_ITEM called stname_it 137 * for a structure called stname. 138 * 139 * If you want the same structure but a different 140 * name then use: 141 * 142 * ASN1_SEQUENCE(itname) = { 143 * ... SEQUENCE components ... 144 * } ASN1_SEQUENCE_END_name(stname, itname) 145 * 146 * This will create an item called itname_it using 147 * a structure called stname. 148 */ 149 150 #define ASN1_SEQUENCE(tname) \ 151 static const ASN1_TEMPLATE[] tname##_seq_tt 152 153 #define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) 154 155 #define ASN1_SEQUENCE_END_name(stname, tname) \ 156 ;\ 157 ASN1_ITEM_start(tname) \ 158 ASN1_ITYPE_SEQUENCE,\ 159 V_ASN1_SEQUENCE,\ 160 tname##_seq_tt,\ 161 sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ 162 NULL,\ 163 sizeof(stname),\ 164 #stname \ 165 ASN1_ITEM_end(tname) 166 167 #define ASN1_NDEF_SEQUENCE(tname) \ 168 ASN1_SEQUENCE(tname) 169 170 #define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ 171 ASN1_SEQUENCE_cb(tname, cb) 172 173 #define ASN1_SEQUENCE_cb(tname, cb) \ 174 static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ 175 ASN1_SEQUENCE(tname) 176 177 #define ASN1_BROKEN_SEQUENCE(tname) \ 178 static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ 179 ASN1_SEQUENCE(tname) 180 181 #define ASN1_SEQUENCE_ref(tname, cb, lck) \ 182 static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \ 183 ASN1_SEQUENCE(tname) 184 185 #define ASN1_SEQUENCE_enc(tname, enc, cb) \ 186 static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ 187 ASN1_SEQUENCE(tname) 188 189 #define ASN1_NDEF_SEQUENCE_END(tname) \ 190 ;\ 191 ASN1_ITEM_start(tname) \ 192 ASN1_ITYPE_NDEF_SEQUENCE,\ 193 V_ASN1_SEQUENCE,\ 194 tname##_seq_tt,\ 195 sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ 196 NULL,\ 197 sizeof(tname),\ 198 #tname \ 199 ASN1_ITEM_end(tname) 200 201 #define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) 202 203 #define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) 204 205 #define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) 206 207 #define ASN1_SEQUENCE_END_ref(stname, tname) \ 208 ;\ 209 ASN1_ITEM_start(tname) \ 210 ASN1_ITYPE_SEQUENCE,\ 211 V_ASN1_SEQUENCE,\ 212 tname##_seq_tt,\ 213 sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ 214 &tname##_aux,\ 215 sizeof(stname),\ 216 #stname \ 217 ASN1_ITEM_end(tname) 218 219 #define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ 220 ;\ 221 ASN1_ITEM_start(tname) \ 222 ASN1_ITYPE_NDEF_SEQUENCE,\ 223 V_ASN1_SEQUENCE,\ 224 tname##_seq_tt,\ 225 sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ 226 &tname##_aux,\ 227 sizeof(stname),\ 228 #stname \ 229 ASN1_ITEM_end(tname) 230 231 232 /* This pair helps declare a CHOICE type. We can do: 233 * 234 * ASN1_CHOICE(chname) = { 235 * ... CHOICE options ... 236 * ASN1_CHOICE_END(chname) 237 * 238 * This will produce an ASN1_ITEM called chname_it 239 * for a structure called chname. The structure 240 * definition must look like this: 241 * typedef struct { 242 * int type; 243 * union { 244 * ASN1_SOMETHING* opt1; 245 * ASN1_SOMEOTHER* opt2; 246 * } value; 247 * } chname; 248 * 249 * the name of the selector must be 'type'. 250 * to use an alternative selector name use the 251 * ASN1_CHOICE_END_selector() version. 252 */ 253 254 #define ASN1_CHOICE(tname) \ 255 static const ASN1_TEMPLATE[] tname##_ch_tt 256 257 #define ASN1_CHOICE_cb(tname, cb) \ 258 static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ 259 ASN1_CHOICE(tname) 260 261 #define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) 262 263 #define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) 264 265 #define ASN1_CHOICE_END_selector(stname, tname, selname) \ 266 ;\ 267 ASN1_ITEM_start(tname) \ 268 ASN1_ITYPE_CHOICE,\ 269 offsetof(stname,selname) ,\ 270 tname##_ch_tt,\ 271 sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ 272 NULL,\ 273 sizeof(stname),\ 274 #stname \ 275 ASN1_ITEM_end(tname) 276 277 #define ASN1_CHOICE_END_cb(stname, tname, selname) \ 278 ;\ 279 ASN1_ITEM_start(tname) \ 280 ASN1_ITYPE_CHOICE,\ 281 offsetof(stname,selname) ,\ 282 tname##_ch_tt,\ 283 sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ 284 &tname##_aux,\ 285 sizeof(stname),\ 286 #stname \ 287 ASN1_ITEM_end(tname) 288 289 /* This helps with the template wrapper form of ASN1_ITEM */ 290 291 #define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ 292 (flags), (tag), 0,\ 293 #name, ASN1_ITEM_ref(type) } 294 295 /* These help with SEQUENCE or CHOICE components */ 296 297 /* used to declare other types */ 298 299 #define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ 300 (flags), (tag), offsetof(stname, field),\ 301 #field, ASN1_ITEM_ref(type) } 302 303 /* used when the structure is combined with the parent */ 304 305 #define ASN1_EX_COMBINE(flags, tag, type) { \ 306 (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) } 307 308 /* implicit and explicit helper macros */ 309 310 #define ASN1_IMP_EX(stname, field, type, tag, ex) \ 311 ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type) 312 313 #define ASN1_EXP_EX(stname, field, type, tag, ex) \ 314 ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type) 315 316 /* Any defined by macros: the field used is in the table itself */ 317 318 #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION 319 #define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const(ASN1_ITEM)*)&(tblname##_adb) } 320 #define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const(ASN1_ITEM)*)&(tblname##_adb) } 321 #else 322 #define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb } 323 #define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb } 324 #endif 325 /* Plain simple type */ 326 #define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) 327 328 /* OPTIONAL simple type */ 329 #define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) 330 331 /* IMPLICIT tagged simple type */ 332 #define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) 333 334 /* IMPLICIT tagged OPTIONAL simple type */ 335 #define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) 336 337 /* Same as above but EXPLICIT */ 338 339 #define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) 340 #define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) 341 342 /* SEQUENCE OF type */ 343 #define ASN1_SEQUENCE_OF(stname, field, type) \ 344 ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) 345 346 /* OPTIONAL SEQUENCE OF */ 347 #define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ 348 ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) 349 350 /* Same as above but for SET OF */ 351 352 #define ASN1_SET_OF(stname, field, type) \ 353 ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) 354 355 #define ASN1_SET_OF_OPT(stname, field, type) \ 356 ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) 357 358 /* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ 359 360 #define ASN1_IMP_SET_OF(stname, field, type, tag) \ 361 ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) 362 363 #define ASN1_EXP_SET_OF(stname, field, type, tag) \ 364 ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) 365 366 #define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ 367 ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) 368 369 #define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ 370 ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) 371 372 #define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ 373 ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) 374 375 #define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ 376 ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) 377 378 #define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ 379 ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) 380 381 #define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ 382 ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) 383 384 /* EXPLICIT using indefinite length constructed form */ 385 #define ASN1_NDEF_EXP(stname, field, type, tag) \ 386 ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) 387 388 /* EXPLICIT OPTIONAL using indefinite length constructed form */ 389 #define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ 390 ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) 391 392 /* Macros for the ASN1_ADB structure */ 393 394 #define ASN1_ADB(name) \ 395 static const ASN1_ADB_TABLE[] name##_adbtbl 396 397 #ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION 398 399 #define ASN1_ADB_END(name, flags, field, app_table, def, none) \ 400 ;\ 401 static const ASN1_ADB name##_adb = {\ 402 flags,\ 403 offsetof(name, field),\ 404 app_table,\ 405 name##_adbtbl,\ 406 sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ 407 def,\ 408 none\ 409 } 410 411 #else 412 413 #define ASN1_ADB_END(name, flags, field, app_table, def, none) \ 414 ;\ 415 static const(ASN1_ITEM)* name##_adb() \ 416 { \ 417 static const ASN1_ADB internal_adb = \ 418 {\ 419 flags,\ 420 offsetof(name, field),\ 421 app_table,\ 422 name##_adbtbl,\ 423 sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ 424 def,\ 425 none\ 426 }; \ 427 return (const(ASN1_ITEM)*) &internal_adb; \ 428 } \ 429 void dummy_function() 430 431 #endif 432 433 #define ADB_ENTRY(val, template) {val, template} 434 435 #define ASN1_ADB_TEMPLATE(name) \ 436 static const ASN1_TEMPLATE name##_tt 437 +/ 438 /* This is the ASN1 template structure that defines 439 * a wrapper round the actual type. It determines the 440 * actual position of the field in the value structure, 441 * various flags such as OPTIONAL and the field name. 442 */ 443 444 struct ASN1_TEMPLATE_st { 445 c_ulong flags; /* Various flags */ 446 c_long tag; /* tag, not used if no tagging */ 447 c_ulong offset; /* Offset of this field in structure */ 448 version (NO_ASN1_FIELD_NAMES) {} else { 449 const(char)* field_name; /* Field name */ 450 } 451 ASN1_ITEM_EXP* item; /* Relevant ASN1_ITEM or ASN1_ADB */ 452 }; 453 454 /* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ 455 456 auto ASN1_TEMPLATE_item()(ASN1_TEMPLATE_st* t) { return (t.item_ptr); } 457 auto ASN1_TEMPLATE_adb()(ASN1_TEMPLATE_st* t) { return (t.item_ptr); } 458 459 alias ASN1_ADB_TABLE_st ASN1_ADB_TABLE; 460 alias ASN1_ADB_st ASN1_ADB; 461 462 struct ASN1_ADB_st { 463 c_ulong flags; /* Various flags */ 464 c_ulong offset; /* Offset of selector field */ 465 STACK_OF!(ASN1_ADB_TABLE) **app_items; /* Application defined items */ 466 const(ASN1_ADB_TABLE)* tbl; /* Table of possible types */ 467 c_long tblcount; /* Number of entries in tbl */ 468 const(ASN1_TEMPLATE)* default_tt; /* Type to use if no match */ 469 const(ASN1_TEMPLATE)* null_tt; /* Type to use if selector is NULL */ 470 }; 471 472 struct ASN1_ADB_TABLE_st { 473 c_long value; /* NID for an object or value for an int */ 474 const ASN1_TEMPLATE tt; /* item for this value */ 475 }; 476 477 /* template flags */ 478 479 /* Field is optional */ 480 enum ASN1_TFLG_OPTIONAL = (0x1); 481 482 /* Field is a SET OF */ 483 enum ASN1_TFLG_SET_OF = (0x1 << 1); 484 485 /* Field is a SEQUENCE OF */ 486 enum ASN1_TFLG_SEQUENCE_OF = (0x2 << 1); 487 488 /* Special case: this refers to a SET OF that 489 * will be sorted into DER order when encoded* and* 490 * the corresponding STACK will be modified to match 491 * the new order. 492 */ 493 enum ASN1_TFLG_SET_ORDER = (0x3 << 1); 494 495 /* Mask for SET OF or SEQUENCE OF */ 496 enum ASN1_TFLG_SK_MASK = (0x3 << 1); 497 498 /* These flags mean the tag should be taken from the 499 * tag field. If EXPLICIT then the underlying type 500 * is used for the inner tag. 501 */ 502 503 /* IMPLICIT tagging */ 504 enum ASN1_TFLG_IMPTAG = (0x1 << 3); 505 506 507 /* EXPLICIT tagging, inner tag from underlying type */ 508 enum ASN1_TFLG_EXPTAG = (0x2 << 3); 509 510 enum ASN1_TFLG_TAG_MASK = (0x3 << 3); 511 512 /* context specific IMPLICIT */ 513 enum ASN1_TFLG_IMPLICIT = ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT; 514 515 /* context specific EXPLICIT */ 516 enum ASN1_TFLG_EXPLICIT = ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT; 517 518 /* If tagging is in force these determine the 519 * type of tag to use. Otherwise the tag is 520 * determined by the underlying type. These 521 * values reflect the actual octet format. 522 */ 523 524 /* Universal tag */ 525 enum ASN1_TFLG_UNIVERSAL = (0x0<<6); 526 /* Application tag */ 527 enum ASN1_TFLG_APPLICATION = (0x1<<6); 528 /* Context specific tag */ 529 enum ASN1_TFLG_CONTEXT = (0x2<<6); 530 /* Private tag */ 531 enum ASN1_TFLG_PRIVATE = (0x3<<6); 532 533 enum ASN1_TFLG_TAG_CLASS = (0x3<<6); 534 535 /* These are for ANY DEFINED BY type. In this case 536 * the 'item' field points to an ASN1_ADB structure 537 * which contains a table of values to decode the 538 * relevant type 539 */ 540 541 enum ASN1_TFLG_ADB_MASK = (0x3<<8); 542 543 enum ASN1_TFLG_ADB_OID = (0x1<<8); 544 545 enum ASN1_TFLG_ADB_INT = (0x1<<9); 546 547 /* This flag means a parent structure is passed 548 * instead of the field: this is useful is a 549 * SEQUENCE is being combined with a CHOICE for 550 * example. Since this means the structure and 551 * item name will differ we need to use the 552 * ASN1_CHOICE_END_name() macro for example. 553 */ 554 555 enum ASN1_TFLG_COMBINE = (0x1<<10); 556 557 /* This flag when present in a SEQUENCE OF, SET OF 558 * or EXPLICIT causes indefinite length constructed 559 * encoding to be used if required. 560 */ 561 562 enum ASN1_TFLG_NDEF = (0x1<<11); 563 564 /* This is the actual ASN1 item itself */ 565 566 struct ASN1_ITEM_st { 567 char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */ 568 c_long utype; /* underlying type */ 569 const(ASN1_TEMPLATE)* templates; /* If SEQUENCE or CHOICE this contains the contents */ 570 c_long tcount; /* Number of templates if SEQUENCE or CHOICE */ 571 const(void)* funcs; /* functions that handle this type */ 572 c_long size; /* Structure size (usually)*/ 573 version (NO_ASN1_FIELD_NAMES) {} else { 574 const(char)* sname; /* Structure name */ 575 } 576 }; 577 578 /* These are values for the itype field and 579 * determine how the type is interpreted. 580 * 581 * For PRIMITIVE types the underlying type 582 * determines the behaviour if items is NULL. 583 * 584 * Otherwise templates must contain a single 585 * template and the type is treated in the 586 * same way as the type specified in the template. 587 * 588 * For SEQUENCE types the templates field points 589 * to the members, the size field is the 590 * structure size. 591 * 592 * For CHOICE types the templates field points 593 * to each possible member (typically a union) 594 * and the 'size' field is the offset of the 595 * selector. 596 * 597 * The 'funcs' field is used for application 598 * specific functions. 599 * 600 * For COMPAT types the funcs field gives a 601 * set of functions that handle this type, this 602 * supports the old d2i, i2d convention. 603 * 604 * The EXTERN type uses a new style d2i/i2d. 605 * The new style should be used where possible 606 * because it avoids things like the d2i IMPLICIT 607 * hack. 608 * 609 * MSTRING is a multiple string type, it is used 610 * for a CHOICE of character strings where the 611 * actual strings all occupy an ASN1_STRING 612 * structure. In this case the 'utype' field 613 * has a special meaning, it is used as a mask 614 * of acceptable types using the B_ASN1 constants. 615 * 616 * NDEF_SEQUENCE is the same as SEQUENCE except 617 * that it will use indefinite length constructed 618 * encoding if requested. 619 * 620 */ 621 622 enum ASN1_ITYPE_PRIMITIVE = 0x0; 623 624 enum ASN1_ITYPE_SEQUENCE = 0x1; 625 626 enum ASN1_ITYPE_CHOICE = 0x2; 627 628 enum ASN1_ITYPE_COMPAT = 0x3; 629 630 enum ASN1_ITYPE_EXTERN = 0x4; 631 632 enum ASN1_ITYPE_MSTRING = 0x5; 633 634 enum ASN1_ITYPE_NDEF_SEQUENCE = 0x6; 635 636 /* Cache for ASN1 tag and length, so we 637 * don't keep re-reading it for things 638 * like CHOICE 639 */ 640 641 struct ASN1_TLC_st{ 642 char valid; /* Values below are valid */ 643 int ret; /* return value */ 644 c_long plen; /* length */ 645 int ptag; /* class value */ 646 int pclass; /* class value */ 647 int hdrlen; /* header length */ 648 }; 649 650 /* Typedefs for ASN1 function pointers */ 651 652 alias typeof(*(ExternC!(ASN1_VALUE* function())).init) ASN1_new_func; 653 alias typeof(*(ExternC!(void function(ASN1_VALUE* a))).init) ASN1_free_func; 654 alias typeof(*(ExternC!(ASN1_VALUE* function(ASN1_VALUE** a, const(ubyte)** in_, c_long length))).init) ASN1_d2i_func; 655 alias typeof(*(ExternC!(int function(ASN1_VALUE* a, ubyte** in_))).init) ASN1_i2d_func; 656 657 alias typeof(*(ExternC!(int function(ASN1_VALUE** pval, const(ubyte)** in_, c_long len, const(ASN1_ITEM)* it, 658 int tag, int aclass, char opt, ASN1_TLC* ctx))).init) ASN1_ex_d2i; 659 660 alias typeof(*(ExternC!(int function(ASN1_VALUE** pval, ubyte** out_, const(ASN1_ITEM)* it, int tag, int aclass))).init) ASN1_ex_i2d; 661 alias typeof(*(ExternC!(int function(ASN1_VALUE** pval, const(ASN1_ITEM)* it))).init) ASN1_ex_new_func; 662 alias typeof(*(ExternC!(void function(ASN1_VALUE** pval, const(ASN1_ITEM)* it))).init) ASN1_ex_free_func; 663 664 alias typeof(*(ExternC!(int function(BIO* out_, ASN1_VALUE** pval, 665 int indent, const(char)* fname, 666 const(ASN1_PCTX)* pctx))).init) ASN1_ex_print_func; 667 668 alias typeof(*(ExternC!(int function(ASN1_VALUE** pval, ubyte* cont, int* putype, const(ASN1_ITEM)* it))).init) ASN1_primitive_i2c; 669 alias typeof(*(ExternC!(int function(ASN1_VALUE** pval, const(ubyte)* cont, int len, int utype, char* free_cont, const(ASN1_ITEM)* it))).init) ASN1_primitive_c2i; 670 alias typeof(*(ExternC!(int function(BIO* out_, ASN1_VALUE** pval, const(ASN1_ITEM)* it, int indent, const(ASN1_PCTX)* pctx))).init) ASN1_primitive_print; 671 672 struct ASN1_COMPAT_FUNCS_st { 673 ASN1_new_func* asn1_new; 674 ASN1_free_func* asn1_free; 675 ASN1_d2i_func* asn1_d2i; 676 ASN1_i2d_func* asn1_i2d; 677 } 678 alias ASN1_COMPAT_FUNCS_st ASN1_COMPAT_FUNCS; 679 680 struct ASN1_EXTERN_FUNCS_st { 681 void* app_data; 682 ASN1_ex_new_func* asn1_ex_new; 683 ASN1_ex_free_func* asn1_ex_free; 684 ASN1_ex_free_func* asn1_ex_clear; 685 ASN1_ex_d2i* asn1_ex_d2i; 686 ASN1_ex_i2d* asn1_ex_i2d; 687 ASN1_ex_print_func* asn1_ex_print; 688 } 689 alias ASN1_EXTERN_FUNCS_st ASN1_EXTERN_FUNCS; 690 691 struct ASN1_PRIMITIVE_FUNCS_st { 692 void* app_data; 693 c_ulong flags; 694 ASN1_ex_new_func* prim_new; 695 ASN1_ex_free_func* prim_free; 696 ASN1_ex_free_func* prim_clear; 697 ASN1_primitive_c2i* prim_c2i; 698 ASN1_primitive_i2c* prim_i2c; 699 ASN1_primitive_print* prim_print; 700 } 701 alias ASN1_PRIMITIVE_FUNCS_st ASN1_PRIMITIVE_FUNCS; 702 703 /* This is the ASN1_AUX structure: it handles various 704 * miscellaneous requirements. For example the use of 705 * reference counts and an informational callback. 706 * 707 * The "informational callback" is called at various 708 * points during the ASN1 encoding and decoding. It can 709 * be used to provide minor customisation of the structures 710 * used. This is most useful where the supplied routines 711 ** almost* do the right thing but need some extra help 712 * at a few points. If the callback returns zero then 713 * it is assumed a fatal error has occurred and the 714 * main operation should be abandoned. 715 * 716 * If major changes in the default behaviour are required 717 * then an external type is more appropriate. 718 */ 719 720 alias typeof(*(ExternC!(int function(int operation, ASN1_VALUE** in_, const(ASN1_ITEM)* it, 721 void* exarg))).init) ASN1_aux_cb; 722 723 struct ASN1_AUX_st { 724 void* app_data; 725 int flags; 726 int ref_offset; /* Offset of reference value */ 727 int ref_lock; /* Lock type to use */ 728 ASN1_aux_cb* asn1_cb; 729 int enc_offset; /* Offset of ASN1_ENCODING structure */ 730 } 731 alias ASN1_AUX_st ASN1_AUX; 732 733 /* For print related callbacks exarg points to this structure */ 734 struct ASN1_PRINT_ARG_st { 735 BIO* out_; 736 int indent; 737 const(ASN1_PCTX)* pctx; 738 } 739 alias ASN1_PRINT_ARG_st ASN1_PRINT_ARG; 740 741 /* For streaming related callbacks exarg points to this structure */ 742 struct ASN1_STREAM_ARG_st { 743 /* BIO to stream through */ 744 BIO* out_; 745 /* BIO with filters appended */ 746 BIO* ndef_bio; 747 /* Streaming I/O boundary */ 748 ubyte** boundary; 749 } 750 alias ASN1_STREAM_ARG_st ASN1_STREAM_ARG; 751 752 /* Flags in ASN1_AUX */ 753 754 /* Use a reference count */ 755 enum ASN1_AFLG_REFCOUNT = 1; 756 /* Save the encoding of structure (useful for signatures) */ 757 enum ASN1_AFLG_ENCODING = 2; 758 /* The Sequence length is invalid */ 759 enum ASN1_AFLG_BROKEN = 4; 760 761 /* operation values for asn1_cb */ 762 763 enum ASN1_OP_NEW_PRE = 0; 764 enum ASN1_OP_NEW_POST = 1; 765 enum ASN1_OP_FREE_PRE = 2; 766 enum ASN1_OP_FREE_POST = 3; 767 enum ASN1_OP_D2I_PRE = 4; 768 enum ASN1_OP_D2I_POST = 5; 769 enum ASN1_OP_I2D_PRE = 6; 770 enum ASN1_OP_I2D_POST = 7; 771 enum ASN1_OP_PRINT_PRE = 8; 772 enum ASN1_OP_PRINT_POST = 9; 773 enum ASN1_OP_STREAM_PRE = 10; 774 enum ASN1_OP_STREAM_POST = 11; 775 enum ASN1_OP_DETACHED_PRE = 12; 776 enum ASN1_OP_DETACHED_POST = 13; 777 778 /+ FIXME: Not yet ported. 779 /* Macro to implement a primitive type */ 780 #define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) 781 #define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ 782 ASN1_ITEM_start(itname) \ 783 ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ 784 ASN1_ITEM_end(itname) 785 786 /* Macro to implement a multi string type */ 787 #define IMPLEMENT_ASN1_MSTRING(itname, mask) \ 788 ASN1_ITEM_start(itname) \ 789 ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ 790 ASN1_ITEM_end(itname) 791 792 /* Macro to implement an ASN1_ITEM in terms of old style funcs */ 793 794 #define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE) 795 796 #define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \ 797 static const ASN1_COMPAT_FUNCS sname##_ff = { \ 798 (ASN1_new_func*)sname##_new, \ 799 (ASN1_free_func*)sname##_free, \ 800 (ASN1_d2i_func*)d2i_##sname, \ 801 (ASN1_i2d_func*)i2d_##sname, \ 802 }; \ 803 ASN1_ITEM_start(sname) \ 804 ASN1_ITYPE_COMPAT, \ 805 tag, \ 806 NULL, \ 807 0, \ 808 &sname##_ff, \ 809 0, \ 810 #sname \ 811 ASN1_ITEM_end(sname) 812 813 #define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ 814 ASN1_ITEM_start(sname) \ 815 ASN1_ITYPE_EXTERN, \ 816 tag, \ 817 NULL, \ 818 0, \ 819 &fptrs, \ 820 0, \ 821 #sname \ 822 ASN1_ITEM_end(sname) 823 824 /* Macro to implement standard functions in terms of ASN1_ITEM structures */ 825 826 #define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) 827 828 #define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) 829 830 #define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ 831 IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) 832 833 #define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ 834 IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) 835 836 #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ 837 IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) 838 839 #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ 840 pre stname* fname##_new() \ 841 { \ 842 return (stname*)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ 843 } \ 844 pre void fname##_free(stname* a) \ 845 { \ 846 ASN1_item_free((ASN1_VALUE*)a, ASN1_ITEM_rptr(itname)); \ 847 } 848 849 #define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ 850 stname* fname##_new() \ 851 { \ 852 return (stname*)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ 853 } \ 854 void fname##_free(stname* a) \ 855 { \ 856 ASN1_item_free((ASN1_VALUE*)a, ASN1_ITEM_rptr(itname)); \ 857 } 858 859 #define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ 860 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ 861 IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) 862 863 #define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ 864 stname* d2i_##fname(stname** a, const(ubyte)** in_, c_long len) \ 865 { \ 866 return (stname*)ASN1_item_d2i((ASN1_VALUE**)a, in_, len, ASN1_ITEM_rptr(itname));\ 867 } \ 868 int i2d_##fname(stname* a, ubyte** out_) \ 869 { \ 870 return ASN1_item_i2d((ASN1_VALUE*)a, out_, ASN1_ITEM_rptr(itname));\ 871 } 872 873 #define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ 874 int i2d_##stname##_NDEF(stname* a, ubyte** out_) \ 875 { \ 876 return ASN1_item_ndef_i2d((ASN1_VALUE*)a, out_, ASN1_ITEM_rptr(stname));\ 877 } 878 879 /* This includes evil casts to remove const: they will go away when full 880 * ASN1 constification is done. 881 */ 882 #define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ 883 stname* d2i_##fname(stname** a, const(ubyte)** in_, c_long len) \ 884 { \ 885 return (stname*)ASN1_item_d2i((ASN1_VALUE**)a, in_, len, ASN1_ITEM_rptr(itname));\ 886 } \ 887 int i2d_##fname(const(stname)* a, ubyte** out_) \ 888 { \ 889 return ASN1_item_i2d((ASN1_VALUE*)a, out_, ASN1_ITEM_rptr(itname));\ 890 } 891 892 #define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ 893 stname* stname##_dup(stname* x) \ 894 { \ 895 return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ 896 } 897 898 #define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ 899 IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) 900 901 #define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ 902 int fname##_print_ctx(BIO* out_, stname* x, int indent, \ 903 const(ASN1_PCTX)* pctx) \ 904 { \ 905 return ASN1_item_print(out, (ASN1_VALUE*)x, indent, \ 906 ASN1_ITEM_rptr(itname), pctx); \ 907 } 908 909 #define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ 910 IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) 911 912 #define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ 913 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ 914 IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) 915 +/ 916 917 /* external definitions for primitive types */ 918 919 mixin(DECLARE_ASN1_ITEM!"ASN1_BOOLEAN"); 920 mixin(DECLARE_ASN1_ITEM!"ASN1_TBOOLEAN"); 921 mixin(DECLARE_ASN1_ITEM!"ASN1_FBOOLEAN"); 922 mixin(DECLARE_ASN1_ITEM!"ASN1_SEQUENCE"); 923 mixin(DECLARE_ASN1_ITEM!"CBIGNUM"); 924 mixin(DECLARE_ASN1_ITEM!"BIGNUM"); 925 mixin(DECLARE_ASN1_ITEM!"LONG"); 926 mixin(DECLARE_ASN1_ITEM!"ZLONG"); 927 928 /+mixin DECLARE_STACK_OF!(ASN1_VALUE);+/ 929 930 /* Functions used internally by the ASN1 code */ 931 932 int ASN1_item_ex_new(ASN1_VALUE** pval, const(ASN1_ITEM)* it); 933 void ASN1_item_ex_free(ASN1_VALUE** pval, const(ASN1_ITEM)* it); 934 int ASN1_template_new(ASN1_VALUE** pval, const(ASN1_TEMPLATE)* tt); 935 int ASN1_primitive_new(ASN1_VALUE** pval, const(ASN1_ITEM)* it); 936 937 void ASN1_template_free(ASN1_VALUE** pval, const(ASN1_TEMPLATE)* tt); 938 int ASN1_template_d2i(ASN1_VALUE** pval, const(ubyte)** in_, c_long len, const(ASN1_TEMPLATE)* tt); 939 int ASN1_item_ex_d2i(ASN1_VALUE** pval, const(ubyte)** in_, c_long len, const(ASN1_ITEM)* it, 940 int tag, int aclass, char opt, ASN1_TLC* ctx); 941 942 int ASN1_item_ex_i2d(ASN1_VALUE** pval, ubyte** out_, const(ASN1_ITEM)* it, int tag, int aclass); 943 int ASN1_template_i2d(ASN1_VALUE** pval, ubyte** out_, const(ASN1_TEMPLATE)* tt); 944 void ASN1_primitive_free(ASN1_VALUE** pval, const(ASN1_ITEM)* it); 945 946 int asn1_ex_i2c(ASN1_VALUE** pval, ubyte* cont, int* putype, const(ASN1_ITEM)* it); 947 int asn1_ex_c2i(ASN1_VALUE** pval, const(ubyte)* cont, int len, int utype, char* free_cont, const(ASN1_ITEM)* it); 948 949 int asn1_get_choice_selector(ASN1_VALUE** pval, const(ASN1_ITEM)* it); 950 int asn1_set_choice_selector(ASN1_VALUE** pval, int value, const(ASN1_ITEM)* it); 951 952 ASN1_VALUE** asn1_get_field_ptr(ASN1_VALUE** pval, const(ASN1_TEMPLATE)* tt); 953 954 const(ASN1_TEMPLATE)* asn1_do_adb(ASN1_VALUE** pval, const(ASN1_TEMPLATE)* tt, int nullerr); 955 956 int asn1_do_lock(ASN1_VALUE** pval, int op, const(ASN1_ITEM)* it); 957 958 void asn1_enc_init(ASN1_VALUE** pval, const(ASN1_ITEM)* it); 959 void asn1_enc_free(ASN1_VALUE** pval, const(ASN1_ITEM)* it); 960 int asn1_enc_restore(int* len, ubyte** out_, ASN1_VALUE** pval, const(ASN1_ITEM)* it); 961 int asn1_enc_save(ASN1_VALUE** pval, const(ubyte)* in_, int inlen, const(ASN1_ITEM)* it);