195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved. 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This package is an SSL implementation written 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * by Eric Young (eay@cryptsoft.com). 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The implementation was written so as to conform with Netscapes SSL. 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This library is free for commercial and non-commercial use as long as 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the following conditions are aheared to. The following conditions 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * apply to all code found in this distribution, be it the RC4, RSA, 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included with this distribution is covered by the same copyright terms 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the code are not to be removed. 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If this package is used in a product, Eric Young should be given attribution 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as the author of the parts of the library used. 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This can be in the form of a textual message at program startup or 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * in documentation (online or textual) provided with the package. 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the copyright 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in the 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * documentation and/or other materials provided with the distribution. 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this software 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * must display the following acknowledgement: 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes cryptographic software written by 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Eric Young (eay@cryptsoft.com)" 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The word 'cryptographic' can be left out if the rouines from the library 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * being used are not cryptographic related :-). 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the apps directory (application code) you must include an acknowledgement: 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SUCH DAMAGE. 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The licence and distribution terms for any publically available version or 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copied and put under another distribution licence 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * [including the GNU Public Licence.] */ 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/asn1.h> 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/asn1t.h> 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_ITEM *it, 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int tag, int aclass); 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int skcontlen, const ASN1_ITEM *item, 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int do_sort, int iclass); 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *tt, 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int tag, int aclass); 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_ITEM *it, int flags); 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Top level i2d equivalents: the 'ndef' variant instructs the encoder 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * to use indefinite length constructed encoding, where appropriate 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_ITEM *it) 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF); 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_item_flags_i2d(val, out, it, 0); 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Encode an ASN1 item, this is use by the 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * standard 'i2d' function. 'out' points to 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * a buffer to output the data to. 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The new i2d has one additional feature. If the output 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * buffer is NULL (i.e. *out == NULL) then a buffer is 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * allocated and populated with the encoding. 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_ITEM *it, int flags) 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out && !*out) 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char *p, *buf; 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int len; 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (len <= 0) 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return len; 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf = OPENSSL_malloc(len); 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!buf) 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = buf; 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_item_ex_i2d(&val, &p, it, -1, flags); 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out = buf; 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return len; 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ASN1_item_ex_i2d(&val, out, it, -1, flags); 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Encode an item, taking care of IMPLICIT tagging (if any). 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This function performs the normal item handling: it can be 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * used in external types. 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_ITEM *it, int tag, int aclass) 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *tt = NULL; 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char *p = NULL; 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i, seqcontlen, seqlen, ndef = 1; 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_COMPAT_FUNCS *cf; 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_EXTERN_FUNCS *ef; 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_AUX *aux = it->funcs; 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_aux_cb *asn1_cb = 0; 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (aux && aux->asn1_cb) 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_cb = aux->asn1_cb; 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley switch(it->itype) 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_PRIMITIVE: 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (it->templates) 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_template_ex_i2d(pval, out, it->templates, 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tag, aclass); 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_i2d_ex_primitive(pval, out, it, tag, aclass); 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_MSTRING: 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_CHOICE: 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = asn1_get_choice_selector(pval, it); 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((i >= 0) && (i < it->tcount)) 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE **pchval; 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *chtt; 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley chtt = it->templates + i; 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pchval = asn1_get_field_ptr(pval, chtt); 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_template_ex_i2d(pchval, out, chtt, 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley -1, aclass); 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Fixme: error condition if selector out of range */ 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_EXTERN: 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If new style i2d it does all the work */ 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ef = it->funcs; 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ef->asn1_ex_i2d(pval, out, it, tag, aclass); 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_COMPAT: 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* old style hackery... */ 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cf = it->funcs; 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out) 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *out; 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = cf->asn1_i2d(*pval, out); 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Fixup for IMPLICIT tag: note this messes up for tags > 30, 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * but so did the old code. Tags > 30 are very rare anyway. 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out && (tag != -1)) 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED); 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return i; 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_NDEF_SEQUENCE: 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Use indefinite length constructed if requested */ 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (aclass & ASN1_TFLG_NDEF) ndef = 2; 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* fall through */ 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case ASN1_ITYPE_SEQUENCE: 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = asn1_enc_restore(&seqcontlen, out, pval, it); 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* An error occurred */ 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i < 0) 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We have a valid cached encoding... */ 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i > 0) 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return seqcontlen; 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Otherwise carry on */ 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seqcontlen = 0; 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ 20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tag == -1) 20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tag = V_ASN1_SEQUENCE; 21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Retain any other flags in aclass */ 21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) 21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley | V_ASN1_UNIVERSAL; 21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) 21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* First work out sequence content length */ 21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *seqtt; 22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE **pseqval; 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seqtt = asn1_do_adb(pval, tt, 1); 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!seqtt) 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pseqval = asn1_get_field_ptr(pval, seqtt); 22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* FIXME: check for errors in enhanced version */ 22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt, 22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley -1, aclass); 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seqlen = ASN1_object_size(ndef, seqcontlen, tag); 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!out) 23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return seqlen; 23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Output SEQUENCE header */ 23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_object(out, ndef, seqcontlen, tag, aclass); 23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) 23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *seqtt; 23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE **pseqval; 24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seqtt = asn1_do_adb(pval, tt, 1); 24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!seqtt) 24295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 24395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pseqval = asn1_get_field_ptr(pval, seqtt); 24495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* FIXME: check for errors in enhanced version */ 24595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); 24695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 24795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ndef == 2) 24895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_eoc(out); 24995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) 25095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 25195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return seqlen; 25295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley default: 25495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 25595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 25695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 25895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 25995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, 26195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *tt) 26295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 26395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return asn1_template_ex_i2d(pval, out, tt, -1, 0); 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, 26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_TEMPLATE *tt, int tag, int iclass) 26895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 26995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i, ret, flags, ttag, tclass, ndef; 27095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t j; 27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley flags = tt->flags; 27295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Work out tag and class to use: tagging may come 27395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * either from the template or the arguments, not both 27495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * because this would create ambiguity. Additionally 27595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the iclass argument may contain some additional flags 27695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * which should be noted and passed down to other levels. 27795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 27895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_TAG_MASK) 27995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 28095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Error if argument and template tagging */ 28195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tag != -1) 28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* FIXME: error code here */ 28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Get tagging from template */ 28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ttag = tt->tag; 28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tclass = flags & ASN1_TFLG_TAG_CLASS; 28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (tag != -1) 28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* No template tagging, get from arguments */ 29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ttag = tag; 29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tclass = iclass & ASN1_TFLG_TAG_CLASS; 29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ttag = -1; 29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tclass = 0; 29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* 30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Remove any class mask from iflag. 30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 30295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley iclass &= ~ASN1_TFLG_TAG_CLASS; 30395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* At this point 'ttag' contains the outer tag to use, 30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 'tclass' is the class and iclass is any flags passed 30695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * to this function. 30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* if template and arguments require ndef, use it */ 31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF)) 31195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ndef = 2; 31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else ndef = 1; 31395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 31495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_SK_MASK) 31595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 31695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* SET OF, SEQUENCE OF */ 31795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; 31895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int isset, sktag, skaclass; 31995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int skcontlen, sklen; 32095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE *skitem; 32195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 32295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*pval) 32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_SET_OF) 32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley isset = 1; 32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* 2 means we reorder */ 32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_SEQUENCE_OF) 33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley isset = 2; 33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else isset = 0; 33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Work out inner tag value: if EXPLICIT 33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * or no tagging use underlying type. 33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) 33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sktag = ttag; 34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skaclass = tclass; 34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skaclass = V_ASN1_UNIVERSAL; 34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (isset) 34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sktag = V_ASN1_SET; 34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else sktag = V_ASN1_SEQUENCE; 34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Determine total length of items */ 35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skcontlen = 0; 35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) 35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skitem = sk_ASN1_VALUE_value(sk, j); 35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skcontlen += ASN1_item_ex_i2d(&skitem, NULL, 35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_ITEM_ptr(tt->item), 35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley -1, iclass); 35895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sklen = ASN1_object_size(ndef, skcontlen, sktag); 36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If EXPLICIT need length of surrounding tag */ 36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_EXPTAG) 36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = ASN1_object_size(ndef, sklen, ttag); 36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else ret = sklen; 36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!out) 36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Now encode this lot... */ 36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* EXPLICIT tag */ 37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_EXPTAG) 37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_object(out, ndef, sklen, ttag, tclass); 37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* SET or SEQUENCE and IMPLICIT tag */ 37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_object(out, ndef, skcontlen, sktag, skaclass); 37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* And the stuff itself */ 37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), 37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley isset, iclass); 37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ndef == 2) 37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_eoc(out); 38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_EXPTAG) 38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_eoc(out); 38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (flags & ASN1_TFLG_EXPTAG) 38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* EXPLICIT tagging */ 39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Find length of tagged item */ 39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), 39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley -1, iclass); 39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!i) 39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Find length of EXPLICIT tag */ 39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = ASN1_object_size(ndef, i, ttag); 39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out) 39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Output tag and item */ 40095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_object(out, ndef, i, ttag, tclass); 40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), 40295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley -1, iclass); 40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ndef == 2) 40495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_eoc(out); 40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 40895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Either normal or IMPLICIT tagging: combine class and flags */ 41095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), 41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ttag, tclass | iclass); 41295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 41495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Temporary structure used to hold DER encoding of items for SET OF */ 41695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleytypedef struct { 41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char *data; 41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int length; 42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE *field; 42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} DER_ENC; 42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int der_cmp(const void *a, const void *b) 42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 42595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const DER_ENC *d1 = a, *d2 = b; 42695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int cmplen, i; 42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cmplen = (d1->length < d2->length) ? d1->length : d2->length; 42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = memcmp(d1->data, d2->data, cmplen); 42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i) 43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return i; 43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return d1->length - d2->length; 43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Output the content octets of SET OF or SEQUENCE OF */ 43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, 43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int skcontlen, const ASN1_ITEM *item, 43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int do_sort, int iclass) 43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 44095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t i; 44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_VALUE *skitem; 44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char *tmpdat = NULL, *p = NULL; 44395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DER_ENC *derlst = NULL, *tder; 44495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (do_sort) 44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Don't need to sort less than 2 items */ 44795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (sk_ASN1_VALUE_num(sk) < 2) 44895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley do_sort = 0; 44995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 45095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 45195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) 45295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * sizeof(*derlst)); 4537893c008e673bd157b698ac5ebd6e43ce8cce409Adam Langley if (!derlst) 4547893c008e673bd157b698ac5ebd6e43ce8cce409Adam Langley return 0; 45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tmpdat = OPENSSL_malloc(skcontlen); 4567893c008e673bd157b698ac5ebd6e43ce8cce409Adam Langley if (!tmpdat) 4577893c008e673bd157b698ac5ebd6e43ce8cce409Adam Langley { 4587893c008e673bd157b698ac5ebd6e43ce8cce409Adam Langley OPENSSL_free(derlst); 45995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 4607893c008e673bd157b698ac5ebd6e43ce8cce409Adam Langley } 46195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 46295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 46395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If not sorting just output each item */ 46495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!do_sort) 46595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 46695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) 46795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 46895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skitem = sk_ASN1_VALUE_value(sk, i); 46995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_item_ex_i2d(&skitem, out, item, -1, iclass); 47095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 47295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 47395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = tmpdat; 47495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 47595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Doing sort: build up a list of each member's DER encoding */ 47695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) 47795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 47895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley skitem = sk_ASN1_VALUE_value(sk, i); 47995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tder->data = p; 48095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass); 48195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tder->field = skitem; 48295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 48395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 48495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Now sort them */ 48595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); 48695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Output sorted DER encoding */ 48795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p = *out; 48895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) 48995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 49095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(p, tder->data, tder->length); 49195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley p += tder->length; 49295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 49395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out = p; 49495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If do_sort is 2 then reorder the STACK */ 49595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (do_sort == 2) 49695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 49795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); 49895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i++, tder++) 49995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (void)sk_ASN1_VALUE_set(sk, i, tder->field); 50095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 50195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(derlst); 50295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(tmpdat); 50395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 50495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 50595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 50695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, 50795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_ITEM *it, int tag, int aclass) 50895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 50995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int len; 51095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int utype; 51195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int usetag; 51295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int ndef = 0; 51395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 51495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley utype = it->utype; 51595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 51695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Get length of content octets and maybe find 51795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * out the underlying type. 51895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 51995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 52095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = asn1_ex_i2c(pval, NULL, &utype, it); 52195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 52295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If SEQUENCE, SET or OTHER then header is 52395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included in pseudo content octets so don't 52495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * include tag+length. We need to check here 52595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * because the call to asn1_ex_i2c() could change 52695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * utype. 52795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 52895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || 52995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley (utype == V_ASN1_OTHER)) 53095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley usetag = 0; 53195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else usetag = 1; 53295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 53395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* -1 means omit type */ 53495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 53595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (len == -1) 53695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 53795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 53895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* -2 return is special meaning use ndef */ 53995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (len == -2) 54095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 54195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ndef = 2; 54295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = 0; 54395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 54495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 54595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If not implicitly tagged get tag from underlying type */ 54695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tag == -1) tag = utype; 54795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 54895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Output tag+length followed by content octets */ 54995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (out) 55095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 55195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (usetag) 55295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_object(out, ndef, len, tag, aclass); 55395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley asn1_ex_i2c(pval, *out, &utype, it); 55495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ndef) 55595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_put_eoc(out); 55695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else 55795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out += len; 55895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 55995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (usetag) 56195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ASN1_object_size(ndef, len, tag); 56295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return len; 56395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 56495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Produce content octets from a structure */ 56695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 56795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, 56895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_ITEM *it) 56995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 57095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_BOOLEAN *tbool = NULL; 57195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_STRING *strtmp; 57295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_OBJECT *otmp; 57395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int utype; 57495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const unsigned char *cont; 57595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned char c; 57695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int len; 57795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const ASN1_PRIMITIVE_FUNCS *pf; 57895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pf = it->funcs; 57995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (pf && pf->prim_i2c) 58095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return pf->prim_i2c(pval, cout, putype, it); 58195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 58295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Should type be omitted? */ 58395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((it->itype != ASN1_ITYPE_PRIMITIVE) 58495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley || (it->utype != V_ASN1_BOOLEAN)) 58595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 58695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*pval) return -1; 58795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 58895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 58995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (it->itype == ASN1_ITYPE_MSTRING) 59095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 59195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If MSTRING type set the underlying type */ 59295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley strtmp = (ASN1_STRING *)*pval; 59395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley utype = strtmp->type; 59495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *putype = utype; 59595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 59695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else if (it->utype == V_ASN1_ANY) 59795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 59895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If ANY set type and pointer to value */ 59995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ASN1_TYPE *typ; 60095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley typ = (ASN1_TYPE *)*pval; 60195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley utype = typ->type; 60295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *putype = utype; 60395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pval = &typ->value.asn1_value; 60495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 60595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley else utype = *putype; 60695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 60795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley switch(utype) 60895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 60995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_OBJECT: 61095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley otmp = (ASN1_OBJECT *)*pval; 61195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cont = otmp->data; 61295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = otmp->length; 61395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 61495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 61595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_NULL: 61695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cont = NULL; 61795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = 0; 61895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 61995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 62095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_BOOLEAN: 62195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tbool = (ASN1_BOOLEAN *)pval; 62295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (*tbool == -1) 62395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 62495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (it->utype != V_ASN1_ANY) 62595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 62695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Default handling if value == size field then omit */ 62795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (*tbool && (it->size > 0)) 62895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 62995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!*tbool && !it->size) 63095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 63195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 63295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley c = (unsigned char)*tbool; 63395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cont = &c; 63495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = 1; 63595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 63695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 63795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_BIT_STRING: 63895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, 63995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cout ? &cout : NULL); 64095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 64195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 64295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_INTEGER: 64395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_NEG_INTEGER: 64495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_ENUMERATED: 64595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_NEG_ENUMERATED: 64695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* These are all have the same content format 64795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as ASN1_INTEGER 64895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 64995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, 65095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cout ? &cout : NULL); 65195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 65295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 65395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_OCTET_STRING: 65495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_NUMERICSTRING: 65595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_PRINTABLESTRING: 65695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_T61STRING: 65795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_VIDEOTEXSTRING: 65895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_IA5STRING: 65995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_UTCTIME: 66095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_GENERALIZEDTIME: 66195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_GRAPHICSTRING: 66295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_VISIBLESTRING: 66395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_GENERALSTRING: 66495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_UNIVERSALSTRING: 66595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_BMPSTRING: 66695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_UTF8STRING: 66795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_SEQUENCE: 66895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley case V_ASN1_SET: 66995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley default: 67095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* All based on ASN1_STRING and handled the same */ 67195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley strtmp = (ASN1_STRING *)*pval; 67295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Special handling for NDEF */ 67395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((it->size == ASN1_TFLG_NDEF) 67495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) 67595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 67695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (cout) 67795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley { 67895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley strtmp->data = cout; 67995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley strtmp->length = 0; 68095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 68195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Special return code */ 68295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -2; 68395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 68495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley cont = strtmp->data; 68595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len = strtmp->length; 68695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 68795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 68895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 68995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 69095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (cout && len) 69195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(cout, cont, len); 69295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return len; 69395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 694