LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/asn1 - a_object.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 52 179 29.1 %
Date: 2015-10-10 Functions: 3 9 33.3 %

          Line data    Source code
       1             : /* crypto/asn1/a_object.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 <limits.h>
      61             : #include "cryptlib.h"
      62             : #include <openssl/buffer.h>
      63             : #include <openssl/asn1.h>
      64             : #include <openssl/objects.h>
      65             : #include <openssl/bn.h>
      66             : 
      67           0 : int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
      68             : {
      69             :     unsigned char *p;
      70             :     int objsize;
      71             : 
      72           0 :     if ((a == NULL) || (a->data == NULL))
      73             :         return (0);
      74             : 
      75           0 :     objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
      76           0 :     if (pp == NULL)
      77             :         return objsize;
      78             : 
      79           0 :     p = *pp;
      80           0 :     ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
      81           0 :     memcpy(p, a->data, a->length);
      82           0 :     p += a->length;
      83             : 
      84           0 :     *pp = p;
      85           0 :     return (objsize);
      86             : }
      87             : 
      88           0 : int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
      89             : {
      90             :     int i, first, len = 0, c, use_bn;
      91             :     char ftmp[24], *tmp = ftmp;
      92             :     int tmpsize = sizeof ftmp;
      93             :     const char *p;
      94             :     unsigned long l;
      95             :     BIGNUM *bl = NULL;
      96             : 
      97           0 :     if (num == 0)
      98             :         return (0);
      99           0 :     else if (num == -1)
     100           0 :         num = strlen(buf);
     101             : 
     102             :     p = buf;
     103           0 :     c = *(p++);
     104           0 :     num--;
     105           0 :     if ((c >= '0') && (c <= '2')) {
     106           0 :         first = c - '0';
     107             :     } else {
     108           0 :         ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
     109           0 :         goto err;
     110             :     }
     111             : 
     112           0 :     if (num <= 0) {
     113           0 :         ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
     114           0 :         goto err;
     115             :     }
     116           0 :     c = *(p++);
     117           0 :     num--;
     118             :     for (;;) {
     119           0 :         if (num <= 0)
     120             :             break;
     121           0 :         if ((c != '.') && (c != ' ')) {
     122           0 :             ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
     123           0 :             goto err;
     124             :         }
     125             :         l = 0;
     126             :         use_bn = 0;
     127             :         for (;;) {
     128           0 :             if (num <= 0)
     129             :                 break;
     130           0 :             num--;
     131           0 :             c = *(p++);
     132           0 :             if ((c == ' ') || (c == '.'))
     133             :                 break;
     134           0 :             if ((c < '0') || (c > '9')) {
     135           0 :                 ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
     136           0 :                 goto err;
     137             :             }
     138           0 :             if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
     139             :                 use_bn = 1;
     140           0 :                 if (!bl)
     141           0 :                     bl = BN_new();
     142           0 :                 if (!bl || !BN_set_word(bl, l))
     143             :                     goto err;
     144             :             }
     145           0 :             if (use_bn) {
     146           0 :                 if (!BN_mul_word(bl, 10L)
     147           0 :                     || !BN_add_word(bl, c - '0'))
     148             :                     goto err;
     149             :             } else
     150           0 :                 l = l * 10L + (long)(c - '0');
     151             :         }
     152           0 :         if (len == 0) {
     153           0 :             if ((first < 2) && (l >= 40)) {
     154           0 :                 ASN1err(ASN1_F_A2D_ASN1_OBJECT,
     155             :                         ASN1_R_SECOND_NUMBER_TOO_LARGE);
     156           0 :                 goto err;
     157             :             }
     158           0 :             if (use_bn) {
     159           0 :                 if (!BN_add_word(bl, first * 40))
     160             :                     goto err;
     161             :             } else
     162           0 :                 l += (long)first *40;
     163             :         }
     164             :         i = 0;
     165           0 :         if (use_bn) {
     166             :             int blsize;
     167           0 :             blsize = BN_num_bits(bl);
     168           0 :             blsize = (blsize + 6) / 7;
     169           0 :             if (blsize > tmpsize) {
     170           0 :                 if (tmp != ftmp)
     171           0 :                     OPENSSL_free(tmp);
     172           0 :                 tmpsize = blsize + 32;
     173           0 :                 tmp = OPENSSL_malloc(tmpsize);
     174           0 :                 if (!tmp)
     175             :                     goto err;
     176             :             }
     177           0 :             while (blsize--)
     178           0 :                 tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
     179             :         } else {
     180             : 
     181             :             for (;;) {
     182           0 :                 tmp[i++] = (unsigned char)l & 0x7f;
     183           0 :                 l >>= 7L;
     184           0 :                 if (l == 0L)
     185             :                     break;
     186             :             }
     187             : 
     188             :         }
     189           0 :         if (out != NULL) {
     190           0 :             if (len + i > olen) {
     191           0 :                 ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
     192           0 :                 goto err;
     193             :             }
     194           0 :             while (--i > 0)
     195           0 :                 out[len++] = tmp[i] | 0x80;
     196           0 :             out[len++] = tmp[0];
     197             :         } else
     198           0 :             len += i;
     199             :     }
     200           0 :     if (tmp != ftmp)
     201           0 :         OPENSSL_free(tmp);
     202           0 :     if (bl)
     203           0 :         BN_free(bl);
     204           0 :     return (len);
     205             :  err:
     206           0 :     if (tmp != ftmp)
     207           0 :         OPENSSL_free(tmp);
     208           0 :     if (bl)
     209           0 :         BN_free(bl);
     210             :     return (0);
     211             : }
     212             : 
     213           0 : int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
     214             : {
     215           0 :     return OBJ_obj2txt(buf, buf_len, a, 0);
     216             : }
     217             : 
     218           0 : int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
     219             : {
     220             :     char buf[80], *p = buf;
     221             :     int i;
     222             : 
     223           0 :     if ((a == NULL) || (a->data == NULL))
     224           0 :         return (BIO_write(bp, "NULL", 4));
     225             :     i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
     226           0 :     if (i > (int)(sizeof(buf) - 1)) {
     227           0 :         p = OPENSSL_malloc(i + 1);
     228           0 :         if (!p)
     229             :             return -1;
     230             :         i2t_ASN1_OBJECT(p, i + 1, a);
     231             :     }
     232           0 :     if (i <= 0)
     233           0 :         return BIO_write(bp, "<INVALID>", 9);
     234           0 :     BIO_write(bp, p, i);
     235           0 :     if (p != buf)
     236           0 :         OPENSSL_free(p);
     237           0 :     return (i);
     238             : }
     239             : 
     240           0 : ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
     241             :                              long length)
     242             : {
     243             :     const unsigned char *p;
     244             :     long len;
     245             :     int tag, xclass;
     246             :     int inf, i;
     247             :     ASN1_OBJECT *ret = NULL;
     248           0 :     p = *pp;
     249           0 :     inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
     250           0 :     if (inf & 0x80) {
     251             :         i = ASN1_R_BAD_OBJECT_HEADER;
     252             :         goto err;
     253             :     }
     254             : 
     255           0 :     if (tag != V_ASN1_OBJECT) {
     256             :         i = ASN1_R_EXPECTING_AN_OBJECT;
     257             :         goto err;
     258             :     }
     259           0 :     ret = c2i_ASN1_OBJECT(a, &p, len);
     260           0 :     if (ret)
     261           0 :         *pp = p;
     262           0 :     return ret;
     263             :  err:
     264           0 :     ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
     265           0 :     return (NULL);
     266             : }
     267             : 
     268       24230 : ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
     269             :                              long len)
     270             : {
     271             :     ASN1_OBJECT *ret = NULL;
     272             :     const unsigned char *p;
     273             :     unsigned char *data;
     274             :     int i, length;
     275             : 
     276             :     /*
     277             :      * Sanity check OID encoding. Need at least one content octet. MSB must
     278             :      * be clear in the last octet. can't have leading 0x80 in subidentifiers,
     279             :      * see: X.690 8.19.2
     280             :      */
     281       48460 :     if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
     282       24230 :         p[len - 1] & 0x80) {
     283           0 :         ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
     284           0 :         return NULL;
     285             :     }
     286             :     /* Now 0 < len <= INT_MAX, so the cast is safe. */
     287       24230 :     length = (int)len;
     288      130240 :     for (i = 0; i < length; i++, p++) {
     289      106010 :         if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
     290           0 :             ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
     291           0 :             return NULL;
     292             :         }
     293             :     }
     294             : 
     295             :     /*
     296             :      * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
     297             :      * ->ln
     298             :      */
     299       48460 :     if ((a == NULL) || ((*a) == NULL) ||
     300       24230 :         !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
     301       24230 :         if ((ret = ASN1_OBJECT_new()) == NULL)
     302             :             return (NULL);
     303             :     } else
     304             :         ret = (*a);
     305             : 
     306       24230 :     p = *pp;
     307             :     /* detach data from object */
     308       24230 :     data = (unsigned char *)ret->data;
     309       24230 :     ret->data = NULL;
     310             :     /* once detached we can change it */
     311       24230 :     if ((data == NULL) || (ret->length < length)) {
     312       24230 :         ret->length = 0;
     313       24230 :         if (data != NULL)
     314           0 :             OPENSSL_free(data);
     315       24230 :         data = (unsigned char *)OPENSSL_malloc(length);
     316       24230 :         if (data == NULL) {
     317             :             i = ERR_R_MALLOC_FAILURE;
     318             :             goto err;
     319             :         }
     320       24230 :         ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
     321             :     }
     322       24230 :     memcpy(data, p, length);
     323             :     /* reattach data to object, after which it remains const */
     324       24230 :     ret->data = data;
     325       24230 :     ret->length = length;
     326       24230 :     ret->sn = NULL;
     327       24230 :     ret->ln = NULL;
     328             :     /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
     329       24230 :     p += length;
     330             : 
     331       24230 :     if (a != NULL)
     332       24230 :         (*a) = ret;
     333       24230 :     *pp = p;
     334       24230 :     return (ret);
     335             :  err:
     336           0 :     ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
     337           0 :     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
     338           0 :         ASN1_OBJECT_free(ret);
     339             :     return (NULL);
     340             : }
     341             : 
     342       38922 : ASN1_OBJECT *ASN1_OBJECT_new(void)
     343             : {
     344             :     ASN1_OBJECT *ret;
     345             : 
     346       38922 :     ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
     347       38922 :     if (ret == NULL) {
     348           0 :         ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
     349           0 :         return (NULL);
     350             :     }
     351       38922 :     ret->length = 0;
     352       38922 :     ret->data = NULL;
     353       38922 :     ret->nid = 0;
     354       38922 :     ret->sn = NULL;
     355       38922 :     ret->ln = NULL;
     356       38922 :     ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
     357       38922 :     return (ret);
     358             : }
     359             : 
     360       38920 : void ASN1_OBJECT_free(ASN1_OBJECT *a)
     361             : {
     362       38920 :     if (a == NULL)
     363       38922 :         return;
     364       38919 :     if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
     365             : #ifndef CONST_STRICT            /* disable purely for compile-time strict
     366             :                                  * const checking. Doing this on a "real"
     367             :                                  * compile will cause memory leaks */
     368       14692 :         if (a->sn != NULL)
     369           0 :             OPENSSL_free((void *)a->sn);
     370       14692 :         if (a->ln != NULL)
     371           0 :             OPENSSL_free((void *)a->ln);
     372             : #endif
     373       14692 :         a->sn = a->ln = NULL;
     374             :     }
     375       38919 :     if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
     376       38919 :         if (a->data != NULL)
     377       38919 :             OPENSSL_free((void *)a->data);
     378       38921 :         a->data = NULL;
     379       38921 :         a->length = 0;
     380             :     }
     381       38921 :     if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
     382       38921 :         OPENSSL_free(a);
     383             : }
     384             : 
     385           0 : ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
     386             :                                 const char *sn, const char *ln)
     387             : {
     388             :     ASN1_OBJECT o;
     389             : 
     390           0 :     o.sn = sn;
     391           0 :     o.ln = ln;
     392           0 :     o.data = data;
     393           0 :     o.nid = nid;
     394           0 :     o.length = len;
     395           0 :     o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
     396             :         ASN1_OBJECT_FLAG_DYNAMIC_DATA;
     397           0 :     return (OBJ_dup(&o));
     398             : }
     399             : 
     400             : IMPLEMENT_STACK_OF(ASN1_OBJECT)
     401             : 
     402             : IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)

Generated by: LCOV version 1.10