// File: /workspace/github_c_makefile_star2_O2/fm4dd[P]learn-ssl/crldisplay.c
// Function: main
int main() {
  const char    crl_filestr[] = "./demo/webcert-crl.der";
  BIO                 *crlbio = NULL;
  BIO                 *outbio = NULL;
  X509_CRL            *mycrl  = NULL;
  X509_NAME           *issuer = NULL;
  STACK_OF(X509_REVOKED) *rev = NULL;
  X509_REVOKED     *rev_entry = NULL;
  X509_EXTENSION      *reason = NULL;
  const ASN1_BIT_STRING *asn1_sig = NULL;
  const X509_ALGOR      *sig_type = NULL;
  size_t                sig_bytes = 0;
  char         sig_type_str[1024] = "";
  const ASN1_TIME *last_update, *next_update;
  const ASN1_INTEGER *ser = NULL;
  BIGNUM *bn = NULL;
  int i, extnum, revnum;
  long version;

  /* ---------------------------------------------------------- *
   * Create the Input/Output BIO's.                             *
   * ---------------------------------------------------------- */
  crlbio = BIO_new(BIO_s_file());
  outbio = BIO_new(BIO_s_file());
  outbio = BIO_new_fp(stdout, BIO_NOCLOSE);

  /* ---------------------------------------------------------- *
   * Load the certificate revocation list from file (DER).      *
   * ---------------------------------------------------------- */
  if (BIO_read_filename(crlbio, crl_filestr) <= 0) {
    BIO_printf(outbio, "Error loading CRL file into memory: %s\n", crl_filestr);
    exit(1);
  }

  if ((mycrl = X509_CRL_new()) == NULL) {
    BIO_printf(outbio, "Error creating a new CRL object\n");
    exit(1);
  }
  BIO_printf(outbio, "Successful creation of a new empty CRL object\n");

  if((mycrl = d2i_X509_CRL_bio(crlbio, NULL)) == NULL) {
    BIO_printf(outbio, "Error loading CRL object data.\n");
    exit(1);
  }
  BIO_printf(outbio, "CRL %s converted to internal BIO object\n", crl_filestr);

  /* ---------------------------------------------------------- *
   * Print the CRL Version Number                               *
   * ---------------------------------------------------------- */
  version = X509_CRL_get_version(mycrl);
  BIO_printf(outbio, "This CRL Version Num: %lu (0x%lx)\n", version+1, version);

  /* ---------------------------------------------------------- *
   * Print the CRL Issuer Information                           *
   * ---------------------------------------------------------- */
  issuer = X509_NAME_new();
  issuer = X509_CRL_get_issuer(mycrl);
  BIO_printf(outbio, "This CRL Issuer Info: ");
  X509_NAME_print_ex(outbio, issuer, 0, XN_FLAG_ONELINE);
  BIO_printf(outbio, "\n");

  /* ---------------------------------------------------------- *
   * Print the CRL Issue Date and Time                          *
   * ---------------------------------------------------------- */
  if ((last_update = X509_CRL_get0_lastUpdate(mycrl))) {
    BIO_printf(outbio, "This CRL Release Date: ");
    ASN1_TIME_print(outbio, last_update);
    BIO_printf(outbio, "\n");
  }

  /* ---------------------------------------------------------- *
   * Print the CRL Next Release Date and Time                   *
   * ---------------------------------------------------------- */
  if ((next_update = X509_CRL_get0_nextUpdate(mycrl))) {
    BIO_printf(outbio, "Next CRL Release Date: ");
    ASN1_TIME_print(outbio, next_update);
    BIO_printf(outbio, "\n");
  }

  /* ---------------------------------------------------------- *
   * Print the CRL Signature Algorithm                          *
   * ---------------------------------------------------------- */
  X509_CRL_get0_signature(mycrl, &asn1_sig, &sig_type);
  sig_bytes = asn1_sig->length;
  OBJ_obj2txt(sig_type_str, sizeof(sig_type_str), sig_type->algorithm, 0);

  BIO_printf(outbio, " CRL Signature Format: %s\n", sig_type_str);
  BIO_printf(outbio, " CRL Signature Length: %d Bytes\n", (int) sig_bytes);

  /* ---------------------------------------------------------- *
   * Print the Number of CRL Extensions (CRL may not have any)  *
   * ---------------------------------------------------------- */
  extnum = X509_CRL_get_ext_count(mycrl);
  BIO_printf(outbio, " Number of Extensions: %d\n", extnum);

  /* ---------------------------------------------------------- *
   * Print the Number of revoked Certs (CRL may not have any)   *
   * ---------------------------------------------------------- */
  rev = X509_CRL_get_REVOKED(mycrl);

  revnum = sk_X509_REVOKED_num(rev);
  BIO_printf(outbio, "Found # revoked certs: %d\n", revnum);

  /* ---------------------------------------------------------- *
   * Print the revoked Cert Info if avail. Limit output to 10   *
   * ---------------------------------------------------------- */
  if (revnum > 0 && revnum > 10) revnum = 10;

  for(i=0; i<revnum; i++) {
    rev_entry = sk_X509_REVOKED_value(rev, i);
    if(rev_entry == NULL)
       BIO_printf(outbio, "Error getting rewvoked cert info for: %d\n", i);

    /* ---------------------------------------------------------- *
     * Get cert serial from the revocation entry                  *
     * ---------------------------------------------------------- */
    ser = X509_REVOKED_get0_serialNumber(rev_entry);

    /* ---------------------------------------------------------- *
     * Convert the serial to a hex string                         *
     * ---------------------------------------------------------- */
    char *serialstr = BN_bn2hex(ASN1_INTEGER_to_BN(ser, bn));

    BIO_printf(outbio, "Revocation #: %d S/N: %s", i, serialstr);
    BIO_printf(outbio, " Date: ");
    ASN1_TIME_print(outbio, X509_REVOKED_get0_revocationDate(rev_entry));

    /* ---------------------------------------------------------- *
     * try to get the CRL reason, if the extension exists         *
     * ---------------------------------------------------------- */
    int loc = -1;
    loc = X509_REVOKED_get_ext_by_NID(rev_entry, NID_crl_reason, -1);
    reason = X509_REVOKED_get_ext(rev_entry, loc);
    if (loc > -1) X509V3_EXT_print(outbio, reason, 0, 2);
    BIO_printf(outbio, "\n");
  }

  X509_CRL_free(mycrl);
  BIO_free_all(crlbio);
  BIO_free_all(outbio);
  exit(0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x448, %rsp            # imm = 0x448
movaps 0xcdc(%rip), %xmm0      # 0x2010
leaq 0x20(%rsp), %r14
movaps %xmm0, (%r14)
movabsq $0x7265642e6c7263, %rax # imm = 0x7265642E6C7263
andq $0x0, 0x18(%rsp)
movq %rax, 0xf(%r14)
andq $0x0, 0x10(%rsp)
leaq 0x40(%rsp), %rdi
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x10e0
callq 0x1080
movq %rax, %rdi
callq 0x11e0
movq %rax, %r15
callq 0x1080
movq %rax, %rdi
callq 0x11e0
movq 0x2c44(%rip), %rax      # 0x3fd0
movq (%rax), %rdi
xorl %esi, %esi
callq 0x1110
movq %rax, %rbx
pushq $0x6c
popq %rsi
pushq $0x3
popq %rdx
movq %r15, %rdi
movq %r14, %rcx
callq 0x1050
testl %eax, %eax
jg 0x13c6
leaq 0xc72(%rip), %rsi       # 0x2027
leaq 0x20(%rsp), %rdx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1210
jmp 0x140a
callq 0x1160
testq %rax, %rax
jne 0x13d9
leaq 0xc78(%rip), %rsi       # 0x204f
jmp 0x1400
leaq 0xc90(%rip), %rsi       # 0x2070
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1210
movq %r15, %rdi
xorl %esi, %esi
callq 0x1150
testq %rax, %rax
jne 0x1412
leaq 0xc9f(%rip), %rsi       # 0x209f
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1210
pushq $0x1
popq %rdi
callq 0x1170
movq %rax, %r12
leaq 0xca3(%rip), %rsi       # 0x20bf
leaq 0x20(%rsp), %rdx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1210
movq %r12, %rdi
callq 0x10b0
leaq 0x1(%rax), %rdx
leaq 0xcaa(%rip), %rsi       # 0x20e8
movq %rbx, %rdi
movq %rax, %rcx
xorl %eax, %eax
callq 0x1210
callq 0x1130
movq %r12, %rdi
callq 0x1140
movq %rax, %r14
leaq 0xca9(%rip), %rsi       # 0x210b
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1210
movl $0x82031f, %ecx         # imm = 0x82031F
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0x1040
leaq 0xc84(%rip), %rsi       # 0x2109
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1210
movq %r12, %rdi
callq 0x1100
testq %rax, %rax
je 0x14cc
movq %rax, %r14
leaq 0xc7c(%rip), %rsi       # 0x2122
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1210
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1200
leaq 0xc47(%rip), %rsi       # 0x2109
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1210
movq %r15, 0x8(%rsp)
movq %r12, %rdi
callq 0x1090
testq %rax, %rax
je 0x150e
movq %rax, %r14
leaq 0xc52(%rip), %rsi       # 0x213a
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1210
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1200
leaq 0xc05(%rip), %rsi       # 0x2109
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1210
leaq 0x18(%rsp), %r14
leaq 0x10(%rsp), %r15
movq %r12, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x1060
movq (%r14), %rax
movl (%rax), %ebp
movq (%r15), %rax
movq (%rax), %rdx
leaq 0x40(%rsp), %r14
xorl %r15d, %r15d
movq %r14, %rdi
movl $0x400, %esi            # imm = 0x400
xorl %ecx, %ecx
callq 0x10f0
leaq 0xc03(%rip), %rsi       # 0x2152
movq %rbx, %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x1210
leaq 0xc0a(%rip), %rsi       # 0x216d
movq %rbx, %rdi
movl %ebp, %edx
xorl %eax, %eax
callq 0x1210
movq %r12, %rdi
callq 0x1190
leaq 0xc10(%rip), %rsi       # 0x218e
movq %rbx, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x1210
movq %r12, (%rsp)
movq %r12, %rdi
callq 0x1180
movq %rax, %r12
movq %rax, %rdi
callq 0x10d0
movl %eax, %ebp
leaq 0xbff(%rip), %rsi       # 0x21a9
movq %rbx, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x1210
cmpl $0xa, %ebp
pushq $0xa
popq %r13
cmovll %ebp, %r13d
testl %r13d, %r13d
cmovlel %r15d, %r13d
xorl %ebp, %ebp
cmpl %ebp, %r13d
je 0x1696
movq %r12, %rdi
movl %ebp, %esi
callq 0x11b0
movq %rax, %r15
testq %rax, %rax
jne 0x15f8
movq %rbx, %rdi
leaq 0xbd5(%rip), %rsi       # 0x21c4
movl %ebp, %edx
xorl %eax, %eax
callq 0x1210
movq %r15, %rdi
callq 0x11d0
movq %rax, %rdi
xorl %esi, %esi
callq 0x11a0
movq %rax, %rdi
callq 0x11f0
movq %rbx, %rdi
leaq 0xbd2(%rip), %rsi       # 0x21ee
movl %ebp, %edx
movq %rax, %rcx
xorl %eax, %eax
callq 0x1210
movq %rbx, %rdi
leaq 0xb00(%rip), %rsi       # 0x2132
xorl %eax, %eax
callq 0x1210
movq %r15, %rdi
callq 0x1070
movq %rbx, %rdi
movq %rax, %rsi
callq 0x1200
movq %r15, %rdi
movl $0x8d, %esi
pushq $-0x1
popq %rdx
callq 0x1120
movl %eax, %r14d
movq %r15, %rdi
movl %eax, %esi
callq 0x1030
testl %r14d, %r14d
js 0x167e
movq %rbx, %rdi
movq %rax, %rsi
xorl %edx, %edx
pushq $0x2
popq %rcx
callq 0x11c0
movq %rbx, %rdi
leaq 0xa81(%rip), %rsi       # 0x2109
xorl %eax, %eax
callq 0x1210
incl %ebp
jmp 0x15ca
movq (%rsp), %rdi
callq 0x10c0
movq 0x8(%rsp), %rdi
callq 0x10a0
movq %rbx, %rdi
callq 0x10a0
xorl %edi, %edi
callq 0x1170