// File: /workspace/github_c_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movaps 0xd1f(%rip), %xmm0      # 0x2010
movaps %xmm0, (%rsp)
movw $0x6d, 0x10(%rsp)
movq 0x2ccd(%rip), %rax      # 0x3fd0
movq (%rax), %rdi
xorl %esi, %esi
callq 0x1100
movq %rax, %rbx
xorl %edi, %edi
xorl %esi, %esi
callq 0x1130
testl %eax, %eax
jns 0x132e
leaq 0xcfe(%rip), %rsi       # 0x2022
movq %rbx, %rdi
xorl %eax, %eax
callq 0x11d0
callq 0x10a0
movq %rax, %rdi
callq 0x1180
movq %rax, %r14
testq %rax, %rax
jne 0x1354
leaq 0xd04(%rip), %rsi       # 0x204e
movq %rbx, %rdi
xorl %eax, %eax
callq 0x11d0
movq %r14, %rdi
xorl %esi, %esi
callq 0x11b0
movq %r14, %rdi
callq 0x1140
movq %rax, %r15
movq %rsp, %rdi
movq %rbx, %rsi
callq 0x1477
movl %eax, %ebp
testl %eax, %eax
je 0x138e
leaq 0xcfc(%rip), %rsi       # 0x207d
movq %rsp, %rdx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x11d0
movq %r15, %rdi
movl %ebp, %esi
callq 0x10f0
movq %r15, %rdi
callq 0x1170
cmpl $0x1, %eax
leaq 0xd2f(%rip), %rax       # 0x20d9
leaq 0xcfa(%rip), %rsi       # 0x20ab
cmoveq %rax, %rsi
movq %rsp, %r12
movq %rbx, %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x11d0
movq %r15, %rdi
callq 0x11a0
movq %rax, %r13
testq %rax, %rax
leaq 0xd2d(%rip), %rax       # 0x2107
leaq 0xd54(%rip), %rsi       # 0x2135
cmoveq %rax, %rsi
movq %rbx, %rdi
movq %r12, %rdx
xorl %eax, %eax
callq 0x11d0
callq 0x1120
movq %r13, %rdi
callq 0x1150
movq %rax, %r12
leaq 0xd5a(%rip), %rsi       # 0x2163
movq %rbx, %rdi
xorl %eax, %eax
callq 0x11d0
movq %rbx, %rdi
movq %r12, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x1030
leaq 0xc23(%rip), %rsi       # 0x204c
movq %rbx, %rdi
xorl %eax, %eax
callq 0x11d0
movq %r15, %rdi
callq 0x10e0
movl %ebp, %edi
callq 0x11c0
movq %r13, %rdi
callq 0x10c0
movq %r14, %rdi
callq 0x1040
leaq 0xd34(%rip), %rsi       # 0x218d
movq %rbx, %rdi
movq %rsp, %rdx
xorl %eax, %eax
callq 0x11d0
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq