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

#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/x509.h>

#include "internal.h"


int X509_REQ_print_fp(FILE *fp, X509_REQ *x) {
  BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE);
  if (bio == NULL) {
    OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
    return 0;
  }
  int ret = X509_REQ_print(bio, x);
  BIO_free(bio);
  return ret;
}

int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags,
                      unsigned long cflag) {
  long l;
  STACK_OF(X509_ATTRIBUTE) *sk;
  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;
  }

  X509_REQ_INFO *ri = x->req_info;
  if (!(cflag & X509_FLAG_NO_HEADER)) {
    if (BIO_write(bio, "Certificate Request:\n", 21) <= 0 ||
        BIO_write(bio, "    Data:\n", 10) <= 0) {
      goto err;
    }
  }
  if (!(cflag & X509_FLAG_NO_VERSION)) {
    l = X509_REQ_get_version(x);
    // Only zero, |X509_REQ_VERSION_1|, is valid but our parser accepts some
    // invalid values for compatibility.
    assert(0 <= l && l <= 2);
    if (BIO_printf(bio, "%8sVersion: %ld (0x%lx)\n", "", l + 1,
                   (unsigned long)l) <= 0) {
      goto err;
    }
  }
  if (!(cflag & X509_FLAG_NO_SUBJECT)) {
    if (BIO_printf(bio, "        Subject:%c", mlch) <= 0 ||
        X509_NAME_print_ex(bio, ri->subject, nmindent, nmflags) < 0 ||
        BIO_write(bio, "\n", 1) <= 0) {
      goto err;
    }
  }
  if (!(cflag & X509_FLAG_NO_PUBKEY)) {
    if (BIO_write(bio, "        Subject Public Key Info:\n", 33) <= 0 ||
        BIO_printf(bio, "%12sPublic Key Algorithm: ", "") <= 0 ||
        i2a_ASN1_OBJECT(bio, ri->pubkey->algor.algorithm) <= 0 ||
        BIO_puts(bio, "\n") <= 0) {
      goto err;
    }

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

  if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
    if (BIO_printf(bio, "%8sAttributes:\n", "") <= 0) {
      goto err;
    }

    sk = x->req_info->attributes;
    if (sk_X509_ATTRIBUTE_num(sk) == 0) {
      if (BIO_printf(bio, "%12sa0:00\n", "") <= 0) {
        goto err;
      }
    } else {
      size_t i;
      for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
        X509_ATTRIBUTE *a = sk_X509_ATTRIBUTE_value(sk, i);
        ASN1_OBJECT *aobj = X509_ATTRIBUTE_get0_object(a);

        if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) {
          continue;
        }

        if (BIO_printf(bio, "%12s", "") <= 0) {
          goto err;
        }

        const int num_attrs = X509_ATTRIBUTE_count(a);
        const int obj_str_len = i2a_ASN1_OBJECT(bio, aobj);
        if (obj_str_len <= 0) {
          if (BIO_puts(bio, "(Unable to print attribute ID.)\n") < 0) {
            goto err;
          } else {
            continue;
          }
        }

        int j;
        for (j = 0; j < num_attrs; j++) {
          const ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(a, j);
          const int type = at->type;
          ASN1_BIT_STRING *bs = at->value.asn1_string;

          int k;
          for (k = 25 - obj_str_len; k > 0; k--) {
            if (BIO_write(bio, " ", 1) != 1) {
              goto err;
            }
          }

          if (BIO_puts(bio, ":") <= 0) {
            goto err;
          }

          if (type == V_ASN1_PRINTABLESTRING || type == V_ASN1_UTF8STRING ||
              type == V_ASN1_IA5STRING || type == V_ASN1_T61STRING) {
            if (BIO_write(bio, (char *)bs->data, bs->length) != bs->length) {
              goto err;
            }
            BIO_puts(bio, "\n");
          } else {
            BIO_puts(bio, "unable to print attribute\n");
          }
        }
      }
    }
  }

  if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
    STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(x);
    if (exts) {
      BIO_printf(bio, "%8sRequested Extensions:\n", "");

      for (size_t i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
        const X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i);
        if (BIO_printf(bio, "%12s", "") <= 0) {
          goto err;
        }
        const ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex);
        i2a_ASN1_OBJECT(bio, obj);
        const int is_critical = X509_EXTENSION_get_critical(ex);
        if (BIO_printf(bio, ": %s\n", is_critical ? "critical" : "") <= 0) {
          goto err;
        }
        if (!X509V3_EXT_print(bio, ex, cflag, 16)) {
          BIO_printf(bio, "%16s", "");
          ASN1_STRING_print(bio, X509_EXTENSION_get_data(ex));
        }
        if (BIO_write(bio, "\n", 1) <= 0) {
          goto err;
        }
      }
      sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
    }
  }

  if (!(cflag & X509_FLAG_NO_SIGDUMP) &&
      !X509_signature_print(bio, x->sig_alg, x->signature)) {
    goto err;
  }

  return 1;

err:
  OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
  return 0;
}

int X509_REQ_print(BIO *bio, X509_REQ *req) {
  return X509_REQ_print_ex(bio, req, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
}
