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

  ASN1_INTEGER                 *aserial = NULL;
  EVP_PKEY                     *ca_privkey, *req_pubkey;
  EVP_MD                       const *digest = NULL;
  X509                         *newcert, *cacert;
  X509_NAME                    *name;
  X509V3_CTX                   ctx;
  FILE                         *fp;
  long                         valid_secs = 31536000;

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

  /* ---------------------------------------------------------- *
   * Load the request data in a BIO, then in a x509_REQ struct. *
   * ---------------------------------------------------------- */
  reqbio = BIO_new_mem_buf(request_str, -1);

  if (! (certreq = PEM_read_bio_X509_REQ(reqbio, NULL, NULL, NULL))) {
    BIO_printf(outbio, "Error can't read X509 request data into memory\n");
    exit(1);
   }

  /* -------------------------------------------------------- *
   * Load ithe signing CA Certificate file                    *
   * ---------------------------------------------------------*/
  if (! (fp=fopen(CACERT, "r"))) {
    BIO_printf(outbio, "Error reading CA cert file %s\n", CACERT);
    exit(1);
   }

  if(! (cacert = PEM_read_X509(fp,NULL,NULL,NULL))) {
    BIO_printf(outbio, "Error loading CA cert into memory\n");
    exit(1);
   }

  fclose(fp);

  /* -------------------------------------------------------- *
   * Import CA private key file for signing                   *
   * ---------------------------------------------------------*/
  ca_privkey = EVP_PKEY_new();

  if (! (fp = fopen (CAKEY, "r"))) {
    BIO_printf(outbio, "Error reading CA private key file: %s\n", CAKEY);
    exit(1);
   }

  if (! (ca_privkey = PEM_read_PrivateKey( fp, NULL, NULL, PASS))) {
    BIO_printf(outbio, "Error importing key content from file: %s\n", CAKEY);
    exit(1);
   }

  fclose(fp);

  /* --------------------------------------------------------- *
   * Build Certificate with data from request                  *
   * ----------------------------------------------------------*/
  if (! (newcert=X509_new())) {
    BIO_printf(outbio, "Error creating new X509 object\n");
    exit(1);
   }

  if (X509_set_version(newcert, 2) != 1) {
    BIO_printf(outbio, "Error setting certificate version\n");
    exit(1);
   }

  /* --------------------------------------------------------- *
   * set the certificate serial number here                    *
   * If there is a problem, the value defaults to '0'          *
   * ----------------------------------------------------------*/
  aserial=ASN1_INTEGER_new();
  ASN1_INTEGER_set(aserial, 0);
  if (! X509_set_serialNumber(newcert, aserial)) {
    BIO_printf(outbio, "Error setting serial number of the certificate\n");
    exit(1);
   }

  /* --------------------------------------------------------- *
   * Extract the subject name from the request                 *
   * ----------------------------------------------------------*/
  if (! (name = X509_REQ_get_subject_name(certreq)))
    BIO_printf(outbio, "Error getting subject from cert request\n");

  /* --------------------------------------------------------- *
   * Set the new certificate subject name                      *
   * ----------------------------------------------------------*/
  if (X509_set_subject_name(newcert, name) != 1) {
    BIO_printf(outbio, "Error setting subject name of certificate\n");
    exit(1);
   }

  /* --------------------------------------------------------- *
   * Extract the subject name from the signing CA cert         *
   * ----------------------------------------------------------*/
  if (! (name = X509_get_subject_name(cacert))) {
    BIO_printf(outbio, "Error getting subject from CA certificate\n");
    exit(1);
   }

  /* --------------------------------------------------------- *
   * Set the new certificate issuer name                       *
   * ----------------------------------------------------------*/
  if (X509_set_issuer_name(newcert, name) != 1) {
    BIO_printf(outbio, "Error setting issuer name of certificate\n");
    exit(1);
   }

  /* --------------------------------------------------------- *
   * Extract the public key data from the request              *
   * ----------------------------------------------------------*/
  if (! (req_pubkey=X509_REQ_get_pubkey(certreq))) {
    BIO_printf(outbio, "Error unpacking public key from request\n");
    exit(1);
   }

  /* --------------------------------------------------------- *
   * Optionally: Use the public key to verify the signature    *
   * ----------------------------------------------------------*/
  if (X509_REQ_verify(certreq, req_pubkey) != 1) {
    BIO_printf(outbio, "Error verifying signature on request\n");
    exit(1);
   }

  /* --------------------------------------------------------- *
   * Set the new certificate public key                        *
   * ----------------------------------------------------------*/
  if (X509_set_pubkey(newcert, req_pubkey) != 1) {
    BIO_printf(outbio, "Error setting public key of certificate\n");
    exit(1);
   }

  /* ---------------------------------------------------------- *
   * Set X509V3 start date (now) and expiration date (+365 days)*
   * -----------------------------------------------------------*/
   if (! (X509_gmtime_adj(X509_get_notBefore(newcert),0))) {
      BIO_printf(outbio, "Error setting start time\n");
    exit(1);
   }

   if(! (X509_gmtime_adj(X509_get_notAfter(newcert), valid_secs))) {
      BIO_printf(outbio, "Error setting expiration time\n");
    exit(1);
   }

  /* ----------------------------------------------------------- *
   * Add X509V3 extensions                                       *
   * ------------------------------------------------------------*/
  X509V3_set_ctx(&ctx, cacert, newcert, NULL, NULL, 0);

  /* ----------------------------------------------------------- *
   * Set digest type, sign new certificate with CA's private key *
   * ------------------------------------------------------------*/
  digest = EVP_sha256();

  if (! X509_sign(newcert, ca_privkey, digest)) {
    BIO_printf(outbio, "Error signing the new certificate\n");
    exit(1);
   }

  /* ------------------------------------------------------------ *
   *  print the certificate                                       *
   * -------------------------------------------------------------*/
  if (! PEM_write_bio_X509(outbio, newcert)) {
    BIO_printf(outbio, "Error printing the signed certificate\n");
    exit(1);
   }

  /* ---------------------------------------------------------- *
   * Free up all structures                                     *
   * ---------------------------------------------------------- */
  EVP_PKEY_free(req_pubkey);
  EVP_PKEY_free(ca_privkey);
  X509_REQ_free(certreq);
  X509_free(newcert);
  BIO_free_all(reqbio);
  BIO_free_all(outbio);

  exit(0);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movl $0x0, -0x4(%rbp)
movq $0x0, -0x10(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x1e13380, -0x90(%rbp) # imm = 0x1E13380
callq 0x1050
movq %rax, %rdi
callq 0x11f0
movq %rax, 0x2f5f(%rip)      # 0x4300
movq 0x2c28(%rip), %rax      # 0x3fd0
movq (%rax), %rdi
xorl %esi, %esi
callq 0x1100
movq %rax, 0x2f47(%rip)      # 0x4300
leaq 0x2d80(%rip), %rdi      # 0x4140
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x1040
movq %rax, 0x2f27(%rip)      # 0x42f8
movq 0x2f20(%rip), %rdi      # 0x42f8
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x1120
movq %rax, 0x2f22(%rip)      # 0x4310
cmpq $0x0, %rax
jne 0x1413
movq 0x2f05(%rip), %rdi      # 0x4300
leaq 0xc02(%rip), %rsi       # 0x2004
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
leaq 0xc1a(%rip), %rdi       # 0x2034
leaq 0xc25(%rip), %rsi       # 0x2046
callq 0x1160
movq %rax, -0x88(%rbp)
cmpq $0x0, %rax
jne 0x1459
movq 0x2ec6(%rip), %rdi      # 0x4300
leaq 0xc07(%rip), %rsi       # 0x2048
leaq 0xbec(%rip), %rdx       # 0x2034
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x88(%rbp), %rdi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x11a0
movq %rax, -0x38(%rbp)
cmpq $0x0, %rax
jne 0x1498
movq 0x2e80(%rip), %rdi      # 0x4300
leaq 0xbe0(%rip), %rsi       # 0x2067
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x88(%rbp), %rdi
callq 0x1130
callq 0x1210
movq %rax, -0x18(%rbp)
leaq 0xbd6(%rip), %rdi       # 0x208a
leaq 0xb8b(%rip), %rsi       # 0x2046
callq 0x1160
movq %rax, -0x88(%rbp)
cmpq $0x0, %rax
jne 0x14f3
movq 0x2e2c(%rip), %rdi      # 0x4300
leaq 0xbc1(%rip), %rsi       # 0x209c
leaq 0xba8(%rip), %rdx       # 0x208a
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x88(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
leaq 0xbbe(%rip), %rcx       # 0x20c3
movq %rdx, %rsi
callq 0x1110
movq %rax, -0x18(%rbp)
cmpq $0x0, %rax
jne 0x153d
movq 0x2de2(%rip), %rdi      # 0x4300
leaq 0xbad(%rip), %rsi       # 0x20d2
leaq 0xb5e(%rip), %rdx       # 0x208a
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x88(%rbp), %rdi
callq 0x1130
callq 0x1030
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
jne 0x1577
movq 0x2da1(%rip), %rdi      # 0x4300
leaq 0xb97(%rip), %rsi       # 0x20fd
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x30(%rbp), %rdi
movl $0x2, %esi
callq 0x1080
cmpl $0x1, %eax
je 0x15a9
movq 0x2d6f(%rip), %rdi      # 0x4300
leaq 0xb85(%rip), %rsi       # 0x211d
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
callq 0x1240
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x10f0
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x11c0
cmpl $0x0, %eax
jne 0x15f0
movq 0x2d28(%rip), %rdi      # 0x4300
leaq 0xb61(%rip), %rsi       # 0x2140
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq 0x2d19(%rip), %rdi      # 0x4310
callq 0x1140
movq %rax, -0x40(%rbp)
cmpq $0x0, %rax
jne 0x161b
movq 0x2cf3(%rip), %rdi      # 0x4300
leaq 0xb5c(%rip), %rsi       # 0x2170
movb $0x0, %al
callq 0x1250
movq -0x30(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x11b0
cmpl $0x1, %eax
je 0x164c
movq 0x2ccc(%rip), %rdi      # 0x4300
leaq 0xb5e(%rip), %rsi       # 0x2199
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x38(%rbp), %rdi
callq 0x1150
movq %rax, -0x40(%rbp)
cmpq $0x0, %rax
jne 0x167e
movq 0x2c9a(%rip), %rdi      # 0x4300
leaq 0xb57(%rip), %rsi       # 0x21c4
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x30(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x10a0
cmpl $0x1, %eax
je 0x16af
movq 0x2c69(%rip), %rdi      # 0x4300
leaq 0xb51(%rip), %rsi       # 0x21ef
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq 0x2c5a(%rip), %rdi      # 0x4310
callq 0x1090
movq %rax, -0x20(%rbp)
cmpq $0x0, %rax
jne 0x16e4
movq 0x2c34(%rip), %rdi      # 0x4300
leaq 0xb46(%rip), %rsi       # 0x2219
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq 0x2c25(%rip), %rdi      # 0x4310
movq -0x20(%rbp), %rsi
callq 0x11d0
cmpl $0x1, %eax
je 0x1718
movq 0x2c00(%rip), %rdi      # 0x4300
leaq 0xb3b(%rip), %rsi       # 0x2242
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x10d0
cmpl $0x1, %eax
je 0x1749
movq 0x2bcf(%rip), %rdi      # 0x4300
leaq 0xb30(%rip), %rsi       # 0x2268
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x30(%rbp), %rdi
callq 0x1230
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x11e0
cmpq $0x0, %rax
jne 0x1783
movq 0x2b95(%rip), %rdi      # 0x4300
leaq 0xb1f(%rip), %rsi       # 0x2291
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x30(%rbp), %rdi
callq 0x1060
movq %rax, %rdi
movq -0x90(%rbp), %rsi
callq 0x11e0
cmpq $0x0, %rax
jne 0x17c0
movq 0x2b58(%rip), %rdi      # 0x4300
leaq 0xafc(%rip), %rsi       # 0x22ab
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x38(%rbp), %rsi
movq -0x30(%rbp), %rdx
leaq -0x80(%rbp), %rdi
xorl %eax, %eax
movl %eax, %r8d
xorl %r9d, %r9d
movq %r8, %rcx
callq 0x1220
callq 0x1200
movq %rax, -0x28(%rbp)
movq -0x30(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x10b0
cmpl $0x0, %eax
jne 0x181a
movq 0x2afe(%rip), %rdi      # 0x4300
leaq 0xac1(%rip), %rsi       # 0x22ca
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq 0x2adf(%rip), %rdi      # 0x4300
movq -0x30(%rbp), %rsi
callq 0x1180
cmpl $0x0, %eax
jne 0x184e
movq 0x2aca(%rip), %rdi      # 0x4300
leaq 0xab0(%rip), %rsi       # 0x22ed
movb $0x0, %al
callq 0x1250
movl $0x1, %edi
callq 0x1170
movq -0x20(%rbp), %rdi
callq 0x10e0
movq -0x18(%rbp), %rdi
callq 0x10e0
movq 0x2aa9(%rip), %rdi      # 0x4310
callq 0x1190
movq -0x30(%rbp), %rdi
callq 0x10c0
movq 0x2a7c(%rip), %rdi      # 0x42f8
callq 0x1070
movq 0x2a78(%rip), %rdi      # 0x4300
callq 0x1070
xorl %edi, %edi
callq 0x1170