1*0Sstevel@tonic-gate /* tasn_new.c */ 2*0Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 3*0Sstevel@tonic-gate * project 2000. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate /* ==================================================================== 6*0Sstevel@tonic-gate * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 7*0Sstevel@tonic-gate * 8*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 9*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 10*0Sstevel@tonic-gate * are met: 11*0Sstevel@tonic-gate * 12*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright 13*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 14*0Sstevel@tonic-gate * 15*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 16*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in 17*0Sstevel@tonic-gate * the documentation and/or other materials provided with the 18*0Sstevel@tonic-gate * distribution. 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this 21*0Sstevel@tonic-gate * software must display the following acknowledgment: 22*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 23*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24*0Sstevel@tonic-gate * 25*0Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26*0Sstevel@tonic-gate * endorse or promote products derived from this software without 27*0Sstevel@tonic-gate * prior written permission. For written permission, please contact 28*0Sstevel@tonic-gate * licensing@OpenSSL.org. 29*0Sstevel@tonic-gate * 30*0Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL" 31*0Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written 32*0Sstevel@tonic-gate * permission of the OpenSSL Project. 33*0Sstevel@tonic-gate * 34*0Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following 35*0Sstevel@tonic-gate * acknowledgment: 36*0Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project 37*0Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38*0Sstevel@tonic-gate * 39*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40*0Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42*0Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43*0Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44*0Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45*0Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46*0Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48*0Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49*0Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50*0Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE. 51*0Sstevel@tonic-gate * ==================================================================== 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young 54*0Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim 55*0Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com). 56*0Sstevel@tonic-gate * 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate #include <stddef.h> 61*0Sstevel@tonic-gate #include <openssl/asn1.h> 62*0Sstevel@tonic-gate #include <openssl/objects.h> 63*0Sstevel@tonic-gate #include <openssl/err.h> 64*0Sstevel@tonic-gate #include <openssl/asn1t.h> 65*0Sstevel@tonic-gate #include <string.h> 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine); 68*0Sstevel@tonic-gate static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 69*0Sstevel@tonic-gate static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); 70*0Sstevel@tonic-gate void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) 73*0Sstevel@tonic-gate { 74*0Sstevel@tonic-gate ASN1_VALUE *ret = NULL; 75*0Sstevel@tonic-gate if(ASN1_item_ex_new(&ret, it) > 0) return ret; 76*0Sstevel@tonic-gate return NULL; 77*0Sstevel@tonic-gate } 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate /* Allocate an ASN1 structure */ 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 82*0Sstevel@tonic-gate { 83*0Sstevel@tonic-gate return asn1_item_ex_combine_new(pval, it, 0); 84*0Sstevel@tonic-gate } 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) 87*0Sstevel@tonic-gate { 88*0Sstevel@tonic-gate const ASN1_TEMPLATE *tt = NULL; 89*0Sstevel@tonic-gate const ASN1_COMPAT_FUNCS *cf; 90*0Sstevel@tonic-gate const ASN1_EXTERN_FUNCS *ef; 91*0Sstevel@tonic-gate const ASN1_AUX *aux = it->funcs; 92*0Sstevel@tonic-gate ASN1_aux_cb *asn1_cb; 93*0Sstevel@tonic-gate ASN1_VALUE **pseqval; 94*0Sstevel@tonic-gate int i; 95*0Sstevel@tonic-gate if(aux && aux->asn1_cb) asn1_cb = aux->asn1_cb; 96*0Sstevel@tonic-gate else asn1_cb = 0; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate if(!combine) *pval = NULL; 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate #ifdef CRYPTO_MDEBUG 101*0Sstevel@tonic-gate if(it->sname) CRYPTO_push_info(it->sname); 102*0Sstevel@tonic-gate #endif 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate switch(it->itype) { 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate case ASN1_ITYPE_EXTERN: 107*0Sstevel@tonic-gate ef = it->funcs; 108*0Sstevel@tonic-gate if(ef && ef->asn1_ex_new) { 109*0Sstevel@tonic-gate if(!ef->asn1_ex_new(pval, it)) 110*0Sstevel@tonic-gate goto memerr; 111*0Sstevel@tonic-gate } 112*0Sstevel@tonic-gate break; 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate case ASN1_ITYPE_COMPAT: 115*0Sstevel@tonic-gate cf = it->funcs; 116*0Sstevel@tonic-gate if(cf && cf->asn1_new) { 117*0Sstevel@tonic-gate *pval = cf->asn1_new(); 118*0Sstevel@tonic-gate if(!*pval) goto memerr; 119*0Sstevel@tonic-gate } 120*0Sstevel@tonic-gate break; 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate case ASN1_ITYPE_PRIMITIVE: 123*0Sstevel@tonic-gate if(it->templates) { 124*0Sstevel@tonic-gate if(!ASN1_template_new(pval, it->templates)) 125*0Sstevel@tonic-gate goto memerr; 126*0Sstevel@tonic-gate } else { 127*0Sstevel@tonic-gate if(!ASN1_primitive_new(pval, it)) 128*0Sstevel@tonic-gate goto memerr; 129*0Sstevel@tonic-gate } 130*0Sstevel@tonic-gate break; 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gate case ASN1_ITYPE_MSTRING: 133*0Sstevel@tonic-gate if(!ASN1_primitive_new(pval, it)) 134*0Sstevel@tonic-gate goto memerr; 135*0Sstevel@tonic-gate break; 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate case ASN1_ITYPE_CHOICE: 138*0Sstevel@tonic-gate if(asn1_cb) { 139*0Sstevel@tonic-gate i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); 140*0Sstevel@tonic-gate if(!i) goto auxerr; 141*0Sstevel@tonic-gate if(i==2) { 142*0Sstevel@tonic-gate #ifdef CRYPTO_MDEBUG 143*0Sstevel@tonic-gate if(it->sname) CRYPTO_pop_info(); 144*0Sstevel@tonic-gate #endif 145*0Sstevel@tonic-gate return 1; 146*0Sstevel@tonic-gate } 147*0Sstevel@tonic-gate } 148*0Sstevel@tonic-gate if(!combine) { 149*0Sstevel@tonic-gate *pval = OPENSSL_malloc(it->size); 150*0Sstevel@tonic-gate if(!*pval) goto memerr; 151*0Sstevel@tonic-gate memset(*pval, 0, it->size); 152*0Sstevel@tonic-gate } 153*0Sstevel@tonic-gate asn1_set_choice_selector(pval, -1, it); 154*0Sstevel@tonic-gate if(asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) 155*0Sstevel@tonic-gate goto auxerr; 156*0Sstevel@tonic-gate break; 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gate case ASN1_ITYPE_SEQUENCE: 159*0Sstevel@tonic-gate if(asn1_cb) { 160*0Sstevel@tonic-gate i = asn1_cb(ASN1_OP_NEW_PRE, pval, it); 161*0Sstevel@tonic-gate if(!i) goto auxerr; 162*0Sstevel@tonic-gate if(i==2) { 163*0Sstevel@tonic-gate #ifdef CRYPTO_MDEBUG 164*0Sstevel@tonic-gate if(it->sname) CRYPTO_pop_info(); 165*0Sstevel@tonic-gate #endif 166*0Sstevel@tonic-gate return 1; 167*0Sstevel@tonic-gate } 168*0Sstevel@tonic-gate } 169*0Sstevel@tonic-gate if(!combine) { 170*0Sstevel@tonic-gate *pval = OPENSSL_malloc(it->size); 171*0Sstevel@tonic-gate if(!*pval) goto memerr; 172*0Sstevel@tonic-gate memset(*pval, 0, it->size); 173*0Sstevel@tonic-gate asn1_do_lock(pval, 0, it); 174*0Sstevel@tonic-gate asn1_enc_init(pval, it); 175*0Sstevel@tonic-gate } 176*0Sstevel@tonic-gate for(i = 0, tt = it->templates; i < it->tcount; tt++, i++) { 177*0Sstevel@tonic-gate pseqval = asn1_get_field_ptr(pval, tt); 178*0Sstevel@tonic-gate if(!ASN1_template_new(pseqval, tt)) goto memerr; 179*0Sstevel@tonic-gate } 180*0Sstevel@tonic-gate if(asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it)) 181*0Sstevel@tonic-gate goto auxerr; 182*0Sstevel@tonic-gate break; 183*0Sstevel@tonic-gate } 184*0Sstevel@tonic-gate #ifdef CRYPTO_MDEBUG 185*0Sstevel@tonic-gate if(it->sname) CRYPTO_pop_info(); 186*0Sstevel@tonic-gate #endif 187*0Sstevel@tonic-gate return 1; 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gate memerr: 190*0Sstevel@tonic-gate ASN1err(ASN1_F_ASN1_ITEM_NEW, ERR_R_MALLOC_FAILURE); 191*0Sstevel@tonic-gate #ifdef CRYPTO_MDEBUG 192*0Sstevel@tonic-gate if(it->sname) CRYPTO_pop_info(); 193*0Sstevel@tonic-gate #endif 194*0Sstevel@tonic-gate return 0; 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate auxerr: 197*0Sstevel@tonic-gate ASN1err(ASN1_F_ASN1_ITEM_NEW, ASN1_R_AUX_ERROR); 198*0Sstevel@tonic-gate ASN1_item_ex_free(pval, it); 199*0Sstevel@tonic-gate #ifdef CRYPTO_MDEBUG 200*0Sstevel@tonic-gate if(it->sname) CRYPTO_pop_info(); 201*0Sstevel@tonic-gate #endif 202*0Sstevel@tonic-gate return 0; 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate } 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 207*0Sstevel@tonic-gate { 208*0Sstevel@tonic-gate const ASN1_EXTERN_FUNCS *ef; 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate switch(it->itype) { 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate case ASN1_ITYPE_EXTERN: 213*0Sstevel@tonic-gate ef = it->funcs; 214*0Sstevel@tonic-gate if(ef && ef->asn1_ex_clear) 215*0Sstevel@tonic-gate ef->asn1_ex_clear(pval, it); 216*0Sstevel@tonic-gate else *pval = NULL; 217*0Sstevel@tonic-gate break; 218*0Sstevel@tonic-gate 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate case ASN1_ITYPE_PRIMITIVE: 221*0Sstevel@tonic-gate if(it->templates) 222*0Sstevel@tonic-gate asn1_template_clear(pval, it->templates); 223*0Sstevel@tonic-gate else 224*0Sstevel@tonic-gate asn1_primitive_clear(pval, it); 225*0Sstevel@tonic-gate break; 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate case ASN1_ITYPE_MSTRING: 228*0Sstevel@tonic-gate asn1_primitive_clear(pval, it); 229*0Sstevel@tonic-gate break; 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate case ASN1_ITYPE_COMPAT: 232*0Sstevel@tonic-gate case ASN1_ITYPE_CHOICE: 233*0Sstevel@tonic-gate case ASN1_ITYPE_SEQUENCE: 234*0Sstevel@tonic-gate *pval = NULL; 235*0Sstevel@tonic-gate break; 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate } 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 241*0Sstevel@tonic-gate { 242*0Sstevel@tonic-gate const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); 243*0Sstevel@tonic-gate int ret; 244*0Sstevel@tonic-gate if(tt->flags & ASN1_TFLG_OPTIONAL) { 245*0Sstevel@tonic-gate asn1_template_clear(pval, tt); 246*0Sstevel@tonic-gate return 1; 247*0Sstevel@tonic-gate } 248*0Sstevel@tonic-gate /* If ANY DEFINED BY nothing to do */ 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate if(tt->flags & ASN1_TFLG_ADB_MASK) { 251*0Sstevel@tonic-gate *pval = NULL; 252*0Sstevel@tonic-gate return 1; 253*0Sstevel@tonic-gate } 254*0Sstevel@tonic-gate #ifdef CRYPTO_MDEBUG 255*0Sstevel@tonic-gate if(tt->field_name) CRYPTO_push_info(tt->field_name); 256*0Sstevel@tonic-gate #endif 257*0Sstevel@tonic-gate /* If SET OF or SEQUENCE OF, its a STACK */ 258*0Sstevel@tonic-gate if(tt->flags & ASN1_TFLG_SK_MASK) { 259*0Sstevel@tonic-gate STACK_OF(ASN1_VALUE) *skval; 260*0Sstevel@tonic-gate skval = sk_ASN1_VALUE_new_null(); 261*0Sstevel@tonic-gate if(!skval) { 262*0Sstevel@tonic-gate ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); 263*0Sstevel@tonic-gate ret = 0; 264*0Sstevel@tonic-gate goto done; 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate *pval = (ASN1_VALUE *)skval; 267*0Sstevel@tonic-gate ret = 1; 268*0Sstevel@tonic-gate goto done; 269*0Sstevel@tonic-gate } 270*0Sstevel@tonic-gate /* Otherwise pass it back to the item routine */ 271*0Sstevel@tonic-gate ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); 272*0Sstevel@tonic-gate done: 273*0Sstevel@tonic-gate #ifdef CRYPTO_MDEBUG 274*0Sstevel@tonic-gate if(it->sname) CRYPTO_pop_info(); 275*0Sstevel@tonic-gate #endif 276*0Sstevel@tonic-gate return ret; 277*0Sstevel@tonic-gate } 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) 280*0Sstevel@tonic-gate { 281*0Sstevel@tonic-gate /* If ADB or STACK just NULL the field */ 282*0Sstevel@tonic-gate if(tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK)) 283*0Sstevel@tonic-gate *pval = NULL; 284*0Sstevel@tonic-gate else 285*0Sstevel@tonic-gate asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); 286*0Sstevel@tonic-gate } 287*0Sstevel@tonic-gate 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate /* NB: could probably combine most of the real XXX_new() behaviour and junk all the old 290*0Sstevel@tonic-gate * functions. 291*0Sstevel@tonic-gate */ 292*0Sstevel@tonic-gate 293*0Sstevel@tonic-gate int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 294*0Sstevel@tonic-gate { 295*0Sstevel@tonic-gate ASN1_TYPE *typ; 296*0Sstevel@tonic-gate int utype; 297*0Sstevel@tonic-gate const ASN1_PRIMITIVE_FUNCS *pf; 298*0Sstevel@tonic-gate pf = it->funcs; 299*0Sstevel@tonic-gate if(pf && pf->prim_new) return pf->prim_new(pval, it); 300*0Sstevel@tonic-gate if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; 301*0Sstevel@tonic-gate else utype = it->utype; 302*0Sstevel@tonic-gate switch(utype) { 303*0Sstevel@tonic-gate case V_ASN1_OBJECT: 304*0Sstevel@tonic-gate *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); 305*0Sstevel@tonic-gate return 1; 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate case V_ASN1_BOOLEAN: 308*0Sstevel@tonic-gate if (it) 309*0Sstevel@tonic-gate *(ASN1_BOOLEAN *)pval = it->size; 310*0Sstevel@tonic-gate else 311*0Sstevel@tonic-gate *(ASN1_BOOLEAN *)pval = -1; 312*0Sstevel@tonic-gate return 1; 313*0Sstevel@tonic-gate 314*0Sstevel@tonic-gate case V_ASN1_NULL: 315*0Sstevel@tonic-gate *pval = (ASN1_VALUE *)1; 316*0Sstevel@tonic-gate return 1; 317*0Sstevel@tonic-gate 318*0Sstevel@tonic-gate case V_ASN1_ANY: 319*0Sstevel@tonic-gate typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); 320*0Sstevel@tonic-gate if(!typ) return 0; 321*0Sstevel@tonic-gate typ->value.ptr = NULL; 322*0Sstevel@tonic-gate typ->type = -1; 323*0Sstevel@tonic-gate *pval = (ASN1_VALUE *)typ; 324*0Sstevel@tonic-gate break; 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate default: 327*0Sstevel@tonic-gate *pval = (ASN1_VALUE *)ASN1_STRING_type_new(utype); 328*0Sstevel@tonic-gate break; 329*0Sstevel@tonic-gate } 330*0Sstevel@tonic-gate if(*pval) return 1; 331*0Sstevel@tonic-gate return 0; 332*0Sstevel@tonic-gate } 333*0Sstevel@tonic-gate 334*0Sstevel@tonic-gate void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) 335*0Sstevel@tonic-gate { 336*0Sstevel@tonic-gate int utype; 337*0Sstevel@tonic-gate const ASN1_PRIMITIVE_FUNCS *pf; 338*0Sstevel@tonic-gate pf = it->funcs; 339*0Sstevel@tonic-gate if(pf) { 340*0Sstevel@tonic-gate if(pf->prim_clear) 341*0Sstevel@tonic-gate pf->prim_clear(pval, it); 342*0Sstevel@tonic-gate else 343*0Sstevel@tonic-gate *pval = NULL; 344*0Sstevel@tonic-gate return; 345*0Sstevel@tonic-gate } 346*0Sstevel@tonic-gate if(!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; 347*0Sstevel@tonic-gate else utype = it->utype; 348*0Sstevel@tonic-gate if(utype == V_ASN1_BOOLEAN) 349*0Sstevel@tonic-gate *(ASN1_BOOLEAN *)pval = it->size; 350*0Sstevel@tonic-gate else *pval = NULL; 351*0Sstevel@tonic-gate } 352