RosettaCodeData/Task/HTTPS/X86-64-Assembly/https-2.x86-64
2026-04-30 12:34:36 -04:00

201 lines
4.8 KiB
Text

%macro prolog 1
push rbp
mov rbp, rsp
sub rsp, %1
%endmacro
%macro epilog 1
add rsp, %1
pop rbp
%endmacro
%macro xcall 1
call [rel %1 wrt ..got]
%endmacro
%macro xlea 2
lea %1, [rel %2]
%endmacro
extern printf
extern strlen
extern strdup
extern strchr
extern free
extern exit
;; --> OpenSSL Stuffs <--
extern BIO_new_ssl_connect
extern BIO_ctrl
extern BIO_write
extern BIO_read
extern BIO_free_all
extern TLS_client_method
extern SSL_CTX_new
extern SSL_CTX_free
extern SSL_CTX_set_verify
extern SSL_CTX_set_default_verify_paths
extern SSL_ctrl
%define BIO_C_SET_CONNECT 100
%define BIO_C_DO_STATE 101
%define BIO_C_GET_SSL 110
%define SSL_CTRL_SET_TLSHOST 55
%define SSL_VERIFY_PEER 1
section .text
global xrequest
xrequest:
prolog 6*8
%define _req_host rbp-1*8
%define _req_pack rbp-2*8
%define _req_buff rbp-3*8
%define _req_ssl rbp-4*8
%define _req_ctx rbp-5*8
%define _req_bio rbp-6*8
mov rax, rdi
mov qword [_req_host], rax
mov rax, rsi
mov qword [_req_pack], rax
mov rax, rdx
mov qword [_req_buff], rax
xcall TLS_client_method
mov rdi, rax
xcall SSL_CTX_new
test rax, rax
jz __req_err_ctx
mov qword [_req_ctx], rax
mov rdi, qword [_req_ctx]
xcall SSL_CTX_set_default_verify_paths
test eax, eax
jz __req_err_verify
mov rdx, 0
mov rsi, SSL_VERIFY_PEER
mov rdi, qword [_req_ctx]
xcall SSL_CTX_set_verify
;;-->> Create Bio chain
mov rdi, qword [_req_ctx]
xcall BIO_new_ssl_connect
test rax, rax
jz __req_err_bio
mov qword [_req_bio], rax
;;-->> Get SSL object
lea rcx, [_req_ssl]
mov rdx, 0
mov rsi, BIO_C_GET_SSL
mov rdi, qword [_req_bio]
xcall BIO_ctrl
;; -->> Set the SNI hostname.
mov rdi, qword [_req_host]
xcall strdup
mov rdx, rax ; rdx now holds the copy
push rdx ; Push pointer to stack
mov rdi, rdx
mov rsi, ':'
xcall strchr
test rax, rax
jz __req_sni_set
mov byte [rax], 0 ; Null-terminate at colon
__req_sni_set:
mov rdi, qword [_req_ssl]
mov rsi, SSL_CTRL_SET_TLSHOST
mov rdx, 0
mov rcx, [rsp]
xcall SSL_ctrl
pop rdi
xcall free
;; -->>Set Hostname (BIO expects "host:port")
mov rdi, qword [_req_bio]
mov rsi, BIO_C_SET_CONNECT
mov rdx, 0
mov rcx, qword [_req_host]
xcall BIO_ctrl
mov rdi, qword [_req_bio]
mov rsi, BIO_C_DO_STATE
mov rdx, 0
mov rcx, 0
xcall BIO_ctrl
cmp rax, 1
jl __req_err_conn
;; -->> Send Request
mov rdi, qword [_req_pack]
xcall strlen
mov rdx, rax
mov rdi, qword [_req_bio]
mov rsi, qword [_req_pack]
xcall BIO_write
; -->> Read Response Loop
__req_read_loop:
mov rdi, qword [_req_bio]
mov rsi, qword [_req_buff]
mov rdx, 1024
xcall BIO_read
test eax, eax
jle __req_exit
add qword [_req_buff], rax
jmp __req_read_loop
__req_err_bio:
mov r13, -1
jmp __req_exit
__req_err_verify:
mov r13, -2
jmp __req_exit
__req_err_ctx:
;;-->> CTX Error
mov r13, -3
jmp __req_exit
__req_err_conn:
mov r13, -4
;; fall through..
__req_exit:
mov r13, rax
mov rdi, qword [_req_bio]
xcall BIO_free_all
mov rdi, qword [_req_ctx]
xcall SSL_CTX_free
mov rax, r13
epilog 6*8
ret
global main
main:
prolog 4*8
; request(hostname, request_str, buffer)
xlea rdi, hostname
xlea rsi, request_str
xlea rdx, buffer
call xrequest
mov rsi, rax
xlea rdi, fmt_ret
xcall printf
; Print the response buffer
xlea rdi, fmt_str
xlea rsi, buffer
xor rax, rax
xcall printf
xor rdi, rdi
xcall exit
prolog 4*8 ;;Never gets here but w/e.
ret
section .data
hostname db "google.com:443", 0
request_str db "GET / HTTP/1.1", 13, 10
db "Host: google.com", 13, 10
db "Connection: close", 13, 10
db "User-Agent: TLS-TEST/0.5", 13, 10
db 13, 10, 0
fmt_str db "%s", 0
fmt_ret db "%i",10,0
section .bss
buffer resb 16384