155714Skris/* crypto/asn1/a_int.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8280297Sjkim *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15280297Sjkim *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22280297Sjkim *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37280297Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40280297Sjkim *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52280297Sjkim *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include "cryptlib.h"
6155714Skris#include <openssl/asn1.h>
62160814Ssimon#include <openssl/bn.h>
6355714Skris
64238405SjkimASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
65280297Sjkim{
66280297Sjkim    return M_ASN1_INTEGER_dup(x);
67280297Sjkim}
6859191Skris
69238405Sjkimint ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
70280297Sjkim{
71280297Sjkim    int neg, ret;
72280297Sjkim    /* Compare signs */
73280297Sjkim    neg = x->type & V_ASN1_NEG;
74280297Sjkim    if (neg != (y->type & V_ASN1_NEG)) {
75280297Sjkim        if (neg)
76280297Sjkim            return -1;
77280297Sjkim        else
78280297Sjkim            return 1;
79280297Sjkim    }
8059191Skris
81280297Sjkim    ret = ASN1_STRING_cmp(x, y);
82142425Snectar
83280297Sjkim    if (neg)
84280297Sjkim        return -ret;
85280297Sjkim    else
86280297Sjkim        return ret;
87280297Sjkim}
88142425Snectar
89280297Sjkim/*-
9068651Skris * This converts an ASN1 INTEGER into its content encoding.
9155714Skris * The internal representation is an ASN1_STRING whose data is a big endian
9255714Skris * representation of the value, ignoring the sign. The sign is determined by
93280297Sjkim * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
9455714Skris *
9555714Skris * Positive integers are no problem: they are almost the same as the DER
9655714Skris * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
9755714Skris *
9855714Skris * Negative integers are a bit trickier...
9955714Skris * The DER representation of negative integers is in 2s complement form.
100280297Sjkim * The internal form is converted by complementing each octet and finally
10155714Skris * adding one to the result. This can be done less messily with a little trick.
10255714Skris * If the internal form has trailing zeroes then they will become FF by the
103280297Sjkim * complement and 0 by the add one (due to carry) so just copy as many trailing
10455714Skris * zeros to the destination as there are in the source. The carry will add one
10555714Skris * to the last none zero octet: so complement this octet and add one and finally
10655714Skris * complement any left over until you get to the start of the string.
10755714Skris *
10855714Skris * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
10955714Skris * with 0xff. However if the first byte is 0x80 and one of the following bytes
11055714Skris * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
11155714Skris * followed by optional zeros isn't padded.
11255714Skris */
11355714Skris
11468651Skrisint i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
115280297Sjkim{
116280297Sjkim    int pad = 0, ret, i, neg;
117280297Sjkim    unsigned char *p, *n, pb = 0;
11855714Skris
119280297Sjkim    if (a == NULL)
120280297Sjkim        return (0);
121280297Sjkim    neg = a->type & V_ASN1_NEG;
122280297Sjkim    if (a->length == 0)
123280297Sjkim        ret = 1;
124280297Sjkim    else {
125280297Sjkim        ret = a->length;
126280297Sjkim        i = a->data[0];
127284283Sjkim        if (ret == 1 && i == 0)
128284283Sjkim            neg = 0;
129280297Sjkim        if (!neg && (i > 127)) {
130280297Sjkim            pad = 1;
131280297Sjkim            pb = 0;
132280297Sjkim        } else if (neg) {
133280297Sjkim            if (i > 128) {
134280297Sjkim                pad = 1;
135280297Sjkim                pb = 0xFF;
136280297Sjkim            } else if (i == 128) {
137280297Sjkim                /*
138280297Sjkim                 * Special case: if any other bytes non zero we pad:
139280297Sjkim                 * otherwise we don't.
140280297Sjkim                 */
141280297Sjkim                for (i = 1; i < a->length; i++)
142280297Sjkim                    if (a->data[i]) {
143280297Sjkim                        pad = 1;
144280297Sjkim                        pb = 0xFF;
145280297Sjkim                        break;
146280297Sjkim                    }
147280297Sjkim            }
148280297Sjkim        }
149280297Sjkim        ret += pad;
150280297Sjkim    }
151280297Sjkim    if (pp == NULL)
152280297Sjkim        return (ret);
153280297Sjkim    p = *pp;
15455714Skris
155280297Sjkim    if (pad)
156280297Sjkim        *(p++) = pb;
157280297Sjkim    if (a->length == 0)
158280297Sjkim        *(p++) = 0;
159280297Sjkim    else if (!neg)
160280297Sjkim        memcpy(p, a->data, (unsigned int)a->length);
161280297Sjkim    else {
162280297Sjkim        /* Begin at the end of the encoding */
163280297Sjkim        n = a->data + a->length - 1;
164280297Sjkim        p += a->length - 1;
165280297Sjkim        i = a->length;
166280297Sjkim        /* Copy zeros to destination as long as source is zero */
167284283Sjkim        while (!*n && i > 1) {
168280297Sjkim            *(p--) = 0;
169280297Sjkim            n--;
170280297Sjkim            i--;
171280297Sjkim        }
172280297Sjkim        /* Complement and increment next octet */
173280297Sjkim        *(p--) = ((*(n--)) ^ 0xff) + 1;
174280297Sjkim        i--;
175280297Sjkim        /* Complement any octets left */
176280297Sjkim        for (; i > 0; i--)
177280297Sjkim            *(p--) = *(n--) ^ 0xff;
178280297Sjkim    }
17955714Skris
180280297Sjkim    *pp += ret;
181280297Sjkim    return (ret);
182280297Sjkim}
18355714Skris
18468651Skris/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
18568651Skris
186160814SsimonASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
187280297Sjkim                               long len)
188280297Sjkim{
189280297Sjkim    ASN1_INTEGER *ret = NULL;
190280297Sjkim    const unsigned char *p, *pend;
191280297Sjkim    unsigned char *to, *s;
192280297Sjkim    int i;
19368651Skris
194280297Sjkim    if ((a == NULL) || ((*a) == NULL)) {
195280297Sjkim        if ((ret = M_ASN1_INTEGER_new()) == NULL)
196280297Sjkim            return (NULL);
197280297Sjkim        ret->type = V_ASN1_INTEGER;
198280297Sjkim    } else
199280297Sjkim        ret = (*a);
20068651Skris
201280297Sjkim    p = *pp;
202280297Sjkim    pend = p + len;
20368651Skris
204280297Sjkim    /*
205280297Sjkim     * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
206280297Sjkim     * a missing NULL parameter.
207280297Sjkim     */
208280297Sjkim    s = (unsigned char *)OPENSSL_malloc((int)len + 1);
209280297Sjkim    if (s == NULL) {
210280297Sjkim        i = ERR_R_MALLOC_FAILURE;
211280297Sjkim        goto err;
212280297Sjkim    }
213280297Sjkim    to = s;
214280297Sjkim    if (!len) {
215280297Sjkim        /*
216280297Sjkim         * Strictly speaking this is an illegal INTEGER but we tolerate it.
217280297Sjkim         */
218280297Sjkim        ret->type = V_ASN1_INTEGER;
219280297Sjkim    } else if (*p & 0x80) {     /* a negative number */
220280297Sjkim        ret->type = V_ASN1_NEG_INTEGER;
221280297Sjkim        if ((*p == 0xff) && (len != 1)) {
222280297Sjkim            p++;
223280297Sjkim            len--;
224280297Sjkim        }
225280297Sjkim        i = len;
226280297Sjkim        p += i - 1;
227280297Sjkim        to += i - 1;
228280297Sjkim        while ((!*p) && i) {
229280297Sjkim            *(to--) = 0;
230280297Sjkim            i--;
231280297Sjkim            p--;
232280297Sjkim        }
233280297Sjkim        /*
234280297Sjkim         * Special case: if all zeros then the number will be of the form FF
235280297Sjkim         * followed by n zero bytes: this corresponds to 1 followed by n zero
236280297Sjkim         * bytes. We've already written n zeros so we just append an extra
237280297Sjkim         * one and set the first byte to a 1. This is treated separately
238280297Sjkim         * because it is the only case where the number of bytes is larger
239280297Sjkim         * than len.
240280297Sjkim         */
241280297Sjkim        if (!i) {
242280297Sjkim            *s = 1;
243280297Sjkim            s[len] = 0;
244280297Sjkim            len++;
245280297Sjkim        } else {
246280297Sjkim            *(to--) = (*(p--) ^ 0xff) + 1;
247280297Sjkim            i--;
248280297Sjkim            for (; i > 0; i--)
249280297Sjkim                *(to--) = *(p--) ^ 0xff;
250280297Sjkim        }
251280297Sjkim    } else {
252280297Sjkim        ret->type = V_ASN1_INTEGER;
253280297Sjkim        if ((*p == 0) && (len != 1)) {
254280297Sjkim            p++;
255280297Sjkim            len--;
256280297Sjkim        }
257280297Sjkim        memcpy(s, p, (int)len);
258280297Sjkim    }
25955714Skris
260280297Sjkim    if (ret->data != NULL)
261280297Sjkim        OPENSSL_free(ret->data);
262280297Sjkim    ret->data = s;
263280297Sjkim    ret->length = (int)len;
264280297Sjkim    if (a != NULL)
265280297Sjkim        (*a) = ret;
266280297Sjkim    *pp = pend;
267280297Sjkim    return (ret);
268280297Sjkim err:
269280297Sjkim    ASN1err(ASN1_F_C2I_ASN1_INTEGER, i);
270280297Sjkim    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
271280297Sjkim        M_ASN1_INTEGER_free(ret);
272280297Sjkim    return (NULL);
273280297Sjkim}
27455714Skris
275280297Sjkim/*
276280297Sjkim * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
277280297Sjkim * integers: some broken software can encode a positive INTEGER with its MSB
278280297Sjkim * set as negative (it doesn't add a padding zero).
27955714Skris */
28055714Skris
281160814SsimonASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
282280297Sjkim                                long length)
283280297Sjkim{
284280297Sjkim    ASN1_INTEGER *ret = NULL;
285280297Sjkim    const unsigned char *p;
286280297Sjkim    unsigned char *s;
287280297Sjkim    long len;
288280297Sjkim    int inf, tag, xclass;
289280297Sjkim    int i;
29055714Skris
291280297Sjkim    if ((a == NULL) || ((*a) == NULL)) {
292280297Sjkim        if ((ret = M_ASN1_INTEGER_new()) == NULL)
293280297Sjkim            return (NULL);
294280297Sjkim        ret->type = V_ASN1_INTEGER;
295280297Sjkim    } else
296280297Sjkim        ret = (*a);
29755714Skris
298280297Sjkim    p = *pp;
299280297Sjkim    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
300280297Sjkim    if (inf & 0x80) {
301280297Sjkim        i = ASN1_R_BAD_OBJECT_HEADER;
302280297Sjkim        goto err;
303280297Sjkim    }
30455714Skris
305280297Sjkim    if (tag != V_ASN1_INTEGER) {
306280297Sjkim        i = ASN1_R_EXPECTING_AN_INTEGER;
307280297Sjkim        goto err;
308280297Sjkim    }
30955714Skris
310280297Sjkim    /*
311280297Sjkim     * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
312280297Sjkim     * a missing NULL parameter.
313280297Sjkim     */
314280297Sjkim    s = (unsigned char *)OPENSSL_malloc((int)len + 1);
315280297Sjkim    if (s == NULL) {
316280297Sjkim        i = ERR_R_MALLOC_FAILURE;
317280297Sjkim        goto err;
318280297Sjkim    }
319280297Sjkim    ret->type = V_ASN1_INTEGER;
320280297Sjkim    if (len) {
321280297Sjkim        if ((*p == 0) && (len != 1)) {
322280297Sjkim            p++;
323280297Sjkim            len--;
324280297Sjkim        }
325280297Sjkim        memcpy(s, p, (int)len);
326280297Sjkim        p += len;
327280297Sjkim    }
32855714Skris
329280297Sjkim    if (ret->data != NULL)
330280297Sjkim        OPENSSL_free(ret->data);
331280297Sjkim    ret->data = s;
332280297Sjkim    ret->length = (int)len;
333280297Sjkim    if (a != NULL)
334280297Sjkim        (*a) = ret;
335280297Sjkim    *pp = p;
336280297Sjkim    return (ret);
337280297Sjkim err:
338280297Sjkim    ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
339280297Sjkim    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
340280297Sjkim        M_ASN1_INTEGER_free(ret);
341280297Sjkim    return (NULL);
342280297Sjkim}
34355714Skris
34455714Skrisint ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
345280297Sjkim{
346280297Sjkim    int j, k;
347280297Sjkim    unsigned int i;
348280297Sjkim    unsigned char buf[sizeof(long) + 1];
349280297Sjkim    long d;
35055714Skris
351280297Sjkim    a->type = V_ASN1_INTEGER;
352280297Sjkim    if (a->length < (int)(sizeof(long) + 1)) {
353280297Sjkim        if (a->data != NULL)
354280297Sjkim            OPENSSL_free(a->data);
355280297Sjkim        if ((a->data =
356280297Sjkim             (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
357280297Sjkim            memset((char *)a->data, 0, sizeof(long) + 1);
358280297Sjkim    }
359280297Sjkim    if (a->data == NULL) {
360280297Sjkim        ASN1err(ASN1_F_ASN1_INTEGER_SET, ERR_R_MALLOC_FAILURE);
361280297Sjkim        return (0);
362280297Sjkim    }
363280297Sjkim    d = v;
364280297Sjkim    if (d < 0) {
365280297Sjkim        d = -d;
366280297Sjkim        a->type = V_ASN1_NEG_INTEGER;
367280297Sjkim    }
36855714Skris
369280297Sjkim    for (i = 0; i < sizeof(long); i++) {
370280297Sjkim        if (d == 0)
371280297Sjkim            break;
372280297Sjkim        buf[i] = (int)d & 0xff;
373280297Sjkim        d >>= 8;
374280297Sjkim    }
375280297Sjkim    j = 0;
376280297Sjkim    for (k = i - 1; k >= 0; k--)
377280297Sjkim        a->data[j++] = buf[k];
378280297Sjkim    a->length = j;
379280297Sjkim    return (1);
380280297Sjkim}
38155714Skris
382238405Sjkimlong ASN1_INTEGER_get(const ASN1_INTEGER *a)
383280297Sjkim{
384280297Sjkim    int neg = 0, i;
385280297Sjkim    long r = 0;
38655714Skris
387280297Sjkim    if (a == NULL)
388280297Sjkim        return (0L);
389280297Sjkim    i = a->type;
390280297Sjkim    if (i == V_ASN1_NEG_INTEGER)
391280297Sjkim        neg = 1;
392280297Sjkim    else if (i != V_ASN1_INTEGER)
393280297Sjkim        return -1;
39455714Skris
395280297Sjkim    if (a->length > (int)sizeof(long)) {
396280297Sjkim        /* hmm... a bit ugly, return all ones */
397280297Sjkim        return -1;
398280297Sjkim    }
399280297Sjkim    if (a->data == NULL)
400280297Sjkim        return 0;
40155714Skris
402280297Sjkim    for (i = 0; i < a->length; i++) {
403280297Sjkim        r <<= 8;
404280297Sjkim        r |= (unsigned char)a->data[i];
405280297Sjkim    }
406280297Sjkim    if (neg)
407280297Sjkim        r = -r;
408280297Sjkim    return (r);
409280297Sjkim}
410280297Sjkim
411238405SjkimASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
412280297Sjkim{
413280297Sjkim    ASN1_INTEGER *ret;
414280297Sjkim    int len, j;
41555714Skris
416280297Sjkim    if (ai == NULL)
417280297Sjkim        ret = M_ASN1_INTEGER_new();
418280297Sjkim    else
419280297Sjkim        ret = ai;
420280297Sjkim    if (ret == NULL) {
421280297Sjkim        ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR);
422280297Sjkim        goto err;
423280297Sjkim    }
424284283Sjkim    if (BN_is_negative(bn) && !BN_is_zero(bn))
425280297Sjkim        ret->type = V_ASN1_NEG_INTEGER;
426280297Sjkim    else
427280297Sjkim        ret->type = V_ASN1_INTEGER;
428280297Sjkim    j = BN_num_bits(bn);
429280297Sjkim    len = ((j == 0) ? 0 : ((j / 8) + 1));
430280297Sjkim    if (ret->length < len + 4) {
431280297Sjkim        unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
432280297Sjkim        if (!new_data) {
433280297Sjkim            ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
434280297Sjkim            goto err;
435280297Sjkim        }
436280297Sjkim        ret->data = new_data;
437280297Sjkim    }
438280297Sjkim    ret->length = BN_bn2bin(bn, ret->data);
439280297Sjkim    /* Correct zero case */
440280297Sjkim    if (!ret->length) {
441280297Sjkim        ret->data[0] = 0;
442280297Sjkim        ret->length = 1;
443280297Sjkim    }
444280297Sjkim    return (ret);
445280297Sjkim err:
446280297Sjkim    if (ret != ai)
447280297Sjkim        M_ASN1_INTEGER_free(ret);
448280297Sjkim    return (NULL);
449280297Sjkim}
45055714Skris
451238405SjkimBIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
452280297Sjkim{
453280297Sjkim    BIGNUM *ret;
45455714Skris
455280297Sjkim    if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
456280297Sjkim        ASN1err(ASN1_F_ASN1_INTEGER_TO_BN, ASN1_R_BN_LIB);
457280297Sjkim    else if (ai->type == V_ASN1_NEG_INTEGER)
458280297Sjkim        BN_set_negative(ret, 1);
459280297Sjkim    return (ret);
460280297Sjkim}
46168651Skris
46268651SkrisIMPLEMENT_STACK_OF(ASN1_INTEGER)
463280297Sjkim
46468651SkrisIMPLEMENT_ASN1_SET_OF(ASN1_INTEGER)
465