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

  const char ca_bundlestr[] = "./demo/ca-bundle.pem";
  const char cert_filestr[] = "./demo/cert-file.pem";

  BIO              *certbio = NULL;
  BIO               *outbio = NULL;
  X509          *error_cert = NULL;
  X509                *cert = NULL;
  X509_NAME    *certsubject = NULL;
  X509_STORE         *store = NULL;
  X509_STORE_CTX  *vrfy_ctx = NULL;
  int vrfy_err, ret;

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

  /* ---------------------------------------------------------- *
   * Initialize the global certificate validation store object. *
   * ---------------------------------------------------------- */
  if (!(store=X509_STORE_new()))
     BIO_printf(outbio, "Error creating X509_STORE_CTX object\n");

  /* ---------------------------------------------------------- *
   * Create the context structure for the validation operation. *
   * ---------------------------------------------------------- */
  vrfy_ctx = X509_STORE_CTX_new();

  /* ---------------------------------------------------------- *
   * Load the certificate and cacert chain from file (PEM).     *
   * ---------------------------------------------------------- */
  ret = BIO_read_filename(certbio, cert_filestr);
  if (! (cert = PEM_read_bio_X509(certbio, NULL, 0, NULL))) {
    BIO_printf(outbio, "Error loading cert into memory: %s\n", cert_filestr);
    exit(1);
  }

  ret = X509_STORE_load_locations(store, ca_bundlestr, NULL);
  if (ret != 1) {
    BIO_printf(outbio, "Error loading CA cert or chain file: %s\n", ca_bundlestr);
    exit(1);
  }

  /* ---------------------------------------------------------- *
   * Initialize the ctx structure for a verification operation: *
   * Set the trusted cert store, the unvalidated cert, and any  *
   * potential certs that could be needed (here we set it NULL) *
   * ---------------------------------------------------------- */
  X509_STORE_CTX_init(vrfy_ctx, store, cert, NULL);

  /* ---------------------------------------------------------- *
   * Check the complete cert chain can be build and validated.  *
   * Returns 1 on success, 0 on verification failures, and -1   *
   * for trouble with the ctx object (i.e. missing certificate) *
   * ---------------------------------------------------------- */
  ret = X509_verify_cert(vrfy_ctx);
  BIO_printf(outbio, "Verification return code: %d\n", ret);

  /* ---------------------------------------------------------- *
   * A negative return value indicates a verification error     *
   * ---------------------------------------------------------- */
  if (ret < 0) {
    BIO_printf(outbio, "Error loading CA cert or chain file: %s\n", ca_bundlestr);
    exit(1);
  }

  /* ---------------------------------------------------------- *
   * For verification return of 0 or 1, check validation result *
   * ---------------------------------------------------------- */
  vrfy_err = X509_STORE_CTX_get_error(vrfy_ctx);
  BIO_printf(outbio, "Verification result text: %s\n",
             X509_verify_cert_error_string(vrfy_err));

  /* ---------------------------------------------------------- *
   * The error handling below shows how to get failure details  *
   * from the offending certificate.                            *
   * ---------------------------------------------------------- */
  if(ret == 0) {
    /*  get the offending certificate causing the failure */
    error_cert  = X509_STORE_CTX_get_current_cert(vrfy_ctx);
    certsubject = X509_NAME_new();
    certsubject = X509_get_subject_name(error_cert);
    BIO_printf(outbio, "Verification failed cert:\n");
    X509_NAME_print_ex(outbio, certsubject, 0, XN_FLAG_MULTILINE);
    BIO_printf(outbio, "\n");
  }

  /* ---------------------------------------------------------- *
   * Free up all structures                                     *
   * ---------------------------------------------------------- */

  X509_STORE_CTX_free(vrfy_ctx); 
  X509_STORE_free(store);
  X509_free(cert);
  BIO_free_all(certbio);
  BIO_free_all(outbio);
  exit(0);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movl $0x0, -0x4(%rbp)
movq 0xd67(%rip), %rax       # 0x2010
movq %rax, -0x20(%rbp)
movq 0xd64(%rip), %rax       # 0x2018
movq %rax, -0x18(%rbp)
movl 0xd62(%rip), %eax       # 0x2020
movl %eax, -0x10(%rbp)
movb 0xd5d(%rip), %al        # 0x2024
movb %al, -0xc(%rbp)
movq 0xd5f(%rip), %rax       # 0x2030
movq %rax, -0x40(%rbp)
movq 0xd5c(%rip), %rax       # 0x2038
movq %rax, -0x38(%rbp)
movl 0xd5a(%rip), %eax       # 0x2040
movl %eax, -0x30(%rbp)
movb 0xd55(%rip), %al        # 0x2044
movb %al, -0x2c(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0x68(%rbp)
movq $0x0, -0x70(%rbp)
movq $0x0, -0x78(%rbp)
callq 0x1050
movq %rax, %rdi
callq 0x1150
movq %rax, -0x48(%rbp)
movq 0x2c8e(%rip), %rax      # 0x3fd0
movq (%rax), %rdi
xorl %esi, %esi
callq 0x1090
movq %rax, -0x50(%rbp)
callq 0x1110
movq %rax, -0x70(%rbp)
cmpq $0x0, %rax
jne 0x1371
movq -0x50(%rbp), %rdi
leaq 0xcdb(%rip), %rsi       # 0x2045
movb $0x0, %al
callq 0x1180
callq 0x10d0
movq %rax, -0x78(%rbp)
movq -0x48(%rbp), %rdi
leaq -0x40(%rbp), %rcx
movl $0x6c, %esi
movl $0x3, %edx
callq 0x1040
movl %eax, -0x80(%rbp)
movq -0x48(%rbp), %rdi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x1160
movq %rax, -0x60(%rbp)
cmpq $0x0, %rax
jne 0x13d1
movq -0x50(%rbp), %rdi
leaq -0x40(%rbp), %rdx
leaq 0xcab(%rip), %rsi       # 0x206b
movb $0x0, %al
callq 0x1180
movl $0x1, %edi
callq 0x1120
movq -0x70(%rbp), %rdi
leaq -0x20(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x1170
movl %eax, -0x80(%rbp)
cmpl $0x1, -0x80(%rbp)
je 0x140b
movq -0x50(%rbp), %rdi
leaq -0x20(%rbp), %rdx
leaq 0xc95(%rip), %rsi       # 0x208f
movb $0x0, %al
callq 0x1180
movl $0x1, %edi
callq 0x1120
movq -0x78(%rbp), %rdi
movq -0x70(%rbp), %rsi
movq -0x60(%rbp), %rdx
xorl %eax, %eax
movl %eax, %ecx
callq 0x1080
movq -0x78(%rbp), %rdi
callq 0x10c0
movl %eax, -0x80(%rbp)
movq -0x50(%rbp), %rdi
movl -0x80(%rbp), %edx
leaq 0xc7e(%rip), %rsi       # 0x20b8
movb $0x0, %al
callq 0x1180
cmpl $0x0, -0x80(%rbp)
jge 0x1467
movq -0x50(%rbp), %rdi
leaq -0x20(%rbp), %rdx
leaq 0xc39(%rip), %rsi       # 0x208f
movb $0x0, %al
callq 0x1180
movl $0x1, %edi
callq 0x1120
movq -0x78(%rbp), %rdi
callq 0x10b0
movl %eax, -0x7c(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x88(%rbp)
movslq -0x7c(%rbp), %rdi
callq 0x10a0
movq -0x88(%rbp), %rdi
movq %rax, %rdx
leaq 0xc3e(%rip), %rsi       # 0x20d6
movb $0x0, %al
callq 0x1180
cmpl $0x0, -0x80(%rbp)
jne 0x1500
movq -0x78(%rbp), %rdi
callq 0x1140
movq %rax, -0x58(%rbp)
callq 0x10f0
movq %rax, -0x68(%rbp)
movq -0x58(%rbp), %rdi
callq 0x1100
movq %rax, -0x68(%rbp)
movq -0x50(%rbp), %rdi
leaq 0xc21(%rip), %rsi       # 0x20f4
movb $0x0, %al
callq 0x1180
movq -0x50(%rbp), %rdi
movq -0x68(%rbp), %rsi
xorl %edx, %edx
movl $0x2a40006, %ecx        # imm = 0x2A40006
callq 0x1030
movq -0x50(%rbp), %rdi
leaq 0xc14(%rip), %rsi       # 0x210d
movb $0x0, %al
callq 0x1180
movq -0x78(%rbp), %rdi
callq 0x1130
movq -0x70(%rbp), %rdi
callq 0x10e0
movq -0x60(%rbp), %rdi
callq 0x1070
movq -0x48(%rbp), %rdi
callq 0x1060
movq -0x50(%rbp), %rdi
callq 0x1060
xorl %edi, %edi
callq 0x1120