"Fossies" - the Fresh Open Source Software Archive

Member "openssl-1.0.2q/crypto/asn1/a_bytes.c" (20 Nov 2018, 10127 Bytes) of package /linux/misc/openssl-1.0.2q.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "a_bytes.c" see the Fossies "Dox" file reference documentation.

    1 /* crypto/asn1/a_bytes.c */
    2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
    3  * All rights reserved.
    4  *
    5  * This package is an SSL implementation written
    6  * by Eric Young (eay@cryptsoft.com).
    7  * The implementation was written so as to conform with Netscapes SSL.
    8  *
    9  * This library is free for commercial and non-commercial use as long as
   10  * the following conditions are aheared to.  The following conditions
   11  * apply to all code found in this distribution, be it the RC4, RSA,
   12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
   13  * included with this distribution is covered by the same copyright terms
   14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
   15  *
   16  * Copyright remains Eric Young's, and as such any Copyright notices in
   17  * the code are not to be removed.
   18  * If this package is used in a product, Eric Young should be given attribution
   19  * as the author of the parts of the library used.
   20  * This can be in the form of a textual message at program startup or
   21  * in documentation (online or textual) provided with the package.
   22  *
   23  * Redistribution and use in source and binary forms, with or without
   24  * modification, are permitted provided that the following conditions
   25  * are met:
   26  * 1. Redistributions of source code must retain the copyright
   27  *    notice, this list of conditions and the following disclaimer.
   28  * 2. Redistributions in binary form must reproduce the above copyright
   29  *    notice, this list of conditions and the following disclaimer in the
   30  *    documentation and/or other materials provided with the distribution.
   31  * 3. All advertising materials mentioning features or use of this software
   32  *    must display the following acknowledgement:
   33  *    "This product includes cryptographic software written by
   34  *     Eric Young (eay@cryptsoft.com)"
   35  *    The word 'cryptographic' can be left out if the rouines from the library
   36  *    being used are not cryptographic related :-).
   37  * 4. If you include any Windows specific code (or a derivative thereof) from
   38  *    the apps directory (application code) you must include an acknowledgement:
   39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
   40  *
   41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
   42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   51  * SUCH DAMAGE.
   52  *
   53  * The licence and distribution terms for any publically available version or
   54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
   55  * copied and put under another distribution licence
   56  * [including the GNU Public Licence.]
   57  */
   58 
   59 #include <stdio.h>
   60 #include "cryptlib.h"
   61 #include <openssl/asn1.h>
   62 
   63 static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c,
   64                                   int depth);
   65 static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a,
   66                                        const unsigned char **pp, long length,
   67                                        int Ptag, int Pclass, int depth,
   68                                        int *perr);
   69 /*
   70  * type is a 'bitmap' of acceptable string types.
   71  */
   72 ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
   73                                  long length, int type)
   74 {
   75     ASN1_STRING *ret = NULL;
   76     const unsigned char *p;
   77     unsigned char *s;
   78     long len;
   79     int inf, tag, xclass;
   80     int i = 0;
   81 
   82     p = *pp;
   83     inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
   84     if (inf & 0x80)
   85         goto err;
   86 
   87     if (tag >= 32) {
   88         i = ASN1_R_TAG_VALUE_TOO_HIGH;
   89         goto err;
   90     }
   91     if (!(ASN1_tag2bit(tag) & type)) {
   92         i = ASN1_R_WRONG_TYPE;
   93         goto err;
   94     }
   95 
   96     /* If a bit-string, exit early */
   97     if (tag == V_ASN1_BIT_STRING)
   98         return (d2i_ASN1_BIT_STRING(a, pp, length));
   99 
  100     if ((a == NULL) || ((*a) == NULL)) {
  101         if ((ret = ASN1_STRING_new()) == NULL)
  102             return (NULL);
  103     } else
  104         ret = (*a);
  105 
  106     if (len != 0) {
  107         s = OPENSSL_malloc((int)len + 1);
  108         if (s == NULL) {
  109             i = ERR_R_MALLOC_FAILURE;
  110             goto err;
  111         }
  112         memcpy(s, p, (int)len);
  113         s[len] = '\0';
  114         p += len;
  115     } else
  116         s = NULL;
  117 
  118     if (ret->data != NULL)
  119         OPENSSL_free(ret->data);
  120     ret->length = (int)len;
  121     ret->data = s;
  122     ret->type = tag;
  123     if (a != NULL)
  124         (*a) = ret;
  125     *pp = p;
  126     return (ret);
  127  err:
  128     ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES, i);
  129     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
  130         ASN1_STRING_free(ret);
  131     return (NULL);
  132 }
  133 
  134 int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
  135 {
  136     int ret, r, constructed;
  137     unsigned char *p;
  138 
  139     if (a == NULL)
  140         return (0);
  141 
  142     if (tag == V_ASN1_BIT_STRING)
  143         return (i2d_ASN1_BIT_STRING(a, pp));
  144 
  145     ret = a->length;
  146     r = ASN1_object_size(0, ret, tag);
  147     if (pp == NULL)
  148         return (r);
  149     p = *pp;
  150 
  151     if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
  152         constructed = 1;
  153     else
  154         constructed = 0;
  155     ASN1_put_object(&p, constructed, ret, tag, xclass);
  156     memcpy(p, a->data, a->length);
  157     p += a->length;
  158     *pp = p;
  159     return (r);
  160 }
  161 
  162 /*
  163  * Maximum recursion depth of d2i_ASN1_bytes(): much more than should be
  164  * encountered in pratice.
  165  */
  166 
  167 #define ASN1_BYTES_MAXDEPTH 20
  168 
  169 ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
  170                             long length, int Ptag, int Pclass)
  171 {
  172     int err = 0;
  173     ASN1_STRING *s = int_d2i_ASN1_bytes(a, pp, length, Ptag, Pclass, 0, &err);
  174     if (err != 0)
  175         ASN1err(ASN1_F_D2I_ASN1_BYTES, err);
  176     return s;
  177 }
  178 
  179 static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a,
  180                                        const unsigned char **pp, long length,
  181                                        int Ptag, int Pclass,
  182                                        int depth, int *perr)
  183 {
  184     ASN1_STRING *ret = NULL;
  185     const unsigned char *p;
  186     unsigned char *s;
  187     long len;
  188     int inf, tag, xclass;
  189 
  190     if (depth > ASN1_BYTES_MAXDEPTH) {
  191         *perr = ASN1_R_NESTED_ASN1_STRING;
  192         return NULL;
  193     }
  194 
  195     if ((a == NULL) || ((*a) == NULL)) {
  196         if ((ret = ASN1_STRING_new()) == NULL)
  197             return (NULL);
  198     } else
  199         ret = (*a);
  200 
  201     p = *pp;
  202     inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
  203     if (inf & 0x80) {
  204         *perr = ASN1_R_BAD_OBJECT_HEADER;
  205         goto err;
  206     }
  207 
  208     if (tag != Ptag) {
  209         *perr = ASN1_R_WRONG_TAG;
  210         goto err;
  211     }
  212 
  213     if (inf & V_ASN1_CONSTRUCTED) {
  214         ASN1_const_CTX c;
  215 
  216         c.error = 0;
  217         c.pp = pp;
  218         c.p = p;
  219         c.inf = inf;
  220         c.slen = len;
  221         c.tag = Ptag;
  222         c.xclass = Pclass;
  223         c.max = (length == 0) ? 0 : (p + length);
  224         if (!asn1_collate_primitive(ret, &c, depth)) {
  225             *perr = c.error;
  226             goto err;
  227         } else {
  228             p = c.p;
  229         }
  230     } else {
  231         if (len != 0) {
  232             if ((ret->length < len) || (ret->data == NULL)) {
  233                 s = OPENSSL_malloc((int)len + 1);
  234                 if (s == NULL) {
  235                     *perr = ERR_R_MALLOC_FAILURE;
  236                     goto err;
  237                 }
  238                 if (ret->data != NULL)
  239                     OPENSSL_free(ret->data);
  240             } else
  241                 s = ret->data;
  242             memcpy(s, p, (int)len);
  243             s[len] = '\0';
  244             p += len;
  245         } else {
  246             s = NULL;
  247             if (ret->data != NULL)
  248                 OPENSSL_free(ret->data);
  249         }
  250 
  251         ret->length = (int)len;
  252         ret->data = s;
  253         ret->type = Ptag;
  254     }
  255 
  256     if (a != NULL)
  257         (*a) = ret;
  258     *pp = p;
  259     return (ret);
  260  err:
  261     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
  262         ASN1_STRING_free(ret);
  263     return (NULL);
  264 }
  265 
  266 /*
  267  * We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them
  268  * into the one structure that is then returned
  269  */
  270 /*
  271  * There have been a few bug fixes for this function from Paul Keogh
  272  * <paul.keogh@sse.ie>, many thanks to him
  273  */
  274 static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c,
  275                                   int depth)
  276 {
  277     ASN1_STRING *os = NULL;
  278     BUF_MEM b;
  279     int num;
  280 
  281     b.length = 0;
  282     b.max = 0;
  283     b.data = NULL;
  284 
  285     if (a == NULL) {
  286         c->error = ERR_R_PASSED_NULL_PARAMETER;
  287         goto err;
  288     }
  289 
  290     num = 0;
  291     for (;;) {
  292         if (c->inf & 1) {
  293             c->eos = ASN1_const_check_infinite_end(&c->p,
  294                                                    (long)(c->max - c->p));
  295             if (c->eos)
  296                 break;
  297         } else {
  298             if (c->slen <= 0)
  299                 break;
  300         }
  301 
  302         c->q = c->p;
  303         if (int_d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass,
  304                                depth + 1, &c->error) == NULL) {
  305             goto err;
  306         }
  307 
  308         if (!BUF_MEM_grow_clean(&b, num + os->length)) {
  309             c->error = ERR_R_BUF_LIB;
  310             goto err;
  311         }
  312         memcpy(&(b.data[num]), os->data, os->length);
  313         if (!(c->inf & 1))
  314             c->slen -= (c->p - c->q);
  315         num += os->length;
  316     }
  317 
  318     if (!asn1_const_Finish(c))
  319         goto err;
  320 
  321     a->length = num;
  322     if (a->data != NULL)
  323         OPENSSL_free(a->data);
  324     a->data = (unsigned char *)b.data;
  325     if (os != NULL)
  326         ASN1_STRING_free(os);
  327     return (1);
  328  err:
  329     if (os != NULL)
  330         ASN1_STRING_free(os);
  331     if (b.data != NULL)
  332         OPENSSL_free(b.data);
  333     return (0);
  334 }