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.
855714Skris *
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).
1555714Skris *
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.
2255714Skris *
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 :-).
3755714Skris * 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)"
4055714Skris *
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.
5255714Skris *
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)
6559191Skris{ return M_ASN1_INTEGER_dup(x);}
6659191Skris
67238405Sjkimint ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
68142425Snectar	{
69142425Snectar	int neg, ret;
70142425Snectar	/* Compare signs */
71142425Snectar	neg = x->type & V_ASN1_NEG;
72142425Snectar	if (neg != (y->type & V_ASN1_NEG))
73142425Snectar		{
74142425Snectar		if (neg)
75142425Snectar			return -1;
76142425Snectar		else
77142425Snectar			return 1;
78142425Snectar		}
7959191Skris
80142425Snectar	ret = ASN1_STRING_cmp(x, y);
81142425Snectar
82142425Snectar	if (neg)
83142425Snectar		return -ret;
84142425Snectar	else
85142425Snectar		return ret;
86142425Snectar	}
87142425Snectar
88142425Snectar
8955714Skris/*
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
9355714Skris * 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.
10055714Skris * 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
10355714Skris * 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)
11555714Skris	{
11668651Skris	int pad=0,ret,i,neg;
11755714Skris	unsigned char *p,*n,pb=0;
11855714Skris
119279264Sdelphij	if (a == NULL) return(0);
12068651Skris	neg=a->type & V_ASN1_NEG;
12155714Skris	if (a->length == 0)
12255714Skris		ret=1;
12355714Skris	else
12455714Skris		{
12555714Skris		ret=a->length;
12655714Skris		i=a->data[0];
12768651Skris		if (!neg && (i > 127)) {
12855714Skris			pad=1;
12955714Skris			pb=0;
13068651Skris		} else if(neg) {
13155714Skris			if(i>128) {
13255714Skris				pad=1;
13355714Skris				pb=0xFF;
13455714Skris			} else if(i == 128) {
13555714Skris			/*
13655714Skris			 * Special case: if any other bytes non zero we pad:
13755714Skris			 * otherwise we don't.
13855714Skris			 */
13955714Skris				for(i = 1; i < a->length; i++) if(a->data[i]) {
14055714Skris						pad=1;
14155714Skris						pb=0xFF;
14255714Skris						break;
14355714Skris				}
14455714Skris			}
14555714Skris		}
14655714Skris		ret+=pad;
14755714Skris		}
14868651Skris	if (pp == NULL) return(ret);
14955714Skris	p= *pp;
15055714Skris
15155714Skris	if (pad) *(p++)=pb;
15255714Skris	if (a->length == 0) *(p++)=0;
15368651Skris	else if (!neg) memcpy(p,a->data,(unsigned int)a->length);
15455714Skris	else {
15555714Skris		/* Begin at the end of the encoding */
15655714Skris		n=a->data + a->length - 1;
15755714Skris		p += a->length - 1;
15855714Skris		i = a->length;
15955714Skris		/* Copy zeros to destination as long as source is zero */
16055714Skris		while(!*n) {
16155714Skris			*(p--) = 0;
16255714Skris			n--;
16355714Skris			i--;
16455714Skris		}
16555714Skris		/* Complement and increment next octet */
16655714Skris		*(p--) = ((*(n--)) ^ 0xff) + 1;
16755714Skris		i--;
16855714Skris		/* Complement any octets left */
16955714Skris		for(;i > 0; i--) *(p--) = *(n--) ^ 0xff;
17055714Skris	}
17155714Skris
17268651Skris	*pp+=ret;
17368651Skris	return(ret);
17455714Skris	}
17555714Skris
17668651Skris/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
17768651Skris
178160814SsimonASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
17968651Skris	     long len)
18068651Skris	{
18168651Skris	ASN1_INTEGER *ret=NULL;
182160814Ssimon	const unsigned char *p, *pend;
183160814Ssimon	unsigned char *to,*s;
18468651Skris	int i;
18568651Skris
18668651Skris	if ((a == NULL) || ((*a) == NULL))
18768651Skris		{
18868651Skris		if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
18968651Skris		ret->type=V_ASN1_INTEGER;
19068651Skris		}
19168651Skris	else
19268651Skris		ret=(*a);
19368651Skris
19468651Skris	p= *pp;
19568651Skris	pend = p + len;
19668651Skris
19768651Skris	/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
19855714Skris	 * signifies a missing NULL parameter. */
19968651Skris	s=(unsigned char *)OPENSSL_malloc((int)len+1);
20055714Skris	if (s == NULL)
20155714Skris		{
20255714Skris		i=ERR_R_MALLOC_FAILURE;
20355714Skris		goto err;
20455714Skris		}
20555714Skris	to=s;
20659191Skris	if(!len) {
20759191Skris		/* Strictly speaking this is an illegal INTEGER but we
20859191Skris		 * tolerate it.
20959191Skris		 */
21059191Skris		ret->type=V_ASN1_INTEGER;
21159191Skris	} else if (*p & 0x80) /* a negative number */
21255714Skris		{
21355714Skris		ret->type=V_ASN1_NEG_INTEGER;
21455714Skris		if ((*p == 0xff) && (len != 1)) {
21555714Skris			p++;
21655714Skris			len--;
21755714Skris		}
21855714Skris		i = len;
21955714Skris		p += i - 1;
22055714Skris		to += i - 1;
22155714Skris		while((!*p) && i) {
22255714Skris			*(to--) = 0;
22355714Skris			i--;
22455714Skris			p--;
22555714Skris		}
22655714Skris		/* Special case: if all zeros then the number will be of
22755714Skris		 * the form FF followed by n zero bytes: this corresponds to
22855714Skris		 * 1 followed by n zero bytes. We've already written n zeros
22955714Skris		 * so we just append an extra one and set the first byte to
23055714Skris		 * a 1. This is treated separately because it is the only case
23155714Skris		 * where the number of bytes is larger than len.
23255714Skris		 */
23355714Skris		if(!i) {
23455714Skris			*s = 1;
23555714Skris			s[len] = 0;
23655714Skris			len++;
23755714Skris		} else {
23855714Skris			*(to--) = (*(p--) ^ 0xff) + 1;
23955714Skris			i--;
24055714Skris			for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
24155714Skris		}
24255714Skris	} else {
24355714Skris		ret->type=V_ASN1_INTEGER;
24455714Skris		if ((*p == 0) && (len != 1))
24555714Skris			{
24655714Skris			p++;
24755714Skris			len--;
24855714Skris			}
24955714Skris		memcpy(s,p,(int)len);
25055714Skris	}
25155714Skris
25268651Skris	if (ret->data != NULL) OPENSSL_free(ret->data);
25355714Skris	ret->data=s;
25455714Skris	ret->length=(int)len;
25555714Skris	if (a != NULL) (*a)=ret;
25655714Skris	*pp=pend;
25755714Skris	return(ret);
25855714Skriserr:
259160814Ssimon	ASN1err(ASN1_F_C2I_ASN1_INTEGER,i);
26055714Skris	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
26159191Skris		M_ASN1_INTEGER_free(ret);
26255714Skris	return(NULL);
26355714Skris	}
26455714Skris
26568651Skris
26655714Skris/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
26755714Skris * ASN1 integers: some broken software can encode a positive INTEGER
26855714Skris * with its MSB set as negative (it doesn't add a padding zero).
26955714Skris */
27055714Skris
271160814SsimonASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
27255714Skris	     long length)
27355714Skris	{
27455714Skris	ASN1_INTEGER *ret=NULL;
275160814Ssimon	const unsigned char *p;
276215697Ssimon	unsigned char *s;
27755714Skris	long len;
27855714Skris	int inf,tag,xclass;
27955714Skris	int i;
28055714Skris
28155714Skris	if ((a == NULL) || ((*a) == NULL))
28255714Skris		{
28359191Skris		if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
28455714Skris		ret->type=V_ASN1_INTEGER;
28555714Skris		}
28655714Skris	else
28755714Skris		ret=(*a);
28855714Skris
28955714Skris	p= *pp;
29055714Skris	inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
29155714Skris	if (inf & 0x80)
29255714Skris		{
29355714Skris		i=ASN1_R_BAD_OBJECT_HEADER;
29455714Skris		goto err;
29555714Skris		}
29655714Skris
29755714Skris	if (tag != V_ASN1_INTEGER)
29855714Skris		{
29955714Skris		i=ASN1_R_EXPECTING_AN_INTEGER;
30055714Skris		goto err;
30155714Skris		}
30255714Skris
30368651Skris	/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
30455714Skris	 * signifies a missing NULL parameter. */
30568651Skris	s=(unsigned char *)OPENSSL_malloc((int)len+1);
30655714Skris	if (s == NULL)
30755714Skris		{
30855714Skris		i=ERR_R_MALLOC_FAILURE;
30955714Skris		goto err;
31055714Skris		}
31159191Skris	ret->type=V_ASN1_INTEGER;
31259191Skris	if(len) {
31355714Skris		if ((*p == 0) && (len != 1))
31455714Skris			{
31555714Skris			p++;
31655714Skris			len--;
31755714Skris			}
31855714Skris		memcpy(s,p,(int)len);
31955714Skris		p+=len;
32059191Skris	}
32155714Skris
32268651Skris	if (ret->data != NULL) OPENSSL_free(ret->data);
32355714Skris	ret->data=s;
32455714Skris	ret->length=(int)len;
32555714Skris	if (a != NULL) (*a)=ret;
32655714Skris	*pp=p;
32755714Skris	return(ret);
32855714Skriserr:
32955714Skris	ASN1err(ASN1_F_D2I_ASN1_UINTEGER,i);
33055714Skris	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
33159191Skris		M_ASN1_INTEGER_free(ret);
33255714Skris	return(NULL);
33355714Skris	}
33455714Skris
33555714Skrisint ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
33655714Skris	{
337160814Ssimon	int j,k;
338160814Ssimon	unsigned int i;
33955714Skris	unsigned char buf[sizeof(long)+1];
34055714Skris	long d;
34155714Skris
34255714Skris	a->type=V_ASN1_INTEGER;
343160814Ssimon	if (a->length < (int)(sizeof(long)+1))
34455714Skris		{
34555714Skris		if (a->data != NULL)
34668651Skris			OPENSSL_free(a->data);
34768651Skris		if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
34855714Skris			memset((char *)a->data,0,sizeof(long)+1);
34955714Skris		}
35055714Skris	if (a->data == NULL)
35155714Skris		{
35255714Skris		ASN1err(ASN1_F_ASN1_INTEGER_SET,ERR_R_MALLOC_FAILURE);
35355714Skris		return(0);
35455714Skris		}
35555714Skris	d=v;
35655714Skris	if (d < 0)
35755714Skris		{
35855714Skris		d= -d;
35955714Skris		a->type=V_ASN1_NEG_INTEGER;
36055714Skris		}
36155714Skris
36255714Skris	for (i=0; i<sizeof(long); i++)
36355714Skris		{
36455714Skris		if (d == 0) break;
36555714Skris		buf[i]=(int)d&0xff;
36655714Skris		d>>=8;
36755714Skris		}
36855714Skris	j=0;
36955714Skris	for (k=i-1; k >=0; k--)
37055714Skris		a->data[j++]=buf[k];
37155714Skris	a->length=j;
37255714Skris	return(1);
37355714Skris	}
37455714Skris
375238405Sjkimlong ASN1_INTEGER_get(const ASN1_INTEGER *a)
37655714Skris	{
37755714Skris	int neg=0,i;
37855714Skris	long r=0;
37955714Skris
38055714Skris	if (a == NULL) return(0L);
38155714Skris	i=a->type;
38255714Skris	if (i == V_ASN1_NEG_INTEGER)
38355714Skris		neg=1;
38455714Skris	else if (i != V_ASN1_INTEGER)
385109998Smarkm		return -1;
38655714Skris
387160814Ssimon	if (a->length > (int)sizeof(long))
38855714Skris		{
389238405Sjkim		/* hmm... a bit ugly, return all ones */
390238405Sjkim		return -1;
39155714Skris		}
39255714Skris	if (a->data == NULL)
393109998Smarkm		return 0;
39455714Skris
39555714Skris	for (i=0; i<a->length; i++)
39655714Skris		{
39755714Skris		r<<=8;
39855714Skris		r|=(unsigned char)a->data[i];
39955714Skris		}
40055714Skris	if (neg) r= -r;
40155714Skris	return(r);
40255714Skris	}
40355714Skris
404238405SjkimASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
40555714Skris	{
40655714Skris	ASN1_INTEGER *ret;
40755714Skris	int len,j;
40855714Skris
40955714Skris	if (ai == NULL)
41059191Skris		ret=M_ASN1_INTEGER_new();
41155714Skris	else
41255714Skris		ret=ai;
41355714Skris	if (ret == NULL)
41455714Skris		{
41555714Skris		ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR);
41655714Skris		goto err;
41755714Skris		}
418160814Ssimon	if (BN_is_negative(bn))
419160814Ssimon		ret->type = V_ASN1_NEG_INTEGER;
42055714Skris	else ret->type=V_ASN1_INTEGER;
42155714Skris	j=BN_num_bits(bn);
42255714Skris	len=((j == 0)?0:((j/8)+1));
423100936Snectar	if (ret->length < len+4)
424100936Snectar		{
425109998Smarkm		unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
426100936Snectar		if (!new_data)
427100936Snectar			{
428100936Snectar			ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
429100936Snectar			goto err;
430100936Snectar			}
431100936Snectar		ret->data=new_data;
432100936Snectar		}
43355714Skris	ret->length=BN_bn2bin(bn,ret->data);
434109998Smarkm	/* Correct zero case */
435109998Smarkm	if(!ret->length)
436109998Smarkm		{
437109998Smarkm		ret->data[0] = 0;
438109998Smarkm		ret->length = 1;
439109998Smarkm		}
44055714Skris	return(ret);
44155714Skriserr:
44259191Skris	if (ret != ai) M_ASN1_INTEGER_free(ret);
44355714Skris	return(NULL);
44455714Skris	}
44555714Skris
446238405SjkimBIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
44755714Skris	{
44855714Skris	BIGNUM *ret;
44955714Skris
45055714Skris	if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
45155714Skris		ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB);
452160814Ssimon	else if(ai->type == V_ASN1_NEG_INTEGER)
453160814Ssimon		BN_set_negative(ret, 1);
45455714Skris	return(ret);
45555714Skris	}
45668651Skris
45768651SkrisIMPLEMENT_STACK_OF(ASN1_INTEGER)
45868651SkrisIMPLEMENT_ASN1_SET_OF(ASN1_INTEGER)
459