// File: /workspace/github_c_makefile_star2_O2/fm4dd[P]learn-ssl/pkcs12test.c
// Function: main
int main() {
   X509		  *cert, *cacert;
   STACK_OF(X509) *cacertstack;
   PKCS12	  *pkcs12bundle;
   EVP_PKEY	  *cert_privkey;
   FILE 	  *cacertfile, *certfile, *keyfile, *pkcs12file;
   int		  ret, bytes = 0;
   struct stat    fstat;

#if OPENSSL_VERSION_NUMBER < 0x30000000L
/* ------------------------------------------------------------ *
 * 1.) These function calls are essential to make PEM_read and  *
 *     other openssl functions work.                            *
 * ------------------------------------------------------------ */
   OpenSSL_add_all_algorithms();
   ERR_load_crypto_strings();
#endif

/*--------------------------------------------------------------*
 * 2.) we load the certificates private key                     *
 *    ( for this test, it has no password )                     *
 *--------------------------------------------------------------*/
   if ((cert_privkey = EVP_PKEY_new()) == NULL)
      printf("Error creating EVP_PKEY structure.\n");
   if (! (keyfile = fopen(CERTKEY, "r"))) {
      printf("Error cant read certificate private key file: %s\n", CERTKEY);
      exit(1);
   }
   if (! (cert_privkey = PEM_read_PrivateKey(keyfile, NULL, NULL, NULL)))
      printf("Error loading certificate private key content.\n");
   fclose(keyfile);

/*--------------------------------------------------------------*
 * 3.) we load the corresponding certificate                    *
 *--------------------------------------------------------------*/
   if (! (certfile = fopen(CERTFILE, "r"))) {
      printf("Error cant read certificate file: %s\n", CERTFILE);
      exit(1);
   }
   if (! (cert = PEM_read_X509(certfile, NULL, NULL, NULL)))
      printf("Error loading cert into memory.\n");
   fclose(certfile);

/*--------------------------------------------------------------*
 * 4.) we load the CA certificate who signed it                 *
 *--------------------------------------------------------------*/
   if (! (cacertfile = fopen(CAFILE, "r"))) {
      printf("Error cant read ca certificate file: %s\n", CAFILE);
      exit(1);
   }
   if (! (cacert = PEM_read_X509(cacertfile,NULL,NULL,NULL)))
      printf("Error loading CA certificate into memory.\n");
   fclose(cacertfile);

/*--------------------------------------------------------------*
 * 5.) we load the CA certificate on the stack                  *
 *--------------------------------------------------------------*/
   if ((cacertstack = sk_X509_new_null()) == NULL)
      printf("Error creating STACK_OF(X509) structure.\n");
   sk_X509_push(cacertstack, cacert);

/*--------------------------------------------------------------*
 * 6.) we create the PKCS12 structure and fill it with our data *
 *--------------------------------------------------------------*/
   if ((pkcs12bundle = PKCS12_new()) == NULL)
      printf("Error creating PKCS12 structure.\n");

   /* values of zero use the openssl default values */
   pkcs12bundle = PKCS12_create(
          "test",      // certbundle access password
          "pkcs12test",// friendly certname
          cert_privkey,// the certificate private key
          cert,        // the main certificate
          cacertstack, // stack of CA cert chain
          0,           // int nid_key (default 3DES)
          0,           // int nid_cert (40bitRC2)
          0,           // int iter (default 2048)
          0,           // int mac_iter (default 1)
          0            // int keytype (default no flag)
   );
   if ( pkcs12bundle == NULL)
      printf("Error generating a valid PKCS12 certificate.\n");

/*--------------------------------------------------------------*
 * 7.) we write the PKCS12 structure out to file                *
 *--------------------------------------------------------------*/
   if (! (pkcs12file = fopen(P12FILE, "w"))) {
      printf("Error cant open pkcs12 file for writing: %s\n", P12FILE);
      exit(1);
   }
   ret = i2d_PKCS12_fp(pkcs12file, pkcs12bundle);
   if (ret == 0) {
      printf("Error writing PKCS12 certificate.\n");
      exit(1);
   }

/*--------------------------------------------------------------*
 * 8.) we are done, let's clean up                              *
 *--------------------------------------------------------------*/
   fclose(pkcs12file);
   X509_free(cert);
   X509_free(cacert);
   sk_X509_free(cacertstack);
   PKCS12_free(pkcs12bundle);

   /* get file status data */
   if (stat(P12FILE, &fstat) != 0) {
      printf("Error cannot stat p12 file: %s\n", P12FILE);
      printf("%s\n", strerror(errno));
      exit(1);
   }
   
   bytes = fstat.st_size;
   printf("Created PKCS12 file %s with %d Bytes.\n", P12FILE, bytes);

   return(0);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb0, %rsp
callq 0x1140
testq %rax, %rax
jne 0x1282
leaq 0xed7(%rip), %rdi       # 0x2154
callq 0x1110
leaq 0xd7b(%rip), %rdi       # 0x2004
leaq 0xd89(%rip), %rsi       # 0x2019
callq 0x10e0
testq %rax, %rax
je 0x1478
movq %rax, %rbx
movq %rax, %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x1080
movq %rax, %r14
testq %rax, %rax
jne 0x12c3
leaq 0xeb9(%rip), %rdi       # 0x2177
callq 0x1110
movq %rbx, %rdi
callq 0x10c0
leaq 0xd7b(%rip), %rdi       # 0x204d
leaq 0xd40(%rip), %rsi       # 0x2019
callq 0x10e0
testq %rax, %rax
je 0x1488
movq %rax, %r15
movq %rax, %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x1100
movq %rax, %rbx
testq %rax, %rax
jne 0x130c
leaq 0xe9f(%rip), %rdi       # 0x21a6
callq 0x1110
movq %r15, %rdi
callq 0x10c0
leaq 0xd6d(%rip), %rdi       # 0x2088
leaq 0xcf7(%rip), %rsi       # 0x2019
callq 0x10e0
testq %rax, %rax
je 0x1498
movq %rax, %r12
movq %rax, %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x1100
movq %rax, %r15
testq %rax, %rax
jne 0x1355
leaq 0xe76(%rip), %rdi       # 0x21c6
callq 0x1110
movq %r12, %rdi
callq 0x10c0
callq 0x1150
movq %rax, %r12
testq %rax, %rax
jne 0x1376
leaq 0xe7f(%rip), %rdi       # 0x21f0
callq 0x1110
movq %r12, %rdi
movq %r15, %rsi
callq 0x1090
callq 0x1130
testq %rax, %rax
jne 0x1397
leaq 0xe87(%rip), %rdi       # 0x2219
callq 0x1110
andl $0x0, 0x18(%rsp)
andl $0x0, 0x10(%rsp)
andl $0x0, 0x8(%rsp)
andl $0x0, (%rsp)
leaq 0xd18(%rip), %rdi       # 0x20c9
leaq 0xd0b(%rip), %rsi       # 0x20c3
movq %r14, %rdx
movq %rbx, %rcx
movq %r12, %r8
xorl %r9d, %r9d
callq 0x10d0
movq %rax, %r14
testq %rax, %rax
jne 0x13dd
leaq 0xe62(%rip), %rdi       # 0x223a
callq 0x1110
leaq 0xcea(%rip), %rdi       # 0x20ce
leaq 0xcf3(%rip), %rsi       # 0x20de
callq 0x10e0
testq %rax, %rax
je 0x14a8
movq %rax, %r13
movq %rax, %rdi
movq %r14, %rsi
callq 0x1120
testl %eax, %eax
je 0x14bf
movq %r13, %rdi
callq 0x10c0
movq %rbx, %rdi
callq 0x1060
movq %r15, %rdi
callq 0x1060
movq %r12, %rdi
callq 0x10b0
movq %r14, %rdi
callq 0x1070
leaq 0xc90(%rip), %rdi       # 0x20ce
leaq 0x20(%rsp), %rsi
callq 0x10a0
testl %eax, %eax
jne 0x14c8
movl 0x50(%rsp), %edx
leaq 0xcd6(%rip), %rdi       # 0x212d
leaq 0xc70(%rip), %rsi       # 0x20ce
xorl %eax, %eax
callq 0x1040
xorl %eax, %eax
addq $0xb0, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
leaq 0xb9c(%rip), %rdi       # 0x201b
leaq 0xb7e(%rip), %rsi       # 0x2004
jmp 0x14b6
leaq 0xbd3(%rip), %rdi       # 0x2062
leaq 0xbb7(%rip), %rsi       # 0x204d
jmp 0x14b6
leaq 0xbfb(%rip), %rdi       # 0x209a
leaq 0xbe2(%rip), %rsi       # 0x2088
jmp 0x14b6
leaq 0xc31(%rip), %rdi       # 0x20e0
leaq 0xc18(%rip), %rsi       # 0x20ce
xorl %eax, %eax
callq 0x1040
jmp 0x14f1
leaq 0xda1(%rip), %rdi       # 0x2267
jmp 0x14ec
leaq 0xc3e(%rip), %rdi       # 0x210d
leaq 0xbf8(%rip), %rsi       # 0x20ce
xorl %eax, %eax
callq 0x1040
callq 0x1030
movl (%rax), %edi
callq 0x1050
movq %rax, %rdi
callq 0x1110
pushq $0x1
popq %rdi
callq 0x10f0