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

  const char cert_filestr[] = "./demo/cert-file.pem";
  ASN1_INTEGER *asn1_serial = NULL;
  BIO              *certbio = NULL;
  BIO               *outbio = NULL;
  X509                *cert = NULL;
  const char *neg;
  int  i;
  long l;

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

  /* ---------------------------------------------------------- *
   * Load the certificate from file (PEM).                      *
   * ---------------------------------------------------------- */
  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);
  }

  /* ---------------------------------------------------------- *
   * Extract the certificate's serial number.                   *
   * ---------------------------------------------------------- */
   asn1_serial = X509_get_serialNumber(cert);
   if (asn1_serial == NULL)
     BIO_printf(outbio, "Error getting serial number from certificate");

  /* ---------------------------------------------------------- *
   * Print the serial number value, openssl x509 -serial style  *
   * ---------------------------------------------------------- */
  BIO_puts(outbio,"serial (openssl x509 -serial style): ");
  i2a_ASN1_INTEGER(outbio, asn1_serial);
  BIO_puts(outbio,"\n");

  /* ---------------------------------------------------------- *
   * Print the serial number value, openssl x509 -text style    *
   * ---------------------------------------------------------- */
  if (asn1_serial->length <= (int)sizeof(long)) {
    l=ASN1_INTEGER_get(asn1_serial);
    if (asn1_serial->type == V_ASN1_NEG_INTEGER) {
      l= -l;
      neg="-";
    }
    else neg="";

    if (BIO_printf(outbio," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
      BIO_printf(outbio, "Error during printing the serial.\n");
  } else {
    neg=(asn1_serial->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
    //if (BIO_printf(outbio,"\n%12s%s","",neg) <= 0)
    if (BIO_printf(outbio,"serial (openssl x509 -text   style): %s ",neg) <= 0)
      BIO_printf(outbio, "Error during printing the serial.\n");

    for (i=0; i<asn1_serial->length; i++) {
     if (BIO_printf(outbio,"%02x%c",asn1_serial->data[i],
        ((i+1 == asn1_serial->length)?'\n':':')) <= 0)
      BIO_printf(outbio, "Error during printing the serial.\n");
    }
  }

  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 $0x28, %rsp
movaps 0xdff(%rip), %xmm0      # 0x2010
leaq 0x10(%rsp), %r15
movaps %xmm0, (%r15)
movabsq $0x6d65702e656c69, %rax # imm = 0x6D65702E656C69
movq %rax, 0xd(%r15)
callq 0x1050
movq %rax, %rdi
callq 0x10d0
movq %rax, %r14
movq 0x2d91(%rip), %rax      # 0x3fd0
movq (%rax), %rdi
xorl %esi, %esi
callq 0x1080
movq %rax, %rbx
pushq $0x6c
popq %rsi
pushq $0x3
popq %rdx
movq %r14, %rdi
movq %r15, %rcx
callq 0x1040
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x10e0
testq %rax, %rax
jne 0x128e
leaq 0xdae(%rip), %rsi       # 0x2025
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x10f0
pushq $0x1
popq %rdi
callq 0x1090
movq %rax, (%rsp)
movq %rax, %rdi
callq 0x10c0
movq %rax, %r12
testq %rax, %rax
jne 0x12b3
leaq 0xda0(%rip), %rsi       # 0x2049
movq %rbx, %rdi
xorl %eax, %eax
callq 0x10f0
movq %r14, 0x8(%rsp)
leaq 0xdb7(%rip), %rsi       # 0x2076
movq %rbx, %rdi
callq 0x10a0
movq %rbx, %rdi
movq %r12, %rsi
callq 0x10b0
leaq 0xdd5(%rip), %rsi       # 0x20ae
movq %rbx, %rdi
callq 0x10a0
cmpl $0x8, (%r12)
jg 0x1363
movq %r12, %rdi
callq 0x1030
movq %rax, %rcx
negq %rcx
cmpl $0x102, 0x4(%r12)       # imm = 0x102
leaq 0xd96(%rip), %rsi       # 0x209c
leaq 0xda2(%rip), %rdx       # 0x20af
cmoveq %rsi, %rdx
cmovneq %rax, %rcx
leaq 0xd82(%rip), %rsi       # 0x209e
movq %rbx, %rdi
movq %rdx, %r8
movq %rcx, %r9
xorl %eax, %eax
callq 0x10f0
testl %eax, %eax
jg 0x1341
leaq 0xd79(%rip), %rsi       # 0x20b0
movq %rbx, %rdi
xorl %eax, %eax
callq 0x10f0
movq (%rsp), %rdi
callq 0x1070
movq 0x8(%rsp), %rdi
callq 0x1060
movq %rbx, %rdi
callq 0x1060
xorl %edi, %edi
callq 0x1090
cmpl $0x102, 0x4(%r12)       # imm = 0x102
leaq 0xd60(%rip), %rax       # 0x20d3
leaq 0xd35(%rip), %rdx       # 0x20af
cmoveq %rax, %rdx
leaq 0xd5a(%rip), %rsi       # 0x20df
movq %rbx, %rdi
xorl %eax, %eax
callq 0x10f0
testl %eax, %eax
jg 0x13a4
leaq 0xd16(%rip), %rsi       # 0x20b0
movq %rbx, %rdi
xorl %eax, %eax
callq 0x10f0
pushq $0xa
popq %r15
pushq $0x3a
popq %r14
leaq 0xd55(%rip), %r13       # 0x2108
xorl %ebp, %ebp
movslq (%r12), %rax
cmpq %rax, %rbp
jge 0x1341
movl %eax, %eax
movq 0x8(%r12), %rcx
movzbl (%rcx,%rbp), %edx
incq %rbp
cmpq %rax, %rbp
movl %r14d, %ecx
cmovel %r15d, %ecx
movq %rbx, %rdi
movq %r13, %rsi
xorl %eax, %eax
callq 0x10f0
testl %eax, %eax
jg 0x13b5
movq %rbx, %rdi
leaq 0xcbf(%rip), %rsi       # 0x20b0
xorl %eax, %eax
callq 0x10f0
jmp 0x13b5