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

  char           dest_url[] = "https://fm4dd.com";
  BIO               *outbio = NULL;
  X509                *cert = NULL;
  X509_NAME       *certname = NULL;
  const SSL_METHOD *method;
  SSL_CTX *ctx;
  SSL *ssl;
  int server = 0;

#if OPENSSL_VERSION_NUMBER < 0x30000000L
  /* ---------------------------------------------------------- *
   * These function calls initialize openssl for correct work.  *
   * ---------------------------------------------------------- */
  OpenSSL_add_all_algorithms();
  ERR_load_crypto_strings();
  SSL_load_error_strings();
#endif

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

  /* ---------------------------------------------------------- *
   * initialize SSL library and register algorithms             *
   * ---------------------------------------------------------- */
  if(SSL_library_init() < 0)
    BIO_printf(outbio, "Could not initialize the OpenSSL library !\n");

  /* ---------------------------------------------------------- *
   * Set SSLv2 client hello, also announce SSLv3 and TLSv1      *
   * ---------------------------------------------------------- */
  method = SSLv23_client_method();

  /* ---------------------------------------------------------- *
   * Try to create a new SSL context                            *
   * ---------------------------------------------------------- */
  if ( (ctx = SSL_CTX_new(method)) == NULL)
    BIO_printf(outbio, "Unable to create a new SSL context structure.\n");

  /* ---------------------------------------------------------- *
   * Disabling SSLv2 will leave v3 and TSLv1 for negotiation    *
   * ---------------------------------------------------------- */
  SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);

  /* ---------------------------------------------------------- *
   * Create new SSL connection state object                     *
   * ---------------------------------------------------------- */
  ssl = SSL_new(ctx);

  /* ---------------------------------------------------------- *
   * Make the underlying TCP socket connection                  *
   * ---------------------------------------------------------- */
  server = create_socket(dest_url, outbio);
  if(server != 0)
    BIO_printf(outbio, "Successfully made the TCP connection to: %s.\n", dest_url);

  /* ---------------------------------------------------------- *
   * Attach the SSL session to the socket descriptor            *
   * ---------------------------------------------------------- */
  SSL_set_fd(ssl, server);

  /* ---------------------------------------------------------- *
   * Try to SSL-connect here, returns 1 for success             *
   * ---------------------------------------------------------- */
  if ( SSL_connect(ssl) != 1 )
    BIO_printf(outbio, "Error: Could not build a SSL session to: %s.\n", dest_url);
  else
    BIO_printf(outbio, "Successfully enabled SSL/TLS session to: %s.\n", dest_url);

  /* ---------------------------------------------------------- *
   * Get the remote certificate into the X509 structure         *
   * ---------------------------------------------------------- */
  cert = SSL_get_peer_certificate(ssl);
  if (cert == NULL)
    BIO_printf(outbio, "Error: Could not get a certificate from: %s.\n", dest_url);
  else
    BIO_printf(outbio, "Retrieved the server's certificate from: %s.\n", dest_url);

  /* ---------------------------------------------------------- *
   * extract various certificate information                    *
   * -----------------------------------------------------------*/
  certname = X509_NAME_new();
  certname = X509_get_subject_name(cert);

  /* ---------------------------------------------------------- *
   * display the cert subject here                              *
   * -----------------------------------------------------------*/
  BIO_printf(outbio, "Displaying the certificate subject data:\n");
  X509_NAME_print_ex(outbio, certname, 0, 0);
  BIO_printf(outbio, "\n");

  /* ---------------------------------------------------------- *
   * Free the structures we don't need anymore                  *
   * -----------------------------------------------------------*/
  SSL_free(ssl);
  close(server);
  X509_free(cert);
  SSL_CTX_free(ctx);
  BIO_printf(outbio, "Finished SSL/TLS connection with server: %s.\n", dest_url);
  return(0);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movl $0x0, -0x4(%rbp)
movq 0xcfa(%rip), %rax       # 0x2010
movq %rax, -0x20(%rbp)
movq 0xcf7(%rip), %rax       # 0x2018
movq %rax, -0x18(%rbp)
movw 0xcf4(%rip), %ax        # 0x2020
movw %ax, -0x10(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movl $0x0, -0x54(%rbp)
movq 0x2c7a(%rip), %rax      # 0x3fd0
movq (%rax), %rdi
xorl %esi, %esi
callq 0x1120
movq %rax, -0x28(%rbp)
xorl %eax, %eax
movl %eax, %esi
movq %rsi, %rdi
callq 0x1150
cmpl $0x0, %eax
jge 0x1387
movq -0x28(%rbp), %rdi
leaq 0xca2(%rip), %rsi       # 0x2022
movb $0x0, %al
callq 0x11f0
callq 0x10b0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0x11a0
movq %rax, -0x48(%rbp)
cmpq $0x0, %rax
jne 0x13b5
movq -0x28(%rbp), %rdi
leaq 0xca0(%rip), %rsi       # 0x204e
movb $0x0, %al
callq 0x11f0
movq -0x48(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x11d0
movq -0x48(%rbp), %rdi
callq 0x1160
movq %rax, -0x50(%rbp)
leaq -0x20(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x1520
movl %eax, -0x54(%rbp)
cmpl $0x0, -0x54(%rbp)
je 0x13fb
movq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rdx
leaq 0xc89(%rip), %rsi       # 0x207d
movb $0x0, %al
callq 0x11f0
movq -0x50(%rbp), %rdi
movl -0x54(%rbp), %esi
callq 0x1110
movq -0x50(%rbp), %rdi
callq 0x1190
cmpl $0x1, %eax
je 0x142d
movq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rdx
leaq 0xc87(%rip), %rsi       # 0x20ab
movb $0x0, %al
callq 0x11f0
jmp 0x1443
movq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rdx
leaq 0xc9d(%rip), %rsi       # 0x20d9
movb $0x0, %al
callq 0x11f0
movq -0x50(%rbp), %rdi
callq 0x11c0
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x146f
movq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rdx
leaq 0xca1(%rip), %rsi       # 0x2107
movb $0x0, %al
callq 0x11f0
jmp 0x1485
movq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rdx
leaq 0xcb7(%rip), %rsi       # 0x2135
movb $0x0, %al
callq 0x11f0
callq 0x1140
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rdi
callq 0x1170
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rdi
leaq 0xcbd(%rip), %rsi       # 0x2163
movb $0x0, %al
callq 0x11f0
movq -0x28(%rbp), %rdi
movq -0x38(%rbp), %rsi
xorl %edx, %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x1030
movq -0x28(%rbp), %rdi
leaq 0xb81(%rip), %rsi       # 0x204c
movb $0x0, %al
callq 0x11f0
movq -0x50(%rbp), %rdi
callq 0x1100
movl -0x54(%rbp), %edi
callq 0x11e0
movq -0x30(%rbp), %rdi
callq 0x10d0
movq -0x48(%rbp), %rdi
callq 0x1050
movq -0x28(%rbp), %rdi
leaq -0x20(%rbp), %rdx
leaq 0xc89(%rip), %rsi       # 0x218d
movb $0x0, %al
callq 0x11f0
xorl %eax, %eax
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)