diff options
author | Federico Ceratto <federico.ceratto@gmail.com> | 2020-03-20 16:11:39 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-20 17:11:39 +0100 |
commit | 5b854442448af96d57135ba7328b0c21f1f80f40 (patch) | |
tree | b4e0e0cf66b15fb9f040e4ee1a11f0ffd3b68ee2 /lib/wrappers | |
parent | 1d665adecde3b3bf16e64068e83c0b3cb0171856 (diff) | |
download | Nim-5b854442448af96d57135ba7328b0c21f1f80f40.tar.gz |
SSL certificate verify GitHub action (#13697)
* Implement SSL/TLS certificate checking #782 * SSL: Add nimDisableCertificateValidation Remove NIM_SSL_CERT_VALIDATION env var tests/untestable/thttpclient_ssl.nim ran successfully on Linux with libssl 1.1.1d * SSL: update integ test to skip flapping tests * Revert .travis.yml change * nimDisableCertificateValidation disable imports Prevent loading symbols that are not defined on older SSL libs * SSL: disable verification in net.nim ..when nimDisableCertificateValidation is set * Update changelog * Fix peername type * Add define check for windows * Disable test on windows * Add exprimental GitHub action CI for SSL * Test nimDisableCertificateValidation
Diffstat (limited to 'lib/wrappers')
-rw-r--r-- | lib/wrappers/openssl.nim | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index 4a53fba80..789b3611c 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -647,3 +647,74 @@ proc md5_Str*(str: string): string = when defined(nimHasStyleChecks): {.pop.} + + +# Certificate validation +# On old openSSL version some of these symbols are not available +when not defined(nimDisableCertificateValidation) and not defined(windows): + + proc SSL_get_peer_certificate*(ssl: SslCtx): PX509{.cdecl, dynlib: DLLSSLName, + importc.} + + proc X509_get_subject_name*(a: PX509): PX509_NAME{.cdecl, dynlib: DLLSSLName, importc.} + + proc X509_get_issuer_name*(a: PX509): PX509_NAME{.cdecl, dynlib: DLLUtilName, importc.} + + proc X509_NAME_oneline*(a: PX509_NAME, buf: cstring, size: cint): cstring {. + cdecl, dynlib:DLLSSLName, importc.} + + proc X509_NAME_get_text_by_NID*(subject:cstring, NID: cint, buf: cstring, size: cint): cint{. + cdecl, dynlib:DLLSSLName, importc.} + + proc X509_check_host*(cert: PX509, name: cstring, namelen: cint, flags:cuint, peername: cstring): cint {.cdecl, dynlib: DLLSSLName, importc.} + + # Certificates store + + type PX509_STORE* = SslPtr + type PX509_OBJECT* = SslPtr + + {.push callconv:cdecl, dynlib:DLLUtilName, importc.} + + proc X509_OBJECT_new*(): PX509_OBJECT + proc X509_OBJECT_free*(a: PX509_OBJECT) + + proc X509_STORE_new*(): PX509_STORE + proc X509_STORE_free*(v: PX509_STORE) + proc X509_STORE_lock*(ctx: PX509_STORE): cint + proc X509_STORE_unlock*(ctx: PX509_STORE): cint + proc X509_STORE_up_ref*(v: PX509_STORE): cint + proc X509_STORE_set_flags*(ctx: PX509_STORE; flags: culong): cint + proc X509_STORE_set_purpose*(ctx: PX509_STORE; purpose: cint): cint + proc X509_STORE_set_trust*(ctx: PX509_STORE; trust: cint): cint + proc X509_STORE_add_cert*(ctx: PX509_STORE; x: PX509): cint + + proc d2i_X509*(px: ptr PX509, i: ptr ptr cuchar, len: cint): PX509 + + proc i2d_X509*(cert: PX509; o: ptr ptr cuchar): cint + + {.pop.} + + proc d2i_X509*(b: string): PX509 = + ## decode DER/BER bytestring into X.509 certificate struct + var bb = b.cstring + let i = cast[ptr ptr cuchar](addr bb) + let ret = d2i_X509(addr result, i, b.len.cint) + if ret.isNil: + raise newException(Exception, "X.509 certificate decoding failed") + + proc i2d_X509*(cert: PX509): string = + ## encode `cert` to DER string + let encoded_length = i2d_X509(cert, nil) + result = newString(encoded_length) + var q = result.cstring + let o = cast[ptr ptr cuchar](addr q) + let length = i2d_X509(cert, o) + if length.int <= 0: + raise newException(Exception, "X.509 certificate encoding failed") + + when isMainModule: + # A simple certificate test + let certbytes = readFile("certificate.der") + let cert = d2i_X509(certbytes) + let encoded = cert.i2d_X509() + assert encoded == certbytes |