// File: /workspace/github_c_makefile_star2_O2/fm4dd[P]learn-ssl/certstack.c
// Function: main
int main() {

  STACK_OF(X509_INFO) *certstack;
  const char   ca_filestr[] = "./demo/ca-bundle.pem";
  X509_INFO *stack_item     = NULL;
  X509_NAME    *certsubject = NULL;
  BIO             *stackbio = NULL;
  BIO               *outbio = NULL;
  X509                *cert = NULL;
  int i;

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

  /* ---------------------------------------------------------- *
   * Load the file with the list of certificates in PEM format  *
   * ---------------------------------------------------------- */
  if (BIO_read_filename(stackbio, ca_filestr) <= 0) {
    BIO_printf(outbio, "Error loading cert bundle into memory: %s\n", ca_filestr);
    exit(1);
  }

  certstack = PEM_X509_INFO_read_bio(stackbio, NULL, NULL, NULL);

  /* ---------------------------------------------------------- *
   * Count the number of certs that are now on the stack        *
   * ---------------------------------------------------------- */
   BIO_printf(outbio, "# of stack certs: %d\n",
                      sk_X509_INFO_num(certstack));

  /* ---------------------------------------------------------- *
   * Cycle through the stack to display various cert data       *
   * ---------------------------------------------------------- */
  for (i = 0; i < sk_X509_INFO_num(certstack); i++) {
    char subject_cn[256] = "** n/a **";
    long cert_version;

    stack_item = sk_X509_INFO_value(certstack, i);

    certsubject = X509_get_subject_name(stack_item->x509);
    X509_NAME_get_text_by_NID(certsubject, NID_commonName,
                                           subject_cn, 256);
    cert_version = (X509_get_version(stack_item->x509)+1);

    BIO_printf(outbio, "Cert #%.2d v%ld CN: %.70s\n", i, 
                                  cert_version, subject_cn);
  }

  /* ---------------------------------------------------------- *
   * Free up the resources                                      *
   * ---------------------------------------------------------- */
  sk_X509_INFO_pop_free(certstack, X509_INFO_free);
  X509_free(cert);
  BIO_free_all(stackbio);
  BIO_free_all(outbio);
  exit(0);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x138, %rsp            # imm = 0x138
movaps 0xdcc(%rip), %xmm0      # 0x2010
leaq 0x10(%rsp), %r14
movaps %xmm0, (%r14)
movabsq $0x6d65702e656c64, %rax # imm = 0x6D65702E656C64
movq %rax, 0xd(%r14)
callq 0x1040
movq %rax, %rdi
callq 0x1100
movq %rax, %r15
movq 0x2d56(%rip), %rax      # 0x3fc8
movq (%rax), %rdi
xorl %esi, %esi
callq 0x1090
movq %rax, %rbx
pushq $0x6c
popq %rsi
pushq $0x3
popq %rdx
movq %r15, %rdi
movq %r14, %rcx
callq 0x1030
testl %eax, %eax
jg 0x12b2
leaq 0xd8a(%rip), %rsi       # 0x2025
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1120
pushq $0x1
popq %rdi
callq 0x10e0
movq %r15, 0x8(%rsp)
movq %r15, %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x1050
movq %rax, %r15
movq %rax, %rdi
callq 0x1070
leaq 0xd79(%rip), %rsi       # 0x2050
movq %rbx, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x1120
leaq 0x30(%rsp), %r13
leaq 0xd77(%rip), %r14       # 0x2066
xorl %r12d, %r12d
movq %r15, %rdi
callq 0x1070
cmpl %eax, %r12d
jge 0x1361
movl $0x100, %edx            # imm = 0x100
movq %r13, %rdi
leaq 0xd82(%rip), %rsi       # 0x2090
callq 0x10a0
movq %r15, %rdi
movl %r12d, %esi
callq 0x10f0
movq %rax, %rbp
movq (%rax), %rdi
callq 0x10b0
movq %rax, %rdi
pushq $0xd
popq %rsi
movq %r13, %rdx
movl $0x100, %ecx            # imm = 0x100
callq 0x10c0
movq (%rbp), %rdi
callq 0x10d0
leaq 0x1(%rax), %rcx
movq %rbx, %rdi
movq %r14, %rsi
movl %r12d, %edx
movq %r13, %r8
xorl %eax, %eax
callq 0x1120
incl %r12d
jmp 0x12f2
movq 0x2c68(%rip), %rsi      # 0x3fd0
movq %r15, %rdi
callq 0x1110
xorl %edi, %edi
callq 0x1080
movq 0x8(%rsp), %rdi
callq 0x1060
movq %rbx, %rdi
callq 0x1060
xorl %edi, %edi
callq 0x10e0