import t, c from openssl.types import * # ============================================================ # openssl/ssl.vp — SSL/TLS 连接层(握手 + SocketIO + 校验证书) # 对应头文件: ssl.h # # 典型客户端流程: # OPENSSL_init_ssl(...) # ctx = SSL_CTX_new(TLS_client_method()) # SSL_CTX_set_verify(ctx, SslVerifyPeer, 0) # 校验对端 # SSL_CTX_load_verify_locations(ctx, cafile, None) # ssl = SSL_new(ctx) # SSL_set_fd(ssl, fd) # 底层已连好的 TCP socket # SSL_connect(ssl) # 握手 # SSL_write/SSL_read # ============================================================ # ---- 证书文件格式(SSL_CTX_use_*_file / use_certificate_file 的 type)---- X509FiletypePem: t.CDefine = 1 X509FiletypeAsn1: t.CDefine = 2 # SSL_FILETYPE_* 与 X509_FILETYPE_* 同值 SslFiletypePem: t.CDefine = 1 SslFiletypeAsn1: t.CDefine = 2 # ---- 校验模式(SSL_CTX_set_verify mode)---- SslVerifyNone: t.CDefine = 0x00 SslVerifyPeer: t.CDefine = 0x01 SslVerifyFailIfNoPeerCert: t.CDefine = 0x02 SslVerifyClientOnce: t.CDefine = 0x04 # ---- 协议版本(SSL_CTX_ctrl SSL_CTRL_SET_MIN/MAX_PROTO_VERSION 的 arg)---- Tls1Version: t.CDefine = 0x0301 Tls1_1Version: t.CDefine = 0x0302 Tls1_2Version: t.CDefine = 0x0303 Tls1_3Version: t.CDefine = 0x0304 # ---- ctrl 命令 ---- SslCtrlSetTlsextHostname: t.CDefine = 55 # SSL_ctrl(ssl, ..., TLSEXT_NAMETYPE_host_name, (void*)name) SslCtrlSetMinProtoVersion: t.CDefine = 123 SslCtrlSetMaxProtoVersion: t.CDefine = 124 SslCtrlMode: t.CDefine = 33 SslCtrlClearMode: t.CDefine = 34 TlsextNametypeHostName: t.CDefine = 0 # ---- shutdown 状态 ---- SslSentShutdown: t.CDefine = 1 SslReceivedShutdown: t.CDefine = 2 # ---- SSL_get_error 返回码 ---- SslErrorNone: t.CDefine = 0 SslErrorSsl: t.CDefine = 1 SslErrorWantRead: t.CDefine = 2 SslErrorWantWrite: t.CDefine = 3 SslErrorWantX509Lookup: t.CDefine = 4 SslErrorSyscall: t.CDefine = 5 SslErrorZeroReturn: t.CDefine = 6 SslErrorWantConnect: t.CDefine = 7 SslErrorWantAccept: t.CDefine = 8 SslErrorWantAsync: t.CDefine = 9 SslErrorWantAsyncJob: t.CDefine = 10 SslErrorWantClientHelloCb: t.CDefine = 11 SslErrorWantRetryVerify: t.CDefine = 12 # ---- SSL_OP_* 选项 ---- # SSL_CTX_set_options(ctx, uint64_t) SslOpNoSslv2: t.CDefine = 0x01000000 SslOpNoSslv3: t.CDefine = 0x02000000 SslOpNoTlsv1: t.CDefine = 0x04000000 SslOpNoTlsv1_2: t.CDefine = 0x08000000 SslOpNoTlsv1_1: t.CDefine = 0x10000000 SslOpNoTlsv1_3: t.CDefine = 0x20000000 SslOpAll: t.CDefine = 0x00000fff # ============================================================ # 初始化 / 方法 # ============================================================ # (OPENSSL_init_ssl 见 crypto.vp) # const SSL_METHOD *TLS_method(void) / *_client_method / *_server_method extern def TLS_method() -> SslMethodPtr extern def TLS_client_method() -> SslMethodPtr extern def TLS_server_method() -> SslMethodPtr # ============================================================ # SSL_CTX # ============================================================ # SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) extern def SSL_CTX_new(meth: SslMethodPtr) -> SslCtxPtr # void SSL_CTX_free(SSL_CTX *ctx) extern def SSL_CTX_free(ctx: SslCtxPtr) # int SSL_CTX_up_ref(SSL_CTX *ctx) extern def SSL_CTX_up_ref(ctx: SslCtxPtr) -> int # 证书 / 私钥 # int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) extern def SSL_CTX_use_certificate_file(ctx: SslCtxPtr, file: str, type: int) -> int # int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) extern def SSL_CTX_use_PrivateKey_file(ctx: SslCtxPtr, file: str, type: int) -> int # int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) extern def SSL_CTX_use_certificate_chain_file(ctx: SslCtxPtr, file: str) -> int # int SSL_CTX_check_private_key(const SSL_CTX *ctx) extern def SSL_CTX_check_private_key(ctx: SslCtxPtr) -> int # 校验配置 # void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, SSL_verify_cb callback) extern def SSL_CTX_set_verify(ctx: SslCtxPtr, mode: int, callback: bytes) # void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) extern def SSL_CTX_set_verify_depth(ctx: SslCtxPtr, depth: int) # int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath) extern def SSL_CTX_load_verify_locations(ctx: SslCtxPtr, CAfile: str, CApath: str) -> int # int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) extern def SSL_CTX_set_default_verify_paths(ctx: SslCtxPtr) -> int # int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) extern def SSL_CTX_set_cipher_list(ctx: SslCtxPtr, cipher_list: str) -> int # int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) (TLS1.3) extern def SSL_CTX_set_ciphersuites(ctx: SslCtxPtr, suites: str) -> int # int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, unsigned int protos_len) extern def SSL_CTX_set_alpn_protos(ctx: SslCtxPtr, protos: bytes, protos_len: t.CUInt32T) -> int # uint64_t SSL_CTX_set_options(SSL_CTX *ctx, uint64_t op) extern def SSL_CTX_set_options(ctx: SslCtxPtr, op: t.CUInt64T) -> t.CUInt64T # long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) extern def SSL_CTX_ctrl(ctx: SslCtxPtr, cmd: int, larg: t.CInt32T, parg: bytes) -> t.CInt32T # long SSL_CTX_set_timeout(SSL_CTX *ctx, long t) -- 用 ctrl? 不是,是函数 # int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode) # ============================================================ # SSL 对象 # ============================================================ # SSL *SSL_new(SSL_CTX *ctx) extern def SSL_new(ctx: SslCtxPtr) -> SslPtr # void SSL_free(SSL *ssl) extern def SSL_free(ssl: SslPtr) # int SSL_up_ref(SSL *ssl) extern def SSL_up_ref(ssl: SslPtr) -> int # int SSL_set_fd(SSL *ssl, int fd) / int SSL_get_fd(const SSL *ssl) extern def SSL_set_fd(ssl: SslPtr, fd: int) -> int extern def SSL_get_fd(ssl: SslPtr) -> int # void SSL_set_connect_state(SSL *ssl) / accept extern def SSL_set_connect_state(ssl: SslPtr) extern def SSL_set_accept_state(ssl: SslPtr) # 握手 extern def SSL_connect(ssl: SslPtr) -> int extern def SSL_accept(ssl: SslPtr) -> int # int SSL_do_handshake(SSL *ssl) extern def SSL_do_handshake(ssl: SslPtr) -> int # int SSL_shutdown(SSL *ssl) extern def SSL_shutdown(ssl: SslPtr) -> int # int SSL_get_shutdown(const SSL *ssl) extern def SSL_get_shutdown(ssl: SslPtr) -> int # IO # int SSL_read(SSL *ssl, void *buf, int num) extern def SSL_read(ssl: SslPtr, buf: bytes, num: int) -> int # int SSL_write(SSL *ssl, const void *buf, int num) extern def SSL_write(ssl: SslPtr, buf: bytes, num: int) -> int # int SSL_pending(const SSL *ssl) extern def SSL_pending(ssl: SslPtr) -> int # int SSL_get_error(const SSL *s, int ret_code) extern def SSL_get_error(s: SslPtr, ret_code: int) -> int # const char *SSL_get_version(const SSL *s) extern def SSL_get_version(s: SslPtr) -> str # long SSL_get_verify_result(const SSL *ssl) extern def SSL_get_verify_result(ssl: SslPtr) -> t.CInt32T # int SSL_get_verify_mode(const SSL *ssl) extern def SSL_get_verify_mode(ssl: SslPtr) -> int # X509 *SSL_get_peer_certificate(const SSL *s) / SSL_get1_peer_certificate extern def SSL_get_peer_certificate(s: SslPtr) -> X509Ptr extern def SSL_get1_peer_certificate(s: SslPtr) -> X509Ptr # 当前加密套件 # SSL_get_cipher_name 在 ssl.h 是宏(SSL_CIPHER_get_name(SSL_get_current_cipher(s))), # FFI 拆成两个真实导出函数调用: # const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) extern def SSL_get_current_cipher(s: SslPtr) -> SslCipherPtr # const char *SSL_CIPHER_get_name(const SSL_CIPHER *c) extern def SSL_CIPHER_get_name(cipher: SslCipherPtr) -> str # SNI: int SSL_set_tlsext_host_name(SSL *s, const char *name)(宏 → SSL_ctrl) # const char *SSL_get_servername(const SSL *s, int type) extern def SSL_get_servername(s: SslPtr, type: int) -> str # ALPN # void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, unsigned int *len) extern def SSL_get0_alpn_selected(ssl: SslPtr, data: bytes, len: bytes) # 控制 / 选项 # long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg) extern def SSL_ctrl(ssl: SslPtr, cmd: int, larg: t.CInt32T, parg: bytes) -> t.CInt32T # uint64_t SSL_set_options(SSL *ssl, uint64_t op) extern def SSL_set_options(ssl: SslPtr, op: t.CUInt64T) -> t.CUInt64T # int SSL_set1_host(SSL *s, const char *hostname) (主机名校验) extern def SSL_set1_host(s: SslPtr, hostname: str) -> int # void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) extern def SSL_set_bio(s: SslPtr, rbio: BioPtr, wbio: BioPtr) # ============================================================ # 便捷封装 # ============================================================ def ssl_set_tlsext_host_name(ssl: SslPtr, name: str) -> int: return SSL_ctrl(ssl, SslCtrlSetTlsextHostname, TlsextNametypeHostName, name) def ssl_ctx_set_min_proto_version(ctx: SslCtxPtr, version: int) -> int: return SSL_CTX_ctrl(ctx, SslCtrlSetMinProtoVersion, version, None) def ssl_ctx_set_max_proto_version(ctx: SslCtxPtr, version: int) -> int: return SSL_CTX_ctrl(ctx, SslCtrlSetMaxProtoVersion, version, None) def ssl_ctx_set_mode(ctx: SslCtxPtr, op: int) -> int: return SSL_CTX_ctrl(ctx, SslCtrlMode, op, None) def ssl_get_verify_result_ok(ssl: SslPtr) -> bool: return SSL_get_verify_result(ssl) == 0