1 /* 2 * Copyright (c) 2003 - 2005 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "der_locl.h" 35 #include "heim_asn1.h" 36 37 RCSID("$Id: extra.c 16672 2006-01-31 09:44:54Z lha $"); 38 39 int 40 encode_heim_any(unsigned char *p, size_t len, 41 const heim_any *data, size_t *size) 42 { 43 if (data->length > len) 44 return ASN1_OVERFLOW; 45 p -= data->length; 46 len -= data->length; 47 memcpy (p+1, data->data, data->length); 48 *size = data->length; 49 return 0; 50 } 51 52 int 53 decode_heim_any(const unsigned char *p, size_t len, 54 heim_any *data, size_t *size) 55 { 56 size_t len_len, length, l; 57 Der_class thisclass; 58 Der_type thistype; 59 unsigned int thistag; 60 int e; 61 62 memset(data, 0, sizeof(*data)); 63 64 e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l); 65 if (e) return e; 66 if (l > len) 67 return ASN1_OVERFLOW; 68 e = der_get_length(p + l, len - l, &length, &len_len); 69 if (e) return e; 70 if (length + len_len + l > len) 71 return ASN1_OVERFLOW; 72 73 data->data = malloc(length + len_len + l); 74 if (data->data == NULL) 75 return ENOMEM; 76 data->length = length + len_len + l; 77 memcpy(data->data, p, length + len_len + l); 78 79 if (size) 80 *size = length + len_len + l; 81 82 return 0; 83 } 84 85 void 86 free_heim_any(heim_any *data) 87 { 88 free(data->data); 89 data->data = NULL; 90 } 91 92 size_t 93 length_heim_any(const heim_any *data) 94 { 95 return data->length; 96 } 97 98 int 99 copy_heim_any(const heim_any *from, heim_any *to) 100 { 101 to->data = malloc(from->length); 102 if (to->data == NULL && from->length != 0) 103 return ENOMEM; 104 memcpy(to->data, from->data, from->length); 105 to->length = from->length; 106 return 0; 107 } 108 109 int 110 encode_heim_any_set(unsigned char *p, size_t len, 111 const heim_any_set *data, size_t *size) 112 { 113 return encode_heim_any(p, len, data, size); 114 } 115 116 117 int 118 decode_heim_any_set(const unsigned char *p, size_t len, 119 heim_any_set *data, size_t *size) 120 { 121 memset(data, 0, sizeof(*data)); 122 data->data = malloc(len); 123 if (data->data == NULL && len != 0) 124 return ENOMEM; 125 data->length = len; 126 memcpy(data->data, p, len); 127 if (size) *size = len; 128 return 0; 129 } 130 131 void 132 free_heim_any_set(heim_any_set *data) 133 { 134 free_heim_any(data); 135 } 136 137 size_t 138 length_heim_any_set(const heim_any *data) 139 { 140 return length_heim_any(data); 141 } 142 143 int 144 copy_heim_any_set(const heim_any_set *from, heim_any_set *to) 145 { 146 return copy_heim_any(from, to); 147 } 148 149 int 150 heim_any_cmp(const heim_any_set *p, const heim_any_set *q) 151 { 152 if (p->length != q->length) 153 return p->length - q->length; 154 return memcmp(p->data, q->data, p->length); 155 } 156