155714Skris/* crypto/asn1/f_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/buffer.h> 6255714Skris#include <openssl/asn1.h> 6355714Skris 6455714Skrisint i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a) 65280297Sjkim{ 66280297Sjkim int i, n = 0; 67280297Sjkim static const char *h = "0123456789ABCDEF"; 68280297Sjkim char buf[2]; 6955714Skris 70280297Sjkim if (a == NULL) 71280297Sjkim return (0); 7255714Skris 73280297Sjkim if (a->type & V_ASN1_NEG) { 74280297Sjkim if (BIO_write(bp, "-", 1) != 1) 75280297Sjkim goto err; 76280297Sjkim n = 1; 77280297Sjkim } 78109998Smarkm 79280297Sjkim if (a->length == 0) { 80280297Sjkim if (BIO_write(bp, "00", 2) != 2) 81280297Sjkim goto err; 82280297Sjkim n += 2; 83280297Sjkim } else { 84280297Sjkim for (i = 0; i < a->length; i++) { 85280297Sjkim if ((i != 0) && (i % 35 == 0)) { 86280297Sjkim if (BIO_write(bp, "\\\n", 2) != 2) 87280297Sjkim goto err; 88280297Sjkim n += 2; 89280297Sjkim } 90280297Sjkim buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; 91280297Sjkim buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; 92280297Sjkim if (BIO_write(bp, buf, 2) != 2) 93280297Sjkim goto err; 94280297Sjkim n += 2; 95280297Sjkim } 96280297Sjkim } 97280297Sjkim return (n); 98280297Sjkim err: 99280297Sjkim return (-1); 100280297Sjkim} 10155714Skris 10255714Skrisint a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) 103280297Sjkim{ 104280297Sjkim int ret = 0; 105280297Sjkim int i, j, k, m, n, again, bufsize; 106280297Sjkim unsigned char *s = NULL, *sp; 107280297Sjkim unsigned char *bufp; 108280297Sjkim int num = 0, slen = 0, first = 1; 10955714Skris 110280297Sjkim bs->type = V_ASN1_INTEGER; 11155714Skris 112280297Sjkim bufsize = BIO_gets(bp, buf, size); 113280297Sjkim for (;;) { 114280297Sjkim if (bufsize < 1) 115280297Sjkim goto err_sl; 116280297Sjkim i = bufsize; 117280297Sjkim if (buf[i - 1] == '\n') 118280297Sjkim buf[--i] = '\0'; 119280297Sjkim if (i == 0) 120280297Sjkim goto err_sl; 121280297Sjkim if (buf[i - 1] == '\r') 122280297Sjkim buf[--i] = '\0'; 123280297Sjkim if (i == 0) 124280297Sjkim goto err_sl; 125280297Sjkim again = (buf[i - 1] == '\\'); 12655714Skris 127280297Sjkim for (j = 0; j < i; j++) { 12855714Skris#ifndef CHARSET_EBCDIC 129280297Sjkim if (!(((buf[j] >= '0') && (buf[j] <= '9')) || 130280297Sjkim ((buf[j] >= 'a') && (buf[j] <= 'f')) || 131280297Sjkim ((buf[j] >= 'A') && (buf[j] <= 'F')))) 13255714Skris#else 133280297Sjkim /* 134280297Sjkim * This #ifdef is not strictly necessary, since the characters 135280297Sjkim * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but 136280297Sjkim * not the whole alphabet). Nevertheless, isxdigit() is faster. 137280297Sjkim */ 138280297Sjkim if (!isxdigit(buf[j])) 13955714Skris#endif 140280297Sjkim { 141280297Sjkim i = j; 142280297Sjkim break; 143280297Sjkim } 144280297Sjkim } 145280297Sjkim buf[i] = '\0'; 146280297Sjkim /* 147280297Sjkim * We have now cleared all the crap off the end of the line 148280297Sjkim */ 149280297Sjkim if (i < 2) 150280297Sjkim goto err_sl; 15155714Skris 152280297Sjkim bufp = (unsigned char *)buf; 153280297Sjkim if (first) { 154280297Sjkim first = 0; 155325335Sjkim if ((bufp[0] == '0') && (bufp[1] == '0')) { 156280297Sjkim bufp += 2; 157280297Sjkim i -= 2; 158280297Sjkim } 159280297Sjkim } 160280297Sjkim k = 0; 161280297Sjkim i -= again; 162280297Sjkim if (i % 2 != 0) { 163280297Sjkim ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS); 164280297Sjkim goto err; 165280297Sjkim } 166280297Sjkim i /= 2; 167280297Sjkim if (num + i > slen) { 168280297Sjkim if (s == NULL) 169280297Sjkim sp = (unsigned char *)OPENSSL_malloc((unsigned int)num + 170280297Sjkim i * 2); 171280297Sjkim else 172280297Sjkim sp = OPENSSL_realloc_clean(s, slen, num + i * 2); 173280297Sjkim if (sp == NULL) { 174280297Sjkim ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); 175280297Sjkim goto err; 176280297Sjkim } 177280297Sjkim s = sp; 178280297Sjkim slen = num + i * 2; 179280297Sjkim } 180280297Sjkim for (j = 0; j < i; j++, k += 2) { 181280297Sjkim for (n = 0; n < 2; n++) { 182280297Sjkim m = bufp[k + n]; 183280297Sjkim if ((m >= '0') && (m <= '9')) 184280297Sjkim m -= '0'; 185280297Sjkim else if ((m >= 'a') && (m <= 'f')) 186280297Sjkim m = m - 'a' + 10; 187280297Sjkim else if ((m >= 'A') && (m <= 'F')) 188280297Sjkim m = m - 'A' + 10; 189280297Sjkim else { 190280297Sjkim ASN1err(ASN1_F_A2I_ASN1_INTEGER, 191280297Sjkim ASN1_R_NON_HEX_CHARACTERS); 192280297Sjkim goto err; 193280297Sjkim } 194280297Sjkim s[num + j] <<= 4; 195280297Sjkim s[num + j] |= m; 196280297Sjkim } 197280297Sjkim } 198280297Sjkim num += i; 199280297Sjkim if (again) 200280297Sjkim bufsize = BIO_gets(bp, buf, size); 201280297Sjkim else 202280297Sjkim break; 203280297Sjkim } 204280297Sjkim bs->length = num; 205280297Sjkim bs->data = s; 206280297Sjkim ret = 1; 207280297Sjkim err: 208280297Sjkim if (0) { 209280297Sjkim err_sl: 210280297Sjkim ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE); 211280297Sjkim } 212306195Sjkim if (ret != 1) 213306195Sjkim OPENSSL_free(s); 214280297Sjkim return (ret); 215280297Sjkim} 216