"Fossies" - the Fresh Open Source Software Archive

Member "libressl-2.9.2/crypto/asn1/a_int.c" (13 May 2019, 12601 Bytes) of package /linux/misc/libressl-2.9.2.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_int.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 2.9.0_vs_2.9.1.

    1 /* $OpenBSD: a_int.c,v 1.33 2019/03/26 09:15:07 jsing Exp $ */
    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 <limits.h>
   60 #include <stdio.h>
   61 #include <string.h>
   62 
   63 #include <openssl/asn1.h>
   64 #include <openssl/bn.h>
   65 #include <openssl/err.h>
   66 
   67 static int
   68 ASN1_INTEGER_valid(const ASN1_INTEGER *a)
   69 {
   70     return (a != NULL && a->length >= 0);
   71 }
   72 
   73 ASN1_INTEGER *
   74 ASN1_INTEGER_dup(const ASN1_INTEGER *x)
   75 {
   76     if (!ASN1_INTEGER_valid(x))
   77         return NULL;
   78 
   79     return ASN1_STRING_dup(x);
   80 }
   81 
   82 int
   83 ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
   84 {
   85     int neg, ret;
   86 
   87     /* Compare signs */
   88     neg = x->type & V_ASN1_NEG;
   89     if (neg != (y->type & V_ASN1_NEG)) {
   90         if (neg)
   91             return -1;
   92         else
   93             return 1;
   94     }
   95 
   96     ret = ASN1_STRING_cmp(x, y);
   97 
   98     if (neg)
   99         return -ret;
  100     else
  101         return ret;
  102 }
  103 
  104 
  105 /*
  106  * This converts an ASN1 INTEGER into its content encoding.
  107  * The internal representation is an ASN1_STRING whose data is a big endian
  108  * representation of the value, ignoring the sign. The sign is determined by
  109  * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
  110  *
  111  * Positive integers are no problem: they are almost the same as the DER
  112  * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
  113  *
  114  * Negative integers are a bit trickier...
  115  * The DER representation of negative integers is in 2s complement form.
  116  * The internal form is converted by complementing each octet and finally
  117  * adding one to the result. This can be done less messily with a little trick.
  118  * If the internal form has trailing zeroes then they will become FF by the
  119  * complement and 0 by the add one (due to carry) so just copy as many trailing
  120  * zeros to the destination as there are in the source. The carry will add one
  121  * to the last none zero octet: so complement this octet and add one and finally
  122  * complement any left over until you get to the start of the string.
  123  *
  124  * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
  125  * with 0xff. However if the first byte is 0x80 and one of the following bytes
  126  * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
  127  * followed by optional zeros isn't padded.
  128  */
  129 
  130 int
  131 i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
  132 {
  133     int pad = 0, ret, i, neg;
  134     unsigned char *p, *n, pb = 0;
  135 
  136     if (!ASN1_INTEGER_valid(a))
  137         return 0;
  138 
  139     neg = a->type & V_ASN1_NEG;
  140     if (a->length == 0)
  141         ret = 1;
  142     else {
  143         ret = a->length;
  144         i = a->data[0];
  145         if (!neg && (i > 127)) {
  146             pad = 1;
  147             pb = 0;
  148         } else if (neg) {
  149             if (i > 128) {
  150                 pad = 1;
  151                 pb = 0xFF;
  152             } else if (i == 128) {
  153                 /*
  154                  * Special case: if any other bytes non zero we pad:
  155                  * otherwise we don't.
  156                  */
  157                 for (i = 1; i < a->length; i++) if (a->data[i]) {
  158                     pad = 1;
  159                     pb = 0xFF;
  160                     break;
  161                 }
  162             }
  163         }
  164         ret += pad;
  165     }
  166     if (pp == NULL)
  167         return (ret);
  168     p= *pp;
  169 
  170     if (pad)
  171         *(p++) = pb;
  172     if (a->length == 0)
  173         *(p++) = 0;
  174     else if (!neg)
  175         memcpy(p, a->data, a->length);
  176     else {
  177         /* Begin at the end of the encoding */
  178         n = a->data + a->length - 1;
  179         p += a->length - 1;
  180         i = a->length;
  181         /* Copy zeros to destination as long as source is zero */
  182         while (!*n) {
  183             *(p--) = 0;
  184             n--;
  185             i--;
  186         }
  187         /* Complement and increment next octet */
  188         *(p--) = ((*(n--)) ^ 0xff) + 1;
  189         i--;
  190         /* Complement any octets left */
  191         for (; i > 0; i--)
  192             *(p--) = *(n--) ^ 0xff;
  193     }
  194 
  195     *pp += ret;
  196     return (ret);
  197 }
  198 
  199 /* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
  200 
  201 ASN1_INTEGER *
  202 c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len)
  203 {
  204     ASN1_INTEGER *ret = NULL;
  205     const unsigned char *p, *pend;
  206     unsigned char *to, *s;
  207     int i;
  208 
  209     if ((a == NULL) || ((*a) == NULL)) {
  210         if ((ret = ASN1_INTEGER_new()) == NULL)
  211             return (NULL);
  212     } else
  213         ret = (*a);
  214 
  215     if (!ASN1_INTEGER_valid(ret)) {
  216         /*
  217          * XXX using i for an alert is confusing,
  218          * we should call this al
  219          */
  220         i = ERR_R_ASN1_LENGTH_MISMATCH;
  221         goto err;
  222     }
  223 
  224     p = *pp;
  225     pend = p + len;
  226 
  227     /* We must malloc stuff, even for 0 bytes otherwise it
  228      * signifies a missing NULL parameter. */
  229     if (len < 0 || len > INT_MAX) {
  230         i = ERR_R_ASN1_LENGTH_MISMATCH;
  231         goto err;
  232     }
  233     s = malloc(len + 1);
  234     if (s == NULL) {
  235         i = ERR_R_MALLOC_FAILURE;
  236         goto err;
  237     }
  238     to = s;
  239     if (!len) {
  240         /* Strictly speaking this is an illegal INTEGER but we
  241          * tolerate it.
  242          */
  243         ret->type = V_ASN1_INTEGER;
  244     } else if (*p & 0x80) /* a negative number */ {
  245         ret->type = V_ASN1_NEG_INTEGER;
  246         if ((*p == 0xff) && (len != 1)) {
  247             p++;
  248             len--;
  249         }
  250         i = len;
  251         p += i - 1;
  252         to += i - 1;
  253         while((!*p) && i) {
  254             *(to--) = 0;
  255             i--;
  256             p--;
  257         }
  258         /* Special case: if all zeros then the number will be of
  259          * the form FF followed by n zero bytes: this corresponds to
  260          * 1 followed by n zero bytes. We've already written n zeros
  261          * so we just append an extra one and set the first byte to
  262          * a 1. This is treated separately because it is the only case
  263          * where the number of bytes is larger than len.
  264          */
  265         if (!i) {
  266             *s = 1;
  267             s[len] = 0;
  268             len++;
  269         } else {
  270             *(to--) = (*(p--) ^ 0xff) + 1;
  271             i--;
  272             for (; i > 0; i--)
  273                 *(to--) = *(p--) ^ 0xff;
  274         }
  275     } else {
  276         ret->type = V_ASN1_INTEGER;
  277         if ((*p == 0) && (len != 1)) {
  278             p++;
  279             len--;
  280         }
  281         memcpy(s, p, len);
  282     }
  283 
  284     free(ret->data);
  285     ret->data = s;
  286     ret->length = (int)len;
  287     if (a != NULL)
  288         (*a) = ret;
  289     *pp = pend;
  290     return (ret);
  291 
  292 err:
  293     ASN1error(i);
  294     if (a == NULL || *a != ret)
  295         ASN1_INTEGER_free(ret);
  296     return (NULL);
  297 }
  298 
  299 
  300 /* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
  301  * ASN1 integers: some broken software can encode a positive INTEGER
  302  * with its MSB set as negative (it doesn't add a padding zero).
  303  */
  304 
  305 ASN1_INTEGER *
  306 d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
  307 {
  308     ASN1_INTEGER *ret = NULL;
  309     const unsigned char *p;
  310     unsigned char *s;
  311     long len;
  312     int inf, tag, xclass;
  313     int i;
  314 
  315     if ((a == NULL) || ((*a) == NULL)) {
  316         if ((ret = ASN1_INTEGER_new()) == NULL)
  317             return (NULL);
  318     } else
  319         ret = (*a);
  320 
  321     if (!ASN1_INTEGER_valid(ret)) {
  322         i = ERR_R_ASN1_LENGTH_MISMATCH;
  323         goto err;
  324     }
  325 
  326     p = *pp;
  327     inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
  328     if (inf & 0x80) {
  329         i = ASN1_R_BAD_OBJECT_HEADER;
  330         goto err;
  331     }
  332 
  333     if (tag != V_ASN1_INTEGER) {
  334         i = ASN1_R_EXPECTING_AN_INTEGER;
  335         goto err;
  336     }
  337 
  338     /* We must malloc stuff, even for 0 bytes otherwise it
  339      * signifies a missing NULL parameter. */
  340     if (len < 0 || len > INT_MAX) {
  341         i = ERR_R_ASN1_LENGTH_MISMATCH;
  342         goto err;
  343     }
  344     s = malloc(len + 1);
  345     if (s == NULL) {
  346         i = ERR_R_MALLOC_FAILURE;
  347         goto err;
  348     }
  349     ret->type = V_ASN1_INTEGER;
  350     if (len) {
  351         if ((*p == 0) && (len != 1)) {
  352             p++;
  353             len--;
  354         }
  355         memcpy(s, p, len);
  356         p += len;
  357     }
  358 
  359     free(ret->data);
  360     ret->data = s;
  361     ret->length = (int)len;
  362     if (a != NULL)
  363         (*a) = ret;
  364     *pp = p;
  365     return (ret);
  366 
  367 err:
  368     ASN1error(i);
  369     if (a == NULL || *a != ret)
  370         ASN1_INTEGER_free(ret);
  371     return (NULL);
  372 }
  373 
  374 int
  375 ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
  376 {
  377     int j, k;
  378     unsigned int i;
  379     unsigned char buf[sizeof(long) + 1];
  380     long d;
  381 
  382     a->type = V_ASN1_INTEGER;
  383     /* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */
  384     if (a->length < (int)(sizeof(long) + 1)) {
  385         free(a->data);
  386         a->data = calloc(1, sizeof(long) + 1);
  387     }
  388     if (a->data == NULL) {
  389         ASN1error(ERR_R_MALLOC_FAILURE);
  390         return (0);
  391     }
  392     d = v;
  393     if (d < 0) {
  394         d = -d;
  395         a->type = V_ASN1_NEG_INTEGER;
  396     }
  397 
  398     for (i = 0; i < sizeof(long); i++) {
  399         if (d == 0)
  400             break;
  401         buf[i] = (int)d & 0xff;
  402         d >>= 8;
  403     }
  404     j = 0;
  405     for (k = i - 1; k >= 0; k--)
  406         a->data[j++] = buf[k];
  407     a->length = j;
  408     return (1);
  409 }
  410 
  411 /*
  412  * XXX this particular API is a gibbering eidrich horror that makes it
  413  * impossible to determine valid return cases from errors.. "a bit
  414  * ugly" is preserved for posterity, unfortunately this is probably
  415  * unfixable without changing public API
  416  */
  417 long
  418 ASN1_INTEGER_get(const ASN1_INTEGER *a)
  419 {
  420     int neg = 0, i;
  421     long r = 0;
  422 
  423     if (a == NULL)
  424         return (0L);
  425     i = a->type;
  426     if (i == V_ASN1_NEG_INTEGER)
  427         neg = 1;
  428     else if (i != V_ASN1_INTEGER)
  429         return -1;
  430 
  431     if (!ASN1_INTEGER_valid(a))
  432         return -1; /* XXX best effort */
  433 
  434     if (a->length > (int)sizeof(long)) {
  435         /* hmm... a bit ugly, return all ones */
  436         return -1;
  437     }
  438     if (a->data == NULL)
  439         return 0;
  440 
  441     for (i = 0; i < a->length; i++) {
  442         r <<= 8;
  443         r |= (unsigned char)a->data[i];
  444     }
  445     if (neg)
  446         r = -r;
  447     return (r);
  448 }
  449 
  450 ASN1_INTEGER *
  451 BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
  452 {
  453     ASN1_INTEGER *ret;
  454     int len, j;
  455 
  456     if (ai == NULL)
  457         ret = ASN1_INTEGER_new();
  458     else
  459         ret = ai;
  460     if (ret == NULL) {
  461         ASN1error(ERR_R_NESTED_ASN1_ERROR);
  462         goto err;
  463     }
  464 
  465     if (!ASN1_INTEGER_valid(ret))
  466         goto err;
  467 
  468     if (BN_is_negative(bn))
  469         ret->type = V_ASN1_NEG_INTEGER;
  470     else
  471         ret->type = V_ASN1_INTEGER;
  472     j = BN_num_bits(bn);
  473     len = ((j == 0) ? 0 : ((j / 8) + 1));
  474     if (ret->length < len + 4) {
  475         unsigned char *new_data = realloc(ret->data, len + 4);
  476         if (!new_data) {
  477             ASN1error(ERR_R_MALLOC_FAILURE);
  478             goto err;
  479         }
  480         ret->data = new_data;
  481     }
  482     ret->length = BN_bn2bin(bn, ret->data);
  483 
  484     /* Correct zero case */
  485     if (!ret->length) {
  486         ret->data[0] = 0;
  487         ret->length = 1;
  488     }
  489     return (ret);
  490 
  491 err:
  492     if (ret != ai)
  493         ASN1_INTEGER_free(ret);
  494     return (NULL);
  495 }
  496 
  497 BIGNUM *
  498 ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
  499 {
  500     BIGNUM *ret;
  501 
  502     if (!ASN1_INTEGER_valid(ai))
  503         return (NULL);
  504 
  505     if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
  506         ASN1error(ASN1_R_BN_LIB);
  507     else if (ai->type == V_ASN1_NEG_INTEGER)
  508         BN_set_negative(ret, 1);
  509     return (ret);
  510 }