155714Skris/* crypto/asn1/a_enum.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 64280297Sjkim/* 6555714Skris * Code for ENUMERATED type: identical to INTEGER apart from a different tag. 6655714Skris * for comments on encoding see a_int.c 6755714Skris */ 6855714Skris 6955714Skrisint ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) 70280297Sjkim{ 71280297Sjkim int j, k; 72280297Sjkim unsigned int i; 73280297Sjkim unsigned char buf[sizeof(long) + 1]; 74280297Sjkim long d; 7555714Skris 76280297Sjkim a->type = V_ASN1_ENUMERATED; 77280297Sjkim if (a->length < (int)(sizeof(long) + 1)) { 78280297Sjkim if (a->data != NULL) 79280297Sjkim OPENSSL_free(a->data); 80280297Sjkim if ((a->data = 81280297Sjkim (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL) 82280297Sjkim memset((char *)a->data, 0, sizeof(long) + 1); 83280297Sjkim } 84280297Sjkim if (a->data == NULL) { 85280297Sjkim ASN1err(ASN1_F_ASN1_ENUMERATED_SET, ERR_R_MALLOC_FAILURE); 86280297Sjkim return (0); 87280297Sjkim } 88280297Sjkim d = v; 89280297Sjkim if (d < 0) { 90280297Sjkim d = -d; 91280297Sjkim a->type = V_ASN1_NEG_ENUMERATED; 92280297Sjkim } 9355714Skris 94280297Sjkim for (i = 0; i < sizeof(long); i++) { 95280297Sjkim if (d == 0) 96280297Sjkim break; 97280297Sjkim buf[i] = (int)d & 0xff; 98280297Sjkim d >>= 8; 99280297Sjkim } 100280297Sjkim j = 0; 101280297Sjkim for (k = i - 1; k >= 0; k--) 102280297Sjkim a->data[j++] = buf[k]; 103280297Sjkim a->length = j; 104280297Sjkim return (1); 105280297Sjkim} 10655714Skris 10755714Skrislong ASN1_ENUMERATED_get(ASN1_ENUMERATED *a) 108280297Sjkim{ 109280297Sjkim int neg = 0, i; 110280297Sjkim long r = 0; 11155714Skris 112280297Sjkim if (a == NULL) 113280297Sjkim return (0L); 114280297Sjkim i = a->type; 115280297Sjkim if (i == V_ASN1_NEG_ENUMERATED) 116280297Sjkim neg = 1; 117280297Sjkim else if (i != V_ASN1_ENUMERATED) 118280297Sjkim return -1; 11955714Skris 120280297Sjkim if (a->length > (int)sizeof(long)) { 121280297Sjkim /* hmm... a bit ugly */ 122280297Sjkim return (0xffffffffL); 123280297Sjkim } 124280297Sjkim if (a->data == NULL) 125280297Sjkim return 0; 12655714Skris 127280297Sjkim for (i = 0; i < a->length; i++) { 128280297Sjkim r <<= 8; 129280297Sjkim r |= (unsigned char)a->data[i]; 130280297Sjkim } 131280297Sjkim if (neg) 132280297Sjkim r = -r; 133280297Sjkim return (r); 134280297Sjkim} 135280297Sjkim 13655714SkrisASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai) 137280297Sjkim{ 138280297Sjkim ASN1_ENUMERATED *ret; 139280297Sjkim int len, j; 14055714Skris 141280297Sjkim if (ai == NULL) 142280297Sjkim ret = M_ASN1_ENUMERATED_new(); 143280297Sjkim else 144280297Sjkim ret = ai; 145280297Sjkim if (ret == NULL) { 146280297Sjkim ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_NESTED_ASN1_ERROR); 147280297Sjkim goto err; 148280297Sjkim } 149280297Sjkim if (BN_is_negative(bn)) 150280297Sjkim ret->type = V_ASN1_NEG_ENUMERATED; 151280297Sjkim else 152280297Sjkim ret->type = V_ASN1_ENUMERATED; 153280297Sjkim j = BN_num_bits(bn); 154280297Sjkim len = ((j == 0) ? 0 : ((j / 8) + 1)); 155280297Sjkim if (ret->length < len + 4) { 156280297Sjkim unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4); 157280297Sjkim if (!new_data) { 158280297Sjkim ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); 159280297Sjkim goto err; 160280297Sjkim } 161280297Sjkim ret->data = new_data; 162280297Sjkim } 163100936Snectar 164280297Sjkim ret->length = BN_bn2bin(bn, ret->data); 165280297Sjkim return (ret); 166280297Sjkim err: 167280297Sjkim if (ret != ai) 168280297Sjkim M_ASN1_ENUMERATED_free(ret); 169280297Sjkim return (NULL); 170280297Sjkim} 17155714Skris 17255714SkrisBIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn) 173280297Sjkim{ 174280297Sjkim BIGNUM *ret; 17555714Skris 176280297Sjkim if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) 177280297Sjkim ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN, ASN1_R_BN_LIB); 178280297Sjkim else if (ai->type == V_ASN1_NEG_ENUMERATED) 179280297Sjkim BN_set_negative(ret, 1); 180280297Sjkim return (ret); 181280297Sjkim} 182