1/* 2 * Copyright (c) 2011-12 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* x_long.c */ 24/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 25 * project 2000. 26 */ 27/* ==================================================================== 28 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 29 * 30 * Redistribution and use in source and binary forms, with or without 31 * modification, are permitted provided that the following conditions 32 * are met: 33 * 34 * 1. Redistributions of source code must retain the above copyright 35 * notice, this list of conditions and the following disclaimer. 36 * 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in 39 * the documentation and/or other materials provided with the 40 * distribution. 41 * 42 * 3. All advertising materials mentioning features or use of this 43 * software must display the following acknowledgment: 44 * "This product includes software developed by the OpenSSL Project 45 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 46 * 47 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 48 * endorse or promote products derived from this software without 49 * prior written permission. For written permission, please contact 50 * licensing@OpenSSL.org. 51 * 52 * 5. Products derived from this software may not be called "OpenSSL" 53 * nor may "OpenSSL" appear in their names without prior written 54 * permission of the OpenSSL Project. 55 * 56 * 6. Redistributions of any form whatsoever must retain the following 57 * acknowledgment: 58 * "This product includes software developed by the OpenSSL Project 59 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 60 * 61 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 62 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 64 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 65 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 66 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 67 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 68 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 70 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 71 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 72 * OF THE POSSIBILITY OF SUCH DAMAGE. 73 * ==================================================================== 74 * 75 * This product includes cryptographic software written by Eric Young 76 * (eay@cryptsoft.com). This product includes software written by Tim 77 * Hudson (tjh@cryptsoft.com). 78 * 79 */ 80 81#include <sys/types.h> 82 83#include <stdio.h> 84#include <stdlib.h> 85#include <string.h> 86 87#if 0 88#include "cryptlib.h" 89#include <openssl/asn1t.h> 90#include <openssl/bn.h> 91 92#else 93 94#include "cs-asn1t.h" 95#include "cs-bn.h" 96#endif 97 98/* Custom primitive type for long handling. This converts between an ASN1_INTEGER 99 * and a long directly. 100 */ 101 102 103static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it); 104static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it); 105 106static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it); 107static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); 108 109static ASN1_PRIMITIVE_FUNCS long_pf = { 110 NULL, 0, 111 long_new, 112 long_free, 113 long_free, /* Clear should set to initial value */ 114 long_c2i, 115 long_i2c 116}; 117 118ASN1_ITEM_start(LONG) 119 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG" 120ASN1_ITEM_end(LONG) 121 122ASN1_ITEM_start(ZLONG) 123 ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG" 124ASN1_ITEM_end(ZLONG) 125 126static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it) 127{ 128 *(long *)pval = it->size; 129 return 1; 130} 131 132static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it) 133{ 134 *(long *)pval = it->size; 135} 136 137static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it) 138{ 139 long ltmp; 140 unsigned long utmp; 141 int clen, pad, i; 142 /* this exists to bypass broken gcc optimization */ 143 char *cp = (char *)pval; 144 145 /* use memcpy, because we may not be long aligned */ 146 memcpy(<mp, cp, sizeof(long)); 147 148 if(ltmp == it->size) return -1; 149 /* Convert the long to positive: we subtract one if negative so 150 * we can cleanly handle the padding if only the MSB of the leading 151 * octet is set. 152 */ 153 if(ltmp < 0) utmp = -ltmp - 1; 154 else utmp = ltmp; 155 clen = BN_num_bits_word(utmp); 156 /* If MSB of leading octet set we need to pad */ 157 if(!(clen & 0x7)) pad = 1; 158 else pad = 0; 159 160 /* Convert number of bits to number of octets */ 161 clen = (clen + 7) >> 3; 162 163 if(cont) { 164 if(pad) *cont++ = (ltmp < 0) ? 0xff : 0; 165 for(i = clen - 1; i >= 0; i--) { 166 cont[i] = (unsigned char)(utmp & 0xff); 167 if(ltmp < 0) cont[i] ^= 0xff; 168 utmp >>= 8; 169 } 170 } 171 return clen + pad; 172} 173 174static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, 175 int utype, char *free_cont, const ASN1_ITEM *it) 176{ 177 int neg, i; 178 long ltmp; 179 unsigned long utmp = 0; 180 char *cp = (char *)pval; 181 if(len > (int)sizeof(long)) { 182 /* ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); */ 183 return 0; 184 } 185 /* Is it negative? */ 186 if(len && (cont[0] & 0x80)) neg = 1; 187 else neg = 0; 188 utmp = 0; 189 for(i = 0; i < len; i++) { 190 utmp <<= 8; 191 if(neg) utmp |= cont[i] ^ 0xff; 192 else utmp |= cont[i]; 193 } 194 ltmp = (long)utmp; 195 if(neg) { 196 ltmp++; 197 ltmp = -ltmp; 198 } 199 if(ltmp == it->size) { 200 /* ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); */ 201 return 0; 202 } 203 memcpy(cp, <mp, sizeof(long)); 204 return 1; 205} 206