1 /* 2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <limits.h> 11 #include <stdio.h> 12 #include "internal/cryptlib.h" 13 #include <openssl/asn1.h> 14 #include "asn1_local.h" 15 16 int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) 17 { 18 return ASN1_STRING_set(x, d, len); 19 } 20 21 int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) 22 { 23 int ret, j, bits, len; 24 unsigned char *p, *d; 25 26 if (a == NULL) 27 return 0; 28 29 len = a->length; 30 31 if (len > 0) { 32 if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) { 33 bits = (int)a->flags & 0x07; 34 } else { 35 for (; len > 0; len--) { 36 if (a->data[len - 1]) 37 break; 38 } 39 j = a->data[len - 1]; 40 if (j & 0x01) 41 bits = 0; 42 else if (j & 0x02) 43 bits = 1; 44 else if (j & 0x04) 45 bits = 2; 46 else if (j & 0x08) 47 bits = 3; 48 else if (j & 0x10) 49 bits = 4; 50 else if (j & 0x20) 51 bits = 5; 52 else if (j & 0x40) 53 bits = 6; 54 else if (j & 0x80) 55 bits = 7; 56 else 57 bits = 0; /* should not happen */ 58 } 59 } else 60 bits = 0; 61 62 ret = 1 + len; 63 if (pp == NULL) 64 return ret; 65 66 p = *pp; 67 68 *(p++) = (unsigned char)bits; 69 d = a->data; 70 if (len > 0) { 71 memcpy(p, d, len); 72 p += len; 73 p[-1] &= (0xff << bits); 74 } 75 *pp = p; 76 return ret; 77 } 78 79 ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, 80 const unsigned char **pp, long len) 81 { 82 ASN1_BIT_STRING *ret = NULL; 83 const unsigned char *p; 84 unsigned char *s; 85 int i; 86 87 if (len < 1) { 88 i = ASN1_R_STRING_TOO_SHORT; 89 goto err; 90 } 91 92 if (len > INT_MAX) { 93 i = ASN1_R_STRING_TOO_LONG; 94 goto err; 95 } 96 97 if ((a == NULL) || ((*a) == NULL)) { 98 if ((ret = ASN1_BIT_STRING_new()) == NULL) 99 return NULL; 100 } else 101 ret = (*a); 102 103 p = *pp; 104 i = *(p++); 105 if (i > 7) { 106 i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT; 107 goto err; 108 } 109 /* 110 * We do this to preserve the settings. If we modify the settings, via 111 * the _set_bit function, we will recalculate on output 112 */ 113 ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */ 114 ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */ 115 116 if (len-- > 1) { /* using one because of the bits left byte */ 117 s = OPENSSL_malloc((int)len); 118 if (s == NULL) { 119 i = ERR_R_MALLOC_FAILURE; 120 goto err; 121 } 122 memcpy(s, p, (int)len); 123 s[len - 1] &= (0xff << i); 124 p += len; 125 } else 126 s = NULL; 127 128 ret->length = (int)len; 129 OPENSSL_free(ret->data); 130 ret->data = s; 131 ret->type = V_ASN1_BIT_STRING; 132 if (a != NULL) 133 (*a) = ret; 134 *pp = p; 135 return ret; 136 err: 137 ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i); 138 if ((a == NULL) || (*a != ret)) 139 ASN1_BIT_STRING_free(ret); 140 return NULL; 141 } 142 143 /* 144 * These next 2 functions from Goetz Babin-Ebell. 145 */ 146 int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) 147 { 148 int w, v, iv; 149 unsigned char *c; 150 151 w = n / 8; 152 v = 1 << (7 - (n & 0x07)); 153 iv = ~v; 154 if (!value) 155 v = 0; 156 157 if (a == NULL) 158 return 0; 159 160 a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */ 161 162 if ((a->length < (w + 1)) || (a->data == NULL)) { 163 if (!value) 164 return 1; /* Don't need to set */ 165 c = OPENSSL_clear_realloc(a->data, a->length, w + 1); 166 if (c == NULL) { 167 ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE); 168 return 0; 169 } 170 if (w + 1 - a->length > 0) 171 memset(c + a->length, 0, w + 1 - a->length); 172 a->data = c; 173 a->length = w + 1; 174 } 175 a->data[w] = ((a->data[w]) & iv) | v; 176 while ((a->length > 0) && (a->data[a->length - 1] == 0)) 177 a->length--; 178 return 1; 179 } 180 181 int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n) 182 { 183 int w, v; 184 185 w = n / 8; 186 v = 1 << (7 - (n & 0x07)); 187 if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) 188 return 0; 189 return ((a->data[w] & v) != 0); 190 } 191 192 /* 193 * Checks if the given bit string contains only bits specified by 194 * the flags vector. Returns 0 if there is at least one bit set in 'a' 195 * which is not specified in 'flags', 1 otherwise. 196 * 'len' is the length of 'flags'. 197 */ 198 int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, 199 const unsigned char *flags, int flags_len) 200 { 201 int i, ok; 202 /* Check if there is one bit set at all. */ 203 if (!a || !a->data) 204 return 1; 205 206 /* 207 * Check each byte of the internal representation of the bit string. 208 */ 209 ok = 1; 210 for (i = 0; i < a->length && ok; ++i) { 211 unsigned char mask = i < flags_len ? ~flags[i] : 0xff; 212 /* We are done if there is an unneeded bit set. */ 213 ok = (a->data[i] & mask) == 0; 214 } 215 return ok; 216 } 217