// 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 <assert.h>

#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/x509.h>

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


using namespace bssl;

int X509_print_ex_fp(FILE *fp, const X509 *x, unsigned long nmflag,
                     unsigned long cflag) {
  BIO *b = BIO_new_fp(fp, BIO_NOCLOSE);
  if (b == nullptr) {
    OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
    return 0;
  }
  int ret = X509_print_ex(b, x, nmflag, cflag);
  BIO_free(b);
  return ret;
}

int X509_print_fp(FILE *fp, const X509 *x) {
  return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
}

int X509_print(BIO *bp, const X509 *x) {
  return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
}

int X509_print_ex(BIO *bp, const X509 *x, unsigned long nmflags,
                  unsigned long cflag) {
  auto *impl = FromOpaque(x);
  char mlch = ' ';
  int nmindent = 0;
  if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
    mlch = '\n';
    nmindent = 12;
  }

  if (nmflags == X509_FLAG_COMPAT) {
    nmindent = 16;
  }

  if (!(cflag & X509_FLAG_NO_HEADER)) {
    if (BIO_write(bp, "Certificate:\n", 13) <= 0) {
      return 0;
    }
    if (BIO_write(bp, "    Data:\n", 10) <= 0) {
      return 0;
    }
  }
  if (!(cflag & X509_FLAG_NO_VERSION)) {
    long l = X509_get_version(x);
    assert(X509_VERSION_1 <= l && l <= X509_VERSION_3);
    if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1,
                   (unsigned long)l) <= 0) {
      return 0;
    }
  }
  if (!(cflag & X509_FLAG_NO_SERIAL)) {
    if (BIO_write(bp, "        Serial Number:", 22) <= 0) {
      return 0;
    }

    const ASN1_INTEGER *serial = X509_get0_serialNumber(x);
    uint64_t serial_u64;
    if (ASN1_INTEGER_get_uint64(&serial_u64, serial)) {
      assert(serial->type != V_ASN1_NEG_INTEGER);
      if (BIO_printf(bp, " %" PRIu64 " (0x%" PRIx64 ")\n", serial_u64,
                     serial_u64) <= 0) {
        return 0;
      }
    } else {
      ERR_clear_error();  // Clear |ASN1_INTEGER_get_uint64|'s error.
      const char *neg =
          (serial->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
      if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0) {
        return 0;
      }

      for (int i = 0; i < serial->length; i++) {
        if (BIO_printf(bp, "%02x%c", serial->data[i],
                       ((i + 1 == serial->length) ? '\n' : ':')) <= 0) {
          return 0;
        }
      }
    }
  }

  if (!(cflag & X509_FLAG_NO_SIGNAME)) {
    if (X509_signature_print(bp, &impl->tbs_sig_alg, nullptr) <= 0) {
      return 0;
    }
  }

  if (!(cflag & X509_FLAG_NO_ISSUER)) {
    if (BIO_printf(bp, "        Issuer:%c", mlch) <= 0) {
      return 0;
    }
    if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags) <
        0) {
      return 0;
    }
    if (BIO_write(bp, "\n", 1) <= 0) {
      return 0;
    }
  }
  if (!(cflag & X509_FLAG_NO_VALIDITY)) {
    if (BIO_write(bp, "        Validity\n", 17) <= 0) {
      return 0;
    }
    if (BIO_write(bp, "            Not Before: ", 24) <= 0) {
      return 0;
    }
    if (!ASN1_TIME_print(bp, X509_get0_notBefore(x))) {
      return 0;
    }
    if (BIO_write(bp, "\n            Not After : ", 25) <= 0) {
      return 0;
    }
    if (!ASN1_TIME_print(bp, X509_get0_notAfter(x))) {
      return 0;
    }
    if (BIO_write(bp, "\n", 1) <= 0) {
      return 0;
    }
  }
  if (!(cflag & X509_FLAG_NO_SUBJECT)) {
    if (BIO_printf(bp, "        Subject:%c", mlch) <= 0) {
      return 0;
    }
    if (X509_NAME_print_ex(bp, X509_get_subject_name(x), nmindent, nmflags) <
        0) {
      return 0;
    }
    if (BIO_write(bp, "\n", 1) <= 0) {
      return 0;
    }
  }
  if (!(cflag & X509_FLAG_NO_PUBKEY)) {
    if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0) {
      return 0;
    }
    if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) {
      return 0;
    }
    if (i2a_ASN1_OBJECT(bp, impl->key.algor.algorithm) <= 0) {
      return 0;
    }
    if (BIO_puts(bp, "\n") <= 0) {
      return 0;
    }

    const EVP_PKEY *pkey = X509_get0_pubkey(x);
    if (pkey == nullptr) {
      BIO_printf(bp, "%12sUnable to load Public Key\n", "");
      ERR_print_errors(bp);
    } else {
      EVP_PKEY_print_public(bp, pkey, 16, nullptr);
    }
  }

  if (!(cflag & X509_FLAG_NO_IDS)) {
    if (impl->issuerUID) {
      if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0) {
        return 0;
      }
      if (!X509_signature_dump(bp, impl->issuerUID, 12)) {
        return 0;
      }
    }
    if (impl->subjectUID) {
      if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0) {
        return 0;
      }
      if (!X509_signature_dump(bp, impl->subjectUID, 12)) {
        return 0;
      }
    }
  }

  if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
    X509V3_extensions_print(bp, "X509v3 extensions", impl->extensions, cflag,
                            8);
  }

  if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
    if (X509_signature_print(bp, &impl->sig_alg, &impl->signature) <= 0) {
      return 0;
    }
  }
  if (!(cflag & X509_FLAG_NO_AUX)) {
    if (!X509_CERT_AUX_print(bp, impl->aux, 0)) {
      return 0;
    }
  }

  return 1;
}

int X509_signature_print(BIO *bp, const X509_ALGOR *sigalg,
                         const ASN1_STRING *sig) {
  if (BIO_puts(bp, "    Signature Algorithm: ") <= 0) {
    return 0;
  }
  if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) {
    return 0;
  }

  // RSA-PSS signatures have parameters to print.
  int sig_nid = OBJ_obj2nid(sigalg->algorithm);
  if (sig_nid == NID_rsassaPss &&
      !x509_print_rsa_pss_params(bp, sigalg, 9, nullptr)) {
    return 0;
  }

  if (sig) {
    return X509_signature_dump(bp, sig, 9);
  } else if (BIO_puts(bp, "\n") <= 0) {
    return 0;
  }
  return 1;
}

int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase) {
  char *s, *c, *b;
  int ret = 0, i;

  b = X509_NAME_oneline(name, nullptr, 0);
  if (!b) {
    return 0;
  }
  if (!*b) {
    OPENSSL_free(b);
    return 1;
  }
  s = b + 1;  // skip the first slash

  c = s;
  for (;;) {
    if (((*s == '/') && ((s[1] >= 'A') && (s[1] <= 'Z') &&
                         ((s[2] == '=') || ((s[2] >= 'A') && (s[2] <= 'Z') &&
                                            (s[3] == '='))))) ||
        (*s == '\0')) {
      i = s - c;
      if (BIO_write(bp, c, i) != i) {
        goto err;
      }
      c = s + 1;  // skip following slash
      if (*s != '\0') {
        if (BIO_write(bp, ", ", 2) != 2) {
          goto err;
        }
      }
    }
    if (*s == '\0') {
      break;
    }
    s++;
  }

  ret = 1;
  if (0) {
  err:
    OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
  }
  OPENSSL_free(b);
  return ret;
}
