This commit was generated by cvs2svn to track changes on a CVS vendor
[openssl.git] / crypto / bn / bn_print.c
1 /* crypto/bn/bn_print.c */
2 /* Copyright (C) 1995-1997 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 <ctype.h>
61 #include "cryptlib.h"
62 #include "buffer.h"
63 #include "bn_lcl.h"
64
65 static char *Hex="0123456789ABCDEF";
66
67 /* Must 'Free' the returned data */
68 char *BN_bn2ascii(a)
69 BIGNUM *a;
70         {
71         int i,j,v,z=0;
72         char *buf;
73         char *p;
74
75         buf=(char *)Malloc(a->top*BN_BYTES*2+2);
76         if (buf == NULL)
77                 {
78                 BNerr(BN_F_BN_BN2ASCII,ERR_R_MALLOC_FAILURE);
79                 goto err;
80                 }
81         p=buf;
82         if (a->neg) *(p++)='-';
83         if (a->top == 0) *(p++)='0';
84         for (i=a->top-1; i >=0; i--)
85                 {
86                 for (j=BN_BITS2-8; j >= 0; j-=8)
87                         {
88                         /* strip leading zeros */
89                         v=((int)(a->d[i]>>(long)j))&0xff;
90                         if (z || (v != 0))
91                                 {
92                                 *(p++)=Hex[v>>4];
93                                 *(p++)=Hex[v&0x0f];
94                                 z=1;
95                                 }
96                         }
97                 }
98         *p='\0';
99 err:
100         return(buf);
101         }
102
103 int BN_ascii2bn(bn,a)
104 BIGNUM **bn;
105 char *a;
106         {
107         BIGNUM *ret=NULL;
108         BN_ULONG l=0;
109         int neg=0,h,m,i,j,k,c;
110         int num;
111
112         if ((a == NULL) || (*a == '\0')) return(0);
113
114         if (*a == '-') { neg=1; a++; }
115
116         for (i=0; isxdigit(a[i]); i++)
117                 ;
118
119         num=i+neg;
120         if (bn == NULL) return(num);
121
122         /* a is the start of the hex digets, and it is 'i' long */
123         if (*bn == NULL)
124                 {
125                 if ((ret=BN_new()) == NULL) return(0);
126                 }
127         else
128                 {
129                 ret= *bn;
130                 BN_zero(ret);
131                 }
132
133         /* i is the number of hex digests; */
134         if (bn_expand(ret,i*4) == NULL) goto err;
135
136         j=i; /* least significate 'hex' */
137         m=0;
138         h=0;
139         while (j > 0)
140                 {
141                 m=((BN_BYTES*2) <= j)?(BN_BYTES*2):j;
142                 l=0;
143                 for (;;)
144                         {
145                         c=a[j-m];
146                         if ((c >= '0') && (c <= '9')) k=c-'0';
147                         else if ((c >= 'a') && (c <= 'f')) k=c-'a'+10;
148                         else if ((c >= 'A') && (c <= 'F')) k=c-'A'+10;
149                         else k=0; /* paranoia */
150                         l=(l<<4)|k;
151
152                         if (--m <= 0)
153                                 {
154                                 ret->d[h++]=l;
155                                 break;
156                                 }
157                         }
158                 j-=(BN_BYTES*2);
159                 }
160         ret->top=h;
161         bn_fix_top(ret);
162         ret->neg=neg;
163
164         *bn=ret;
165         return(num);
166 err:
167         if (*bn == NULL) BN_free(ret);
168         return(0);
169         }
170
171 #ifndef NO_BIO
172
173 #ifndef WIN16
174 int BN_print_fp(fp, a)
175 FILE *fp;
176 BIGNUM *a;
177         {
178         BIO *b;
179         int ret;
180
181         if ((b=BIO_new(BIO_s_file())) == NULL)
182                 return(0);
183         BIO_set_fp(b,fp,BIO_NOCLOSE);
184         ret=BN_print(b,a);
185         BIO_free(b);
186         return(ret);
187         }
188 #endif
189
190 int BN_print(bp, a)
191 BIO *bp;
192 BIGNUM *a;
193         {
194         int i,j,v,z=0;
195         int ret=0;
196
197         if ((a->neg) && (BIO_write(bp,"-",1) != 1)) goto end;
198         if ((a->top == 0) && (BIO_write(bp,"0",1) != 1)) goto end;
199         for (i=a->top-1; i >=0; i--)
200                 {
201                 for (j=BN_BITS2-4; j >= 0; j-=4)
202                         {
203                         /* strip leading zeros */
204                         v=((int)(a->d[i]>>(long)j))&0x0f;
205                         if (z || (v != 0))
206                                 {
207                                 if (BIO_write(bp,&(Hex[v]),1) != 1)
208                                         goto end;
209                                 z=1;
210                                 }
211                         }
212                 }
213         ret=1;
214 end:
215         return(ret);
216         }
217
218 #endif