// 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"


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 == NULL) {
    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) {
  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, &x->tbs_sig_alg, NULL) <= 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, x->key.algor.algorithm) <= 0) {
      return 0;
    }
    if (BIO_puts(bp, "\n") <= 0) {
      return 0;
    }

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

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

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

  if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
    if (X509_signature_print(bp, &x->sig_alg, &x->signature) <= 0) {
      return 0;
    }
  }
  if (!(cflag & X509_FLAG_NO_AUX)) {
    if (!X509_CERT_AUX_print(bp, x->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, 0)) {
    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, NULL, 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;
}
