// File: /workspace/github_c_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movaps 0xd6f(%rip), %xmm0      # 0x2010
movaps %xmm0, (%rsp)
movabsq $0x6d65702e656c64, %rax # imm = 0x6D65702E656C64
movq %rax, 0xd(%rsp)
movaps 0xd75(%rip), %xmm0      # 0x2030
movaps %xmm0, 0x20(%rsp)
movabsq $0x6d65702e656c69, %rax # imm = 0x6D65702E656C69
movq %rax, 0x2d(%rsp)
callq 0x1050
movq %rax, %rdi
callq 0x1150
movq %rax, %r14
movq 0x2cea(%rip), %rax      # 0x3fd0
movq (%rax), %rdi
xorl %esi, %esi
callq 0x1090
movq %rax, %rbx
callq 0x1110
movq %rax, %r15
testq %rax, %rax
jne 0x1311
leaq 0xd3e(%rip), %rsi       # 0x2045
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1180
callq 0x10d0
movq %rax, %r12
leaq 0x20(%rsp), %rcx
movl $0x3, %edx
movq %r14, %rdi
movl $0x6c, %esi
callq 0x1040
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x1160
testq %rax, %rax
jne 0x1351
leaq 0xd21(%rip), %rsi       # 0x206b
leaq 0x20(%rsp), %rdx
jmp 0x13a1
movq %rax, %r13
movq %rsp, %rsi
movq %r15, %rdi
xorl %edx, %edx
callq 0x1170
cmpl $0x1, %eax
jne 0x1397
movq %r12, %rdi
movq %r15, %rsi
movq %r13, %rdx
xorl %ecx, %ecx
callq 0x1080
movq %r12, %rdi
callq 0x10c0
movl %eax, %ebp
leaq 0xd31(%rip), %rsi       # 0x20b8
movq %rbx, %rdi
movl %eax, %edx
xorl %eax, %eax
callq 0x1180
testl %ebp, %ebp
jns 0x13b5
leaq 0xcf1(%rip), %rsi       # 0x208f
movq %rsp, %rdx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1180
movl $0x1, %edi
callq 0x1120
movq %r12, %rdi
callq 0x10b0
movslq %eax, %rdi
callq 0x10a0
leaq 0xd0a(%rip), %rsi       # 0x20d6
movq %rbx, %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x1180
testl %ebp, %ebp
jne 0x142c
movq %r12, %rdi
callq 0x1140
movq %rax, %rbp
callq 0x10f0
movq %rbp, %rdi
callq 0x1100
movq %rax, %rbp
leaq 0xcf5(%rip), %rsi       # 0x20f4
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1180
movl $0x2a40006, %ecx        # imm = 0x2A40006
movq %rbx, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq 0x1030
leaq 0xceb(%rip), %rsi       # 0x210d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x1180
movq %r12, %rdi
callq 0x1130
movq %r15, %rdi
callq 0x10e0
movq %r13, %rdi
callq 0x1070
movq %r14, %rdi
callq 0x1060
movq %rbx, %rdi
callq 0x1060
xorl %edi, %edi
callq 0x1120