Index: openssl/crypto/asn1/tasn_enc.c |
diff --git a/openssl/crypto/asn1/tasn_enc.c b/openssl/crypto/asn1/tasn_enc.c |
deleted file mode 100644 |
index 936ad1f767c686ce612378b342ac9cff00f008aa..0000000000000000000000000000000000000000 |
--- a/openssl/crypto/asn1/tasn_enc.c |
+++ /dev/null |
@@ -1,691 +0,0 @@ |
-/* tasn_enc.c */ |
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
- * project 2000. |
- */ |
-/* ==================================================================== |
- * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. |
- * |
- * Redistribution and use in source and binary forms, with or without |
- * modification, are permitted provided that the following conditions |
- * are met: |
- * |
- * 1. Redistributions of source code must retain the above copyright |
- * notice, this list of conditions and the following disclaimer. |
- * |
- * 2. Redistributions in binary form must reproduce the above copyright |
- * notice, this list of conditions and the following disclaimer in |
- * the documentation and/or other materials provided with the |
- * distribution. |
- * |
- * 3. All advertising materials mentioning features or use of this |
- * software must display the following acknowledgment: |
- * "This product includes software developed by the OpenSSL Project |
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
- * |
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
- * endorse or promote products derived from this software without |
- * prior written permission. For written permission, please contact |
- * licensing@OpenSSL.org. |
- * |
- * 5. Products derived from this software may not be called "OpenSSL" |
- * nor may "OpenSSL" appear in their names without prior written |
- * permission of the OpenSSL Project. |
- * |
- * 6. Redistributions of any form whatsoever must retain the following |
- * acknowledgment: |
- * "This product includes software developed by the OpenSSL Project |
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
- * |
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
- * OF THE POSSIBILITY OF SUCH DAMAGE. |
- * ==================================================================== |
- * |
- * This product includes cryptographic software written by Eric Young |
- * (eay@cryptsoft.com). This product includes software written by Tim |
- * Hudson (tjh@cryptsoft.com). |
- * |
- */ |
- |
- |
-#include <stddef.h> |
-#include <string.h> |
-#include "cryptlib.h" |
-#include <openssl/asn1.h> |
-#include <openssl/asn1t.h> |
-#include <openssl/objects.h> |
- |
-static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, |
- const ASN1_ITEM *it, |
- int tag, int aclass); |
-static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, |
- int skcontlen, const ASN1_ITEM *item, |
- int do_sort, int iclass); |
-static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, |
- const ASN1_TEMPLATE *tt, |
- int tag, int aclass); |
-static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, |
- const ASN1_ITEM *it, int flags); |
- |
-/* Top level i2d equivalents: the 'ndef' variant instructs the encoder |
- * to use indefinite length constructed encoding, where appropriate |
- */ |
- |
-int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, |
- const ASN1_ITEM *it) |
- { |
- return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF); |
- } |
- |
-int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) |
- { |
- return asn1_item_flags_i2d(val, out, it, 0); |
- } |
- |
-/* Encode an ASN1 item, this is use by the |
- * standard 'i2d' function. 'out' points to |
- * a buffer to output the data to. |
- * |
- * The new i2d has one additional feature. If the output |
- * buffer is NULL (i.e. *out == NULL) then a buffer is |
- * allocated and populated with the encoding. |
- */ |
- |
-static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, |
- const ASN1_ITEM *it, int flags) |
- { |
- if (out && !*out) |
- { |
- unsigned char *p, *buf; |
- int len; |
- len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); |
- if (len <= 0) |
- return len; |
- buf = OPENSSL_malloc(len); |
- if (!buf) |
- return -1; |
- p = buf; |
- ASN1_item_ex_i2d(&val, &p, it, -1, flags); |
- *out = buf; |
- return len; |
- } |
- |
- return ASN1_item_ex_i2d(&val, out, it, -1, flags); |
- } |
- |
-/* Encode an item, taking care of IMPLICIT tagging (if any). |
- * This function performs the normal item handling: it can be |
- * used in external types. |
- */ |
- |
-int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, |
- const ASN1_ITEM *it, int tag, int aclass) |
- { |
- const ASN1_TEMPLATE *tt = NULL; |
- unsigned char *p = NULL; |
- int i, seqcontlen, seqlen, ndef = 1; |
- const ASN1_COMPAT_FUNCS *cf; |
- const ASN1_EXTERN_FUNCS *ef; |
- const ASN1_AUX *aux = it->funcs; |
- ASN1_aux_cb *asn1_cb = 0; |
- |
- if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) |
- return 0; |
- |
- if (aux && aux->asn1_cb) |
- asn1_cb = aux->asn1_cb; |
- |
- switch(it->itype) |
- { |
- |
- case ASN1_ITYPE_PRIMITIVE: |
- if (it->templates) |
- return asn1_template_ex_i2d(pval, out, it->templates, |
- tag, aclass); |
- return asn1_i2d_ex_primitive(pval, out, it, tag, aclass); |
- break; |
- |
- case ASN1_ITYPE_MSTRING: |
- return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); |
- |
- case ASN1_ITYPE_CHOICE: |
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) |
- return 0; |
- i = asn1_get_choice_selector(pval, it); |
- if ((i >= 0) && (i < it->tcount)) |
- { |
- ASN1_VALUE **pchval; |
- const ASN1_TEMPLATE *chtt; |
- chtt = it->templates + i; |
- pchval = asn1_get_field_ptr(pval, chtt); |
- return asn1_template_ex_i2d(pchval, out, chtt, |
- -1, aclass); |
- } |
- /* Fixme: error condition if selector out of range */ |
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) |
- return 0; |
- break; |
- |
- case ASN1_ITYPE_EXTERN: |
- /* If new style i2d it does all the work */ |
- ef = it->funcs; |
- return ef->asn1_ex_i2d(pval, out, it, tag, aclass); |
- |
- case ASN1_ITYPE_COMPAT: |
- /* old style hackery... */ |
- cf = it->funcs; |
- if (out) |
- p = *out; |
- i = cf->asn1_i2d(*pval, out); |
- /* Fixup for IMPLICIT tag: note this messes up for tags > 30, |
- * but so did the old code. Tags > 30 are very rare anyway. |
- */ |
- if (out && (tag != -1)) |
- *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED); |
- return i; |
- |
- case ASN1_ITYPE_NDEF_SEQUENCE: |
- /* Use indefinite length constructed if requested */ |
- if (aclass & ASN1_TFLG_NDEF) ndef = 2; |
- /* fall through */ |
- |
- case ASN1_ITYPE_SEQUENCE: |
- i = asn1_enc_restore(&seqcontlen, out, pval, it); |
- /* An error occurred */ |
- if (i < 0) |
- return 0; |
- /* We have a valid cached encoding... */ |
- if (i > 0) |
- return seqcontlen; |
- /* Otherwise carry on */ |
- seqcontlen = 0; |
- /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ |
- if (tag == -1) |
- { |
- tag = V_ASN1_SEQUENCE; |
- /* Retain any other flags in aclass */ |
- aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) |
- | V_ASN1_UNIVERSAL; |
- } |
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) |
- return 0; |
- /* First work out sequence content length */ |
- for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) |
- { |
- const ASN1_TEMPLATE *seqtt; |
- ASN1_VALUE **pseqval; |
- seqtt = asn1_do_adb(pval, tt, 1); |
- if (!seqtt) |
- return 0; |
- pseqval = asn1_get_field_ptr(pval, seqtt); |
- /* FIXME: check for errors in enhanced version */ |
- seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt, |
- -1, aclass); |
- } |
- |
- seqlen = ASN1_object_size(ndef, seqcontlen, tag); |
- if (!out) |
- return seqlen; |
- /* Output SEQUENCE header */ |
- ASN1_put_object(out, ndef, seqcontlen, tag, aclass); |
- for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) |
- { |
- const ASN1_TEMPLATE *seqtt; |
- ASN1_VALUE **pseqval; |
- seqtt = asn1_do_adb(pval, tt, 1); |
- if (!seqtt) |
- return 0; |
- pseqval = asn1_get_field_ptr(pval, seqtt); |
- /* FIXME: check for errors in enhanced version */ |
- asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); |
- } |
- if (ndef == 2) |
- ASN1_put_eoc(out); |
- if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) |
- return 0; |
- return seqlen; |
- |
- default: |
- return 0; |
- |
- } |
- return 0; |
- } |
- |
-int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, |
- const ASN1_TEMPLATE *tt) |
- { |
- return asn1_template_ex_i2d(pval, out, tt, -1, 0); |
- } |
- |
-static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, |
- const ASN1_TEMPLATE *tt, int tag, int iclass) |
- { |
- int i, ret, flags, ttag, tclass, ndef; |
- flags = tt->flags; |
- /* Work out tag and class to use: tagging may come |
- * either from the template or the arguments, not both |
- * because this would create ambiguity. Additionally |
- * the iclass argument may contain some additional flags |
- * which should be noted and passed down to other levels. |
- */ |
- if (flags & ASN1_TFLG_TAG_MASK) |
- { |
- /* Error if argument and template tagging */ |
- if (tag != -1) |
- /* FIXME: error code here */ |
- return -1; |
- /* Get tagging from template */ |
- ttag = tt->tag; |
- tclass = flags & ASN1_TFLG_TAG_CLASS; |
- } |
- else if (tag != -1) |
- { |
- /* No template tagging, get from arguments */ |
- ttag = tag; |
- tclass = iclass & ASN1_TFLG_TAG_CLASS; |
- } |
- else |
- { |
- ttag = -1; |
- tclass = 0; |
- } |
- /* |
- * Remove any class mask from iflag. |
- */ |
- iclass &= ~ASN1_TFLG_TAG_CLASS; |
- |
- /* At this point 'ttag' contains the outer tag to use, |
- * 'tclass' is the class and iclass is any flags passed |
- * to this function. |
- */ |
- |
- /* if template and arguments require ndef, use it */ |
- if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF)) |
- ndef = 2; |
- else ndef = 1; |
- |
- if (flags & ASN1_TFLG_SK_MASK) |
- { |
- /* SET OF, SEQUENCE OF */ |
- STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; |
- int isset, sktag, skaclass; |
- int skcontlen, sklen; |
- ASN1_VALUE *skitem; |
- |
- if (!*pval) |
- return 0; |
- |
- if (flags & ASN1_TFLG_SET_OF) |
- { |
- isset = 1; |
- /* 2 means we reorder */ |
- if (flags & ASN1_TFLG_SEQUENCE_OF) |
- isset = 2; |
- } |
- else isset = 0; |
- |
- /* Work out inner tag value: if EXPLICIT |
- * or no tagging use underlying type. |
- */ |
- if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) |
- { |
- sktag = ttag; |
- skaclass = tclass; |
- } |
- else |
- { |
- skaclass = V_ASN1_UNIVERSAL; |
- if (isset) |
- sktag = V_ASN1_SET; |
- else sktag = V_ASN1_SEQUENCE; |
- } |
- |
- /* Determine total length of items */ |
- skcontlen = 0; |
- for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) |
- { |
- skitem = sk_ASN1_VALUE_value(sk, i); |
- skcontlen += ASN1_item_ex_i2d(&skitem, NULL, |
- ASN1_ITEM_ptr(tt->item), |
- -1, iclass); |
- } |
- sklen = ASN1_object_size(ndef, skcontlen, sktag); |
- /* If EXPLICIT need length of surrounding tag */ |
- if (flags & ASN1_TFLG_EXPTAG) |
- ret = ASN1_object_size(ndef, sklen, ttag); |
- else ret = sklen; |
- |
- if (!out) |
- return ret; |
- |
- /* Now encode this lot... */ |
- /* EXPLICIT tag */ |
- if (flags & ASN1_TFLG_EXPTAG) |
- ASN1_put_object(out, ndef, sklen, ttag, tclass); |
- /* SET or SEQUENCE and IMPLICIT tag */ |
- ASN1_put_object(out, ndef, skcontlen, sktag, skaclass); |
- /* And the stuff itself */ |
- asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), |
- isset, iclass); |
- if (ndef == 2) |
- { |
- ASN1_put_eoc(out); |
- if (flags & ASN1_TFLG_EXPTAG) |
- ASN1_put_eoc(out); |
- } |
- |
- return ret; |
- } |
- |
- if (flags & ASN1_TFLG_EXPTAG) |
- { |
- /* EXPLICIT tagging */ |
- /* Find length of tagged item */ |
- i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), |
- -1, iclass); |
- if (!i) |
- return 0; |
- /* Find length of EXPLICIT tag */ |
- ret = ASN1_object_size(ndef, i, ttag); |
- if (out) |
- { |
- /* Output tag and item */ |
- ASN1_put_object(out, ndef, i, ttag, tclass); |
- ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), |
- -1, iclass); |
- if (ndef == 2) |
- ASN1_put_eoc(out); |
- } |
- return ret; |
- } |
- |
- /* Either normal or IMPLICIT tagging: combine class and flags */ |
- return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), |
- ttag, tclass | iclass); |
- |
-} |
- |
-/* Temporary structure used to hold DER encoding of items for SET OF */ |
- |
-typedef struct { |
- unsigned char *data; |
- int length; |
- ASN1_VALUE *field; |
-} DER_ENC; |
- |
-static int der_cmp(const void *a, const void *b) |
- { |
- const DER_ENC *d1 = a, *d2 = b; |
- int cmplen, i; |
- cmplen = (d1->length < d2->length) ? d1->length : d2->length; |
- i = memcmp(d1->data, d2->data, cmplen); |
- if (i) |
- return i; |
- return d1->length - d2->length; |
- } |
- |
-/* Output the content octets of SET OF or SEQUENCE OF */ |
- |
-static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, |
- int skcontlen, const ASN1_ITEM *item, |
- int do_sort, int iclass) |
- { |
- int i; |
- ASN1_VALUE *skitem; |
- unsigned char *tmpdat = NULL, *p = NULL; |
- DER_ENC *derlst = NULL, *tder; |
- if (do_sort) |
- { |
- /* Don't need to sort less than 2 items */ |
- if (sk_ASN1_VALUE_num(sk) < 2) |
- do_sort = 0; |
- else |
- { |
- derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) |
- * sizeof(*derlst)); |
- tmpdat = OPENSSL_malloc(skcontlen); |
- if (!derlst || !tmpdat) |
- return 0; |
- } |
- } |
- /* If not sorting just output each item */ |
- if (!do_sort) |
- { |
- for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) |
- { |
- skitem = sk_ASN1_VALUE_value(sk, i); |
- ASN1_item_ex_i2d(&skitem, out, item, -1, iclass); |
- } |
- return 1; |
- } |
- p = tmpdat; |
- |
- /* Doing sort: build up a list of each member's DER encoding */ |
- for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) |
- { |
- skitem = sk_ASN1_VALUE_value(sk, i); |
- tder->data = p; |
- tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass); |
- tder->field = skitem; |
- } |
- |
- /* Now sort them */ |
- qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); |
- /* Output sorted DER encoding */ |
- p = *out; |
- for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) |
- { |
- memcpy(p, tder->data, tder->length); |
- p += tder->length; |
- } |
- *out = p; |
- /* If do_sort is 2 then reorder the STACK */ |
- if (do_sort == 2) |
- { |
- for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); |
- i++, tder++) |
- (void)sk_ASN1_VALUE_set(sk, i, tder->field); |
- } |
- OPENSSL_free(derlst); |
- OPENSSL_free(tmpdat); |
- return 1; |
- } |
- |
-static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, |
- const ASN1_ITEM *it, int tag, int aclass) |
- { |
- int len; |
- int utype; |
- int usetag; |
- int ndef = 0; |
- |
- utype = it->utype; |
- |
- /* Get length of content octets and maybe find |
- * out the underlying type. |
- */ |
- |
- len = asn1_ex_i2c(pval, NULL, &utype, it); |
- |
- /* If SEQUENCE, SET or OTHER then header is |
- * included in pseudo content octets so don't |
- * include tag+length. We need to check here |
- * because the call to asn1_ex_i2c() could change |
- * utype. |
- */ |
- if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || |
- (utype == V_ASN1_OTHER)) |
- usetag = 0; |
- else usetag = 1; |
- |
- /* -1 means omit type */ |
- |
- if (len == -1) |
- return 0; |
- |
- /* -2 return is special meaning use ndef */ |
- if (len == -2) |
- { |
- ndef = 2; |
- len = 0; |
- } |
- |
- /* If not implicitly tagged get tag from underlying type */ |
- if (tag == -1) tag = utype; |
- |
- /* Output tag+length followed by content octets */ |
- if (out) |
- { |
- if (usetag) |
- ASN1_put_object(out, ndef, len, tag, aclass); |
- asn1_ex_i2c(pval, *out, &utype, it); |
- if (ndef) |
- ASN1_put_eoc(out); |
- else |
- *out += len; |
- } |
- |
- if (usetag) |
- return ASN1_object_size(ndef, len, tag); |
- return len; |
- } |
- |
-/* Produce content octets from a structure */ |
- |
-int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, |
- const ASN1_ITEM *it) |
- { |
- ASN1_BOOLEAN *tbool = NULL; |
- ASN1_STRING *strtmp; |
- ASN1_OBJECT *otmp; |
- int utype; |
- const unsigned char *cont; |
- unsigned char c; |
- int len; |
- const ASN1_PRIMITIVE_FUNCS *pf; |
- pf = it->funcs; |
- if (pf && pf->prim_i2c) |
- return pf->prim_i2c(pval, cout, putype, it); |
- |
- /* Should type be omitted? */ |
- if ((it->itype != ASN1_ITYPE_PRIMITIVE) |
- || (it->utype != V_ASN1_BOOLEAN)) |
- { |
- if (!*pval) return -1; |
- } |
- |
- if (it->itype == ASN1_ITYPE_MSTRING) |
- { |
- /* If MSTRING type set the underlying type */ |
- strtmp = (ASN1_STRING *)*pval; |
- utype = strtmp->type; |
- *putype = utype; |
- } |
- else if (it->utype == V_ASN1_ANY) |
- { |
- /* If ANY set type and pointer to value */ |
- ASN1_TYPE *typ; |
- typ = (ASN1_TYPE *)*pval; |
- utype = typ->type; |
- *putype = utype; |
- pval = &typ->value.asn1_value; |
- } |
- else utype = *putype; |
- |
- switch(utype) |
- { |
- case V_ASN1_OBJECT: |
- otmp = (ASN1_OBJECT *)*pval; |
- cont = otmp->data; |
- len = otmp->length; |
- break; |
- |
- case V_ASN1_NULL: |
- cont = NULL; |
- len = 0; |
- break; |
- |
- case V_ASN1_BOOLEAN: |
- tbool = (ASN1_BOOLEAN *)pval; |
- if (*tbool == -1) |
- return -1; |
- if (it->utype != V_ASN1_ANY) |
- { |
- /* Default handling if value == size field then omit */ |
- if (*tbool && (it->size > 0)) |
- return -1; |
- if (!*tbool && !it->size) |
- return -1; |
- } |
- c = (unsigned char)*tbool; |
- cont = &c; |
- len = 1; |
- break; |
- |
- case V_ASN1_BIT_STRING: |
- return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, |
- cout ? &cout : NULL); |
- break; |
- |
- case V_ASN1_INTEGER: |
- case V_ASN1_NEG_INTEGER: |
- case V_ASN1_ENUMERATED: |
- case V_ASN1_NEG_ENUMERATED: |
- /* These are all have the same content format |
- * as ASN1_INTEGER |
- */ |
- return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, |
- cout ? &cout : NULL); |
- break; |
- |
- case V_ASN1_OCTET_STRING: |
- case V_ASN1_NUMERICSTRING: |
- case V_ASN1_PRINTABLESTRING: |
- case V_ASN1_T61STRING: |
- case V_ASN1_VIDEOTEXSTRING: |
- case V_ASN1_IA5STRING: |
- case V_ASN1_UTCTIME: |
- case V_ASN1_GENERALIZEDTIME: |
- case V_ASN1_GRAPHICSTRING: |
- case V_ASN1_VISIBLESTRING: |
- case V_ASN1_GENERALSTRING: |
- case V_ASN1_UNIVERSALSTRING: |
- case V_ASN1_BMPSTRING: |
- case V_ASN1_UTF8STRING: |
- case V_ASN1_SEQUENCE: |
- case V_ASN1_SET: |
- default: |
- /* All based on ASN1_STRING and handled the same */ |
- strtmp = (ASN1_STRING *)*pval; |
- /* Special handling for NDEF */ |
- if ((it->size == ASN1_TFLG_NDEF) |
- && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) |
- { |
- if (cout) |
- { |
- strtmp->data = cout; |
- strtmp->length = 0; |
- } |
- /* Special return code */ |
- return -2; |
- } |
- cont = strtmp->data; |
- len = strtmp->length; |
- |
- break; |
- |
- } |
- if (cout && len) |
- memcpy(cout, cont, len); |
- return len; |
- } |