// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/asn1.h>

#include <limits.h>
#include <string.h>

#include <openssl/err.h>
#include <openssl/mem.h>

#include "../internal.h"
#include "internal.h"


int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, const unsigned char *d,
                        ossl_ssize_t len) {
  return ASN1_STRING_set(x, d, len);
}

int asn1_bit_string_length(const ASN1_BIT_STRING *str,
                           uint8_t *out_padding_bits) {
  int len = str->length;
  if (str->flags & ASN1_STRING_FLAG_BITS_LEFT) {
    // If the string is already empty, it cannot have padding bits.
    *out_padding_bits = len == 0 ? 0 : str->flags & 0x07;
    return len;
  }

  // TODO(https://crbug.com/boringssl/447): If we move this logic to
  // |ASN1_BIT_STRING_set_bit|, can we remove this representation?
  while (len > 0 && str->data[len - 1] == 0) {
    len--;
  }
  uint8_t padding_bits = 0;
  if (len > 0) {
    uint8_t last = str->data[len - 1];
    assert(last != 0);
    for (; padding_bits < 7; padding_bits++) {
      if (last & (1 << padding_bits)) {
        break;
      }
    }
  }
  *out_padding_bits = padding_bits;
  return len;
}

int ASN1_BIT_STRING_num_bytes(const ASN1_BIT_STRING *str, size_t *out) {
  uint8_t padding_bits;
  int len = asn1_bit_string_length(str, &padding_bits);
  if (padding_bits != 0) {
    return 0;
  }
  *out = len;
  return 1;
}

int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a, unsigned char **pp) {
  if (a == NULL) {
    return 0;
  }

  uint8_t bits;
  int len = asn1_bit_string_length(a, &bits);
  if (len > INT_MAX - 1) {
    OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
    return 0;
  }
  int ret = 1 + len;
  if (pp == NULL) {
    return ret;
  }

  uint8_t *p = *pp;
  *(p++) = bits;
  OPENSSL_memcpy(p, a->data, len);
  if (len > 0) {
    p[len - 1] &= (0xff << bits);
  }
  p += len;
  *pp = p;
  return ret;
}

ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
                                     const unsigned char **pp, long len) {
  ASN1_BIT_STRING *ret = NULL;
  const unsigned char *p;
  unsigned char *s;
  int padding;
  uint8_t padding_mask;

  if (len < 1) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
    goto err;
  }

  if (len > INT_MAX) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
    goto err;
  }

  if ((a == NULL) || ((*a) == NULL)) {
    if ((ret = ASN1_BIT_STRING_new()) == NULL) {
      return NULL;
    }
  } else {
    ret = (*a);
  }

  p = *pp;
  padding = *(p++);
  len--;
  if (padding > 7) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
    goto err;
  }

  // Unused bits in a BIT STRING must be zero.
  padding_mask = (1 << padding) - 1;
  if (padding != 0 && (len < 1 || (p[len - 1] & padding_mask) != 0)) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_PADDING);
    goto err;
  }

  // We do this to preserve the settings.  If we modify the settings, via
  // the _set_bit function, we will recalculate on output
  ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);    // clear
  ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding);  // set

  if (len > 0) {
    s = reinterpret_cast<uint8_t *>(OPENSSL_memdup(p, len));
    if (s == NULL) {
      goto err;
    }
    p += len;
  } else {
    s = NULL;
  }

  ret->length = (int)len;
  OPENSSL_free(ret->data);
  ret->data = s;
  ret->type = V_ASN1_BIT_STRING;
  if (a != NULL) {
    (*a) = ret;
  }
  *pp = p;
  return ret;
err:
  if ((ret != NULL) && ((a == NULL) || (*a != ret))) {
    ASN1_BIT_STRING_free(ret);
  }
  return NULL;
}

// These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) {
  int w, v, iv;
  unsigned char *c;

  w = n / 8;
  v = 1 << (7 - (n & 0x07));
  iv = ~v;
  if (!value) {
    v = 0;
  }

  if (a == NULL) {
    return 0;
  }

  a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);  // clear, set on write

  if ((a->length < (w + 1)) || (a->data == NULL)) {
    if (!value) {
      return 1;  // Don't need to set
    }
    if (a->data == NULL) {
      c = (unsigned char *)OPENSSL_malloc(w + 1);
    } else {
      c = (unsigned char *)OPENSSL_realloc(a->data, w + 1);
    }
    if (c == NULL) {
      return 0;
    }
    if (w + 1 - a->length > 0) {
      OPENSSL_memset(c + a->length, 0, w + 1 - a->length);
    }
    a->data = c;
    a->length = w + 1;
  }
  a->data[w] = ((a->data[w]) & iv) | v;
  while ((a->length > 0) && (a->data[a->length - 1] == 0)) {
    a->length--;
  }
  return 1;
}

int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n) {
  int w, v;

  w = n / 8;
  v = 1 << (7 - (n & 0x07));
  if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) {
    return 0;
  }
  return ((a->data[w] & v) != 0);
}

// Checks if the given bit string contains only bits specified by
// the flags vector. Returns 0 if there is at least one bit set in 'a'
// which is not specified in 'flags', 1 otherwise.
// 'len' is the length of 'flags'.
int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, const unsigned char *flags,
                          int flags_len) {
  int i, ok;
  // Check if there is one bit set at all.
  if (!a || !a->data) {
    return 1;
  }

  // Check each byte of the internal representation of the bit string.
  ok = 1;
  for (i = 0; i < a->length && ok; ++i) {
    unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
    // We are done if there is an unneeded bit set.
    ok = (a->data[i] & mask) == 0;
  }
  return ok;
}
