W3cubDocs

/Nim

Module openssl

OpenSSL support

When OpenSSL is dynamically linked, the wrapper provides partial forward and backward compatibility for OpenSSL versions above and below 1.1.0

OpenSSL can also be statically linked using --dynlibOverride:ssl for OpenSSL >= 1.1.0. If you want to statically link against OpenSSL 1.0.x, you now have to define the openssl10 symbol via -d:openssl10.

Build and test examples:

./bin/nim c -d:ssl -p:. -r tests/untestable/tssl.nim
./bin/nim c -d:ssl -p:. --dynlibOverride:ssl --passL:-lcrypto --passL:-lssl -r tests/untestable/tssl.nim

Imports

winlean, dynlib, strutils

Types

SslPtr = ptr SslStruct
PSslPtr = ptr SslPtr
SslCtx = SslPtr
PSSL_METHOD = SslPtr
PX509 = SslPtr
PX509_NAME = SslPtr
PEVP_MD = SslPtr
PBIO_METHOD = SslPtr
BIO = SslPtr
EVP_PKEY = SslPtr
PRSA = SslPtr
PASN1_UTCTIME = SslPtr
PASN1_cInt = SslPtr
PPasswdCb = SslPtr
PFunction = proc () {...}{.cdecl.}
DES_cblock = array[0 .. 7, int8]
PDES_cblock = ptr DES_cblock
des_ks_struct {...}{.final.} = object
  ks*: DES_cblock
  weak_key*: cint
des_key_schedule = array[1 .. 16, des_ks_struct]
pem_password_cb = proc (buf: cstring; size, rwflag: cint; userdata: pointer): cint {...}{.cdecl.}
PskClientCallback = proc (ssl: SslPtr; hint: cstring; identity: cstring;
                       max_identity_len: cuint; psk: ptr cuchar; max_psk_len: cuint): cuint {...}{.
    cdecl.}
PskServerCallback = proc (ssl: SslPtr; identity: cstring; psk: ptr cuchar;
                       max_psk_len: cint): cuint {...}{.cdecl.}
MD5_LONG = cuint
MD5_CTX = object
  A, B, C, D, Nl, Nh: MD5_LONG
  data: array[MD5_LBLOCK, MD5_LONG]
  num: cuint

Consts

DLLSSLName = "(libssl-1_1-x64|ssleay64|libssl64).dll"
DLLUtilName = "(libcrypto-1_1-x64|libeay64).dll"
SSL_SENT_SHUTDOWN = 1
SSL_RECEIVED_SHUTDOWN = 2
EVP_MAX_MD_SIZE = 36
SSL_ERROR_NONE = 0
SSL_ERROR_SSL = 1
SSL_ERROR_WANT_READ = 2
SSL_ERROR_WANT_WRITE = 3
SSL_ERROR_WANT_X509_LOOKUP = 4
SSL_ERROR_SYSCALL = 5
SSL_ERROR_ZERO_RETURN = 6
SSL_ERROR_WANT_CONNECT = 7
SSL_ERROR_WANT_ACCEPT = 8
SSL_CTRL_NEED_TMP_RSA = 1
SSL_CTRL_SET_TMP_RSA = 2
SSL_CTRL_SET_TMP_DH = 3
SSL_CTRL_SET_TMP_ECDH = 4
SSL_CTRL_SET_TMP_RSA_CB = 5
SSL_CTRL_SET_TMP_DH_CB = 6
SSL_CTRL_SET_TMP_ECDH_CB = 7
SSL_CTRL_GET_SESSION_REUSED = 8
SSL_CTRL_GET_CLIENT_CERT_REQUEST = 9
SSL_CTRL_GET_NUM_RENEGOTIATIONS = 10
SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS = 11
SSL_CTRL_GET_TOTAL_RENEGOTIATIONS = 12
SSL_CTRL_GET_FLAGS = 13
SSL_CTRL_EXTRA_CHAIN_CERT = 14
SSL_CTRL_SET_MSG_CALLBACK = 15
SSL_CTRL_SET_MSG_CALLBACK_ARG = 16
SSL_CTRL_SET_MTU = 17
SSL_CTRL_SESS_NUMBER = 20
SSL_CTRL_SESS_CONNECT = 21
SSL_CTRL_SESS_CONNECT_GOOD = 22
SSL_CTRL_SESS_CONNECT_RENEGOTIATE = 23
SSL_CTRL_SESS_ACCEPT = 24
SSL_CTRL_SESS_ACCEPT_GOOD = 25
SSL_CTRL_SESS_ACCEPT_RENEGOTIATE = 26
SSL_CTRL_SESS_HIT = 27
SSL_CTRL_SESS_CB_HIT = 28
SSL_CTRL_SESS_MISSES = 29
SSL_CTRL_SESS_TIMEOUTS = 30
SSL_CTRL_SESS_CACHE_FULL = 31
SSL_CTRL_OPTIONS = 32
SSL_CTRL_MODE = 33
SSL_CTRL_GET_READ_AHEAD = 40
SSL_CTRL_SET_READ_AHEAD = 41
SSL_CTRL_SET_SESS_CACHE_SIZE = 42
SSL_CTRL_GET_SESS_CACHE_SIZE = 43
SSL_CTRL_SET_SESS_CACHE_MODE = 44
SSL_CTRL_GET_SESS_CACHE_MODE = 45
SSL_CTRL_GET_MAX_CERT_LIST = 50
SSL_CTRL_SET_MAX_CERT_LIST = 51
TLSEXT_NAMETYPE_host_name = 0
SSL_TLSEXT_ERR_OK = 0
SSL_TLSEXT_ERR_ALERT_WARNING = 1
SSL_TLSEXT_ERR_ALERT_FATAL = 2
SSL_TLSEXT_ERR_NOACK = 3
SSL_MODE_ENABLE_PARTIAL_WRITE = 1
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER = 2
SSL_MODE_AUTO_RETRY = 4
SSL_MODE_NO_AUTO_CHAIN = 8
SSL_OP_NO_SSLv2 = 0x01000000
SSL_OP_NO_SSLv3 = 0x02000000
SSL_OP_NO_TLSv1 = 0x04000000
SSL_OP_NO_TLSv1_1 = 0x08000000
SSL_OP_ALL = 0x000FFFFF
SSL_VERIFY_NONE = 0x00000000
SSL_VERIFY_PEER = 0x00000001
OPENSSL_DES_DECRYPT = 0
OPENSSL_DES_ENCRYPT = 1
X509_V_OK = 0
X509_V_ILLEGAL = 1
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 2
X509_V_ERR_UNABLE_TO_GET_CRL = 3
X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE = 4
X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE = 5
X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY = 6
X509_V_ERR_CERT_SIGNATURE_FAILURE = 7
X509_V_ERR_CRL_SIGNATURE_FAILURE = 8
X509_V_ERR_CERT_NOT_YET_VALID = 9
X509_V_ERR_CERT_HAS_EXPIRED = 10
X509_V_ERR_CRL_NOT_YET_VALID = 11
X509_V_ERR_CRL_HAS_EXPIRED = 12
X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 13
X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 14
X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD = 15
X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 16
X509_V_ERR_OUT_OF_MEM = 17
X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 18
X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 19
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 20
X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 21
X509_V_ERR_CERT_CHAIN_TOO_LONG = 22
X509_V_ERR_CERT_REVOKED = 23
X509_V_ERR_INVALID_CA = 24
X509_V_ERR_PATH_LENGTH_EXCEEDED = 25
X509_V_ERR_INVALID_PURPOSE = 26
X509_V_ERR_CERT_UNTRUSTED = 27
X509_V_ERR_CERT_REJECTED = 28
X509_V_ERR_SUBJECT_ISSUER_MISMATCH = 29
X509_V_ERR_AKID_SKID_MISMATCH = 30
X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH = 31
X509_V_ERR_KEYUSAGE_NO_CERTSIGN = 32
X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER = 33
X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION = 34
X509_V_ERR_APPLICATION_VERIFICATION = 50
SSL_FILETYPE_ASN1 = 2
SSL_FILETYPE_PEM = 1
EVP_PKEY_RSA = 6
MD5_CBLOCK = 64
MD5_LBLOCK = 16
MD5_DIGEST_LENGTH = 16

Procs

proc TLSv1_method(): PSSL_METHOD {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_library_init(): cint {...}{.discardable, raises: [Exception], tags: [RootEffect].}
Initialize SSL using OPENSSL_init_ssl for OpenSSL >= 1.1.0 otherwise SSL_library_init
proc SSL_load_error_strings() {...}{.raises: [Exception], tags: [RootEffect].}
proc SSLv23_client_method(): PSSL_METHOD {...}{.raises: [Exception], tags: [RootEffect].}
proc SSLv23_method(): PSSL_METHOD {...}{.raises: [Exception], tags: [RootEffect].}
proc SSLv2_method(): PSSL_METHOD {...}{.raises: [Exception], tags: [RootEffect].}
proc SSLv3_method(): PSSL_METHOD {...}{.raises: [Exception], tags: [RootEffect].}
proc TLS_method(): PSSL_METHOD {...}{.raises: [Exception], tags: [RootEffect].}
proc TLS_client_method(): PSSL_METHOD {...}{.raises: [Exception], tags: [RootEffect].}
proc TLS_server_method(): PSSL_METHOD {...}{.raises: [Exception], tags: [RootEffect].}
proc OpenSSL_add_all_algorithms() {...}{.raises: [Exception], tags: [RootEffect].}
proc getOpenSSLVersion(): culong {...}{.raises: [Exception], tags: [RootEffect].}
Return OpenSSL version as unsigned long or 0 if not available
proc ERR_load_BIO_strings() {...}{.cdecl, dynlib: DLLUtilName, importc.}
proc SSL_new(context: SslCtx): SslPtr {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_free(ssl: SslPtr) {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_get_SSL_CTX(ssl: SslPtr): SslCtx {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_set_SSL_CTX(ssl: SslPtr; ctx: SslCtx): SslCtx {...}{.cdecl, dynlib: DLLSSLName,
    importc.}
proc SSL_CTX_new(meth: PSSL_METHOD): SslCtx {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_CTX_load_verify_locations(ctx: SslCtx; CAfile: cstring; CApath: cstring): cint {...}{.
    cdecl, dynlib: DLLSSLName, importc.}
proc SSL_CTX_free(arg0: SslCtx) {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_CTX_set_verify(s: SslCtx; mode: int;
                       cb: proc (a: int; b: pointer): int {...}{.cdecl.}) {...}{.cdecl,
    dynlib: DLLSSLName, importc.}
proc SSL_get_verify_result(ssl: SslPtr): int {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_CTX_set_cipher_list(s: SslCtx; ciphers: cstring): cint {...}{.cdecl,
    dynlib: DLLSSLName, importc.}
proc SSL_CTX_use_certificate_file(ctx: SslCtx; filename: cstring; typ: cint): cint {...}{.
    stdcall, dynlib: DLLSSLName, importc.}
proc SSL_CTX_use_certificate_chain_file(ctx: SslCtx; filename: cstring): cint {...}{.
    stdcall, dynlib: DLLSSLName, importc.}
proc SSL_CTX_use_PrivateKey_file(ctx: SslCtx; filename: cstring; typ: cint): cint {...}{.
    cdecl, dynlib: DLLSSLName, importc.}
proc SSL_CTX_check_private_key(ctx: SslCtx): cint {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_CTX_get_ex_new_index(argl: clong; argp: pointer; new_func: pointer;
                             dup_func: pointer; free_func: pointer): cint {...}{.cdecl,
    dynlib: DLLSSLName, importc.}
proc SSL_CTX_set_ex_data(ssl: SslCtx; idx: cint; arg: pointer): cint {...}{.cdecl,
    dynlib: DLLSSLName, importc.}
proc SSL_CTX_get_ex_data(ssl: SslCtx; idx: cint): pointer {...}{.cdecl, dynlib: DLLSSLName,
    importc.}
proc SSL_set_fd(ssl: SslPtr; fd: SocketHandle): cint {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_shutdown(ssl: SslPtr): cint {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_set_shutdown(ssl: SslPtr; mode: cint) {...}{.cdecl, dynlib: DLLSSLName,
    importc: "SSL_set_shutdown".}
proc SSL_get_shutdown(ssl: SslPtr): cint {...}{.cdecl, dynlib: DLLSSLName,
                                       importc: "SSL_get_shutdown".}
proc SSL_connect(ssl: SslPtr): cint {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_read(ssl: SslPtr; buf: pointer; num: int): cint {...}{.cdecl, dynlib: DLLSSLName,
    importc.}
proc SSL_write(ssl: SslPtr; buf: cstring; num: int): cint {...}{.cdecl, dynlib: DLLSSLName,
    importc.}
proc SSL_get_error(s: SslPtr; ret_code: cint): cint {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_accept(ssl: SslPtr): cint {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc SSL_pending(ssl: SslPtr): cint {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc BIO_new_mem_buf(data: pointer; len: cint): BIO {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc BIO_new_ssl_connect(ctx: SslCtx): BIO {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc BIO_ctrl(bio: BIO; cmd: cint; larg: int; arg: cstring): int {...}{.cdecl,
    dynlib: DLLSSLName, importc.}
proc BIO_get_ssl(bio: BIO; ssl: ptr SslPtr): int {...}{.raises: [], tags: [].}
proc BIO_set_conn_hostname(bio: BIO; name: cstring): int {...}{.raises: [], tags: [].}
proc BIO_do_handshake(bio: BIO): int {...}{.raises: [], tags: [].}
proc BIO_do_connect(bio: BIO): int {...}{.raises: [], tags: [].}
proc BIO_read(b: BIO; data: cstring; length: cint): cint {...}{.cdecl, dynlib: DLLUtilName,
    importc.}
proc BIO_write(b: BIO; data: cstring; length: cint): cint {...}{.cdecl, dynlib: DLLUtilName,
    importc.}
proc BIO_free(b: BIO): cint {...}{.cdecl, dynlib: DLLUtilName, importc.}
proc ERR_print_errors_fp(fp: File) {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc ERR_error_string(e: cint; buf: cstring): cstring {...}{.cdecl, dynlib: DLLUtilName,
    importc.}
proc ERR_get_error(): cint {...}{.cdecl, dynlib: DLLUtilName, importc.}
proc ERR_peek_last_error(): cint {...}{.cdecl, dynlib: DLLUtilName, importc.}
proc OPENSSL_config(configName: cstring) {...}{.cdecl, dynlib: DLLSSLName, importc.}
proc CRYPTO_malloc_init() {...}{.raises: [], tags: [].}
proc SSL_CTX_ctrl(ctx: SslCtx; cmd: cint; larg: int; parg: pointer): int {...}{.cdecl,
    dynlib: DLLSSLName, importc.}
proc SSLCTXSetMode(ctx: SslCtx; mode: int): int {...}{.raises: [], tags: [].}
proc SSL_ctrl(ssl: SslPtr; cmd: cint; larg: int; parg: pointer): int {...}{.cdecl,
    dynlib: DLLSSLName, importc.}
proc SSL_set_tlsext_host_name(ssl: SslPtr; name: cstring): int {...}{.raises: [], tags: [].}
Set the SNI server name extension to be used in a client hello. Returns 1 if SNI was set, 0 if current SSL configuration doesn't support SNI.
proc SSL_get_servername(ssl: SslPtr; typ: cint = TLSEXT_NAMETYPE_host_name): cstring {...}{.
    cdecl, dynlib: DLLSSLName, importc.}
Retrieve the server name requested in the client hello. This can be used in the callback set in SSL_CTX_set_tlsext_servername_callback to implement virtual hosting. May return nil.
proc SSL_CTX_set_tlsext_servername_callback(ctx: SslCtx;
    cb: proc (ssl: SslPtr; cb_id: int; arg: pointer): int {...}{.cdecl.}): int {...}{.
    raises: [Exception], tags: [RootEffect].}

Set the callback to be used on listening SSL connections when the client hello is received.

The callback should return one of:

  • SSL_TLSEXT_ERR_OK
  • SSL_TLSEXT_ERR_ALERT_WARNING
  • SSL_TLSEXT_ERR_ALERT_FATAL
  • SSL_TLSEXT_ERR_NOACK
proc SSL_CTX_set_tlsext_servername_arg(ctx: SslCtx; arg: pointer): int {...}{.raises: [],
    tags: [].}
Set the pointer to be used in the callback registered to SSL_CTX_set_tlsext_servername_callback.
proc SSL_CTX_set_psk_client_callback(ctx: SslCtx; callback: PskClientCallback) {...}{.
    cdecl, dynlib: DLLSSLName, importc.}
Set callback called when OpenSSL needs PSK (for client).
proc SSL_CTX_set_psk_server_callback(ctx: SslCtx; callback: PskServerCallback) {...}{.
    cdecl, dynlib: DLLSSLName, importc.}
Set callback called when OpenSSL needs PSK (for server).
proc SSL_CTX_use_psk_identity_hint(ctx: SslCtx; hint: cstring): cint {...}{.cdecl,
    dynlib: DLLSSLName, importc.}
Set PSK identity hint to use.
proc SSL_get_psk_identity(ssl: SslPtr): cstring {...}{.cdecl, dynlib: DLLSSLName, importc.}
Get PSK identity.
proc bioNew(b: PBIO_METHOD): BIO {...}{.cdecl, dynlib: DLLUtilName, importc: "BIO_new".}
proc bioFreeAll(b: BIO) {...}{.cdecl, dynlib: DLLUtilName, importc: "BIO_free_all".}
proc bioSMem(): PBIO_METHOD {...}{.cdecl, dynlib: DLLUtilName, importc: "BIO_s_mem".}
proc bioCtrlPending(b: BIO): cint {...}{.cdecl, dynlib: DLLUtilName,
                                importc: "BIO_ctrl_pending".}
proc bioRead(b: BIO; Buf: cstring; length: cint): cint {...}{.cdecl, dynlib: DLLUtilName,
    importc: "BIO_read".}
proc bioWrite(b: BIO; Buf: cstring; length: cint): cint {...}{.cdecl, dynlib: DLLUtilName,
    importc: "BIO_write".}
proc sslSetConnectState(s: SslPtr) {...}{.cdecl, dynlib: DLLSSLName,
                                  importc: "SSL_set_connect_state".}
proc sslSetAcceptState(s: SslPtr) {...}{.cdecl, dynlib: DLLSSLName,
                                 importc: "SSL_set_accept_state".}
proc sslRead(ssl: SslPtr; buf: cstring; num: cint): cint {...}{.cdecl, dynlib: DLLSSLName,
    importc: "SSL_read".}
proc sslPeek(ssl: SslPtr; buf: cstring; num: cint): cint {...}{.cdecl, dynlib: DLLSSLName,
    importc: "SSL_peek".}
proc sslWrite(ssl: SslPtr; buf: cstring; num: cint): cint {...}{.cdecl, dynlib: DLLSSLName,
    importc: "SSL_write".}
proc sslSetBio(ssl: SslPtr; rbio, wbio: BIO) {...}{.cdecl, dynlib: DLLSSLName,
    importc: "SSL_set_bio".}
proc sslDoHandshake(ssl: SslPtr): cint {...}{.cdecl, dynlib: DLLSSLName,
                                     importc: "SSL_do_handshake".}
proc ErrClearError() {...}{.cdecl, dynlib: DLLUtilName, importc: "ERR_clear_error".}
proc ErrFreeStrings() {...}{.cdecl, dynlib: DLLUtilName, importc: "ERR_free_strings".}
proc ErrRemoveState(pid: cint) {...}{.cdecl, dynlib: DLLUtilName,
                              importc: "ERR_remove_state".}
proc PEM_read_bio_RSA_PUBKEY(bp: BIO; x: ptr PRSA; pw: pem_password_cb; u: pointer): PRSA {...}{.
    cdecl, dynlib: DLLSSLName, importc.}
proc RSA_verify(kind: cint; origMsg: pointer; origMsgLen: cuint; signature: pointer;
               signatureLen: cuint; rsa: PRSA): cint {...}{.cdecl, dynlib: DLLSSLName,
    importc.}
proc md5_Init(c: var MD5_CTX): cint {...}{.importc: "MD5_Init".}
proc md5_Update(c: var MD5_CTX; data: pointer; len: csize): cint {...}{.importc: "MD5_Update".}
proc md5_Final(md: cstring; c: var MD5_CTX): cint {...}{.importc: "MD5_Final".}
proc md5(d: ptr cuchar; n: csize; md: ptr cuchar): ptr cuchar {...}{.importc: "MD5".}
proc md5_Transform(c: var MD5_CTX; b: ptr cuchar) {...}{.importc: "MD5_Transform".}
proc md5_File(file: string): string {...}{.raises: [IOError, Exception],
                                  tags: [ReadIOEffect].}
Generate MD5 hash for a file. Result is a 32 character
proc md5_Str(str: string): string {...}{.raises: [], tags: [].}
Generate MD5 hash for a string. Result is a 32 character hex string with lowercase characters

© 2006–2018 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/openssl.html